ASSERT

Purpose

The ASSERT directive provides the compiler with the characteristics of DO loops that can assist in optimizing source code.

Syntax

Read syntax diagramSkip visual syntax diagram
>>-ASSERT--(--assertion_list--)--------------------------------><

assertion
ITERCNT(n), MINITERCNT(n), MAXITERCNT(n), or NODEPS. All assertions are not mutually exclusive. You can use at most one of each assertion for the same DO loop. n must be a positive, scalar, integer constant expression.
ITERCNT(n)
specifies the expected number of iterations (n) for a given DO loop.
MINITERCNT(n)
specifies the expected minimum number of iterations (n) for a given DO loop.
MAXITERCNT(n)
specifies the expected maximum number of iterations (n) for a given DO loop.
NODEPS
specifies that no loop-carried dependencies exist within a given DO loop.

NODEPS takes effect only when you specify the -qhot or -qsmp compiler options.

Rules

The first noncomment line (not including other directives) following the ASSERT directive must be a DO loop. This line cannot be an infinite DO, Fortran 2008 beginsDO CONCURRENTFortran 2008 ends, or DO WHILE loop. The ASSERT directive applies only to the DO loop immediately following the directive, and not to any nested DO loops.

ITERCNT, MINITERCNT, and MAXITERCNT are not required to be accurate. The values only affect performance, never correctness. Specify the values following the rule MINITERCNT <= ITERCNT <= MAXITERCNT. Otherwise, messages are issued to indicate that the values are inconsistent and the inconsistent value is ignored. The assert directives ITERCNT, MINITERCNT, and MAXITERCNT take priority over the options specified with -qassert={itercnt, minitercnt, maxitercnt} for the given loop.

When NODEPS is specified, the user is explicitly declaring to the compiler that no loop-carried dependencies exist within the DO loop or any procedures invoked from within the DO loop. A loop-carried dependency involves two iterations within a DO loop interfering with one another. Interference occurs in the following situations:
  • Two operations that define, undefine, or redefine the same atomic object (data that has no subobjects) interfere.
  • Definition, undefinition, or redefinition of an atomic object interferes with any use of the value of the object.
  • Any operation that causes the association status of a pointer to become defined or undefined interferes with any reference to the pointer or any other operation that causes the association status to become defined or undefined.
  • Transfer of control outside the DO loop or execution of an EXIT, STOP, or PAUSE statement interferes with all other iterations.
  • Any two input/output (I/O) operations associated with the same file or external unit interfere with each other. The exceptions to this rule are:
    • If the two I/O operations are two INQUIRE statements; or
    • If the two I/O operations are accessing distinct areas of a stream access file; or
    • If the two I/O operations are accessing distinct records of a direct access file.
  • A change in the allocation status of an allocatable object between iterations causes interference.
It is possible for two complementary ASSERT directives to apply to any given DO loop. However, an ASSERT directive cannot be followed by a contradicting ASSERT directive for a given DO loop:
   !IBM* ASSERT (ITERCNT(10))
   !IBM* INDEPENDENT, REDUCTION (A)
   !IBM* ASSERT (ITERCNT(20))     ! invalid
         DO I = 1, N
             A(I) = A(I) * I
         END DO
 

In the example above, the ASSERT(ITERCNT(20)) directive contradicts the ASSERT(ITERCNT(10)) directive and is invalid.

The ASSERT directive overrides the -qassert compiler option for the DO loop on which the ASSERT directive is specified.

Examples

Example 1:
! An example of the ASSERT directive with NODEPS.
PROGRAM EX1
  INTEGER A(100)
!IBM* ASSERT (NODEPS)
  DO I = 1, 100
    A(I) = A(I) * FNC1(I)
  END DO
END PROGRAM EX1

FUNCTION FNC1(I)
  FNC1 = I * I
END FUNCTION FNC1
Example 2:
! An example of the ASSERT directive with NODEPS and ITERCNT.
SUBROUTINE SUB2 (N)
  INTEGER A(N)
!IBM*  ASSERT (NODEPS,ITERCNT(100))
  DO I = 1, N
    A(I) = A(I) * FNC2(I)
  END DO
END SUBROUTINE SUB2

FUNCTION FNC2 (I)
  FNC2 = I * I
END FUNCTION FNC2
Example 3:
! An example of the ASSERT directive with ITERCNT, MINITERCNT, and MAXITERCNT.
!IBM* ASSERT (ITERCNT(10), MINITERCNT(5))
DO I = 1, N
  A(I) = A(I) * I
!IBM* ASSERT (ITERCNT(100))
!IBM* ASSERT (MINITERCNT(5), MAXITERCNT(100))
  DO J = 1, M
    B(J) = A(I) + B(J)
  END DO
END DO

Related information



Voice your opinion on getting help information Ask IBM compiler experts a technical question in the IBM XL compilers forum Reach out to us