Visible to Intel only — GUID: GUID-9FF11FC7-8776-490E-AA8B-108CFE0D7376
Visible to Intel only — GUID: GUID-9FF11FC7-8776-490E-AA8B-108CFE0D7376
UNROLL Directive for OpenMP
OpenMP* Fortran Compiler Directive: Partially or fully unrolls a DO loop. This feature is only available for ifx.
Syntax
!$OMP UNROLL [clause]
loop-nest
[!$OMP END UNROLL]
clause |
Is FULL or PARTIAL [ (count) ], where count is a compile-time integer constant expression. If FULL is specified, and n is the iteration count of the outermost DO loop, the outermost loop is replaced by n copies of the loop body. If PARTIAL is specified, the outermost loop is first tiled with a tile size of count, and then the tiled loop is fully unrolled. If PARTIAL is specified without count, the compiler determines the count. If clause is omitted, the compiler determines if and how the loop is transformed. |
loop-nest |
Is a nest of DO loops in canonical form. |
Description
The UNROLL construct applies to the outermost loop of the loop nest. It is a pure directive, so it can appear in a Fortran PURE procedure.
The transformed loop will be in canonical form only when PARTIAL is specified.
The iteration count of the outermost DO loop must be constant if FULL is specified.
Examples
In the following example, the FULL clause is specified in the UNROLL directive, so the loop iteration count must be a compile-time constant. In this case, a worksharing loop construct cannot be used because there is no loop to apply it to after the loop is unrolled.
INTEGER,DIMENSION (5) :: arr
INTEGER :: i
!$OMP UNROLL FULL
DO i = 1, 5
arr(i) = 100
END DO
Unrolling the above DO loops produces the following transformed code:
INTEGER,DIMENSION (5) :: arr INTEGER :: i arr(1) = 100 arr(2) = 100 arr(3) = 100 arr(4) = 100 arr(5) = 100
In the following example, the loop is partially unrolled. The trip count is a multiple of count specified in the PARTIAL clause:
INTEGER,DIMENSION (64) :: arr
INTEGER :: i
!$OMP PARALLEL DO
!$OMP UNROLL PARTIAL(4)
DO i = 1, 64
arr(i) = arr(i) * 10
END DO
Unrolling the above DO loops 4 times produces the following result:
INTEGER,DIMENSION (64) :: arr INTEGER :: i !$OMP PARALLEL DO DO i = 0, 15 arr(i*4 + 1) = arr(i*4 + 1) * 10 arr(i*4 + 2) = arr(i*4 + 2) * 10 arr(i*4 + 3) = arr(i*4 + 3) * 10 arr(i*4 + 4) = arr(i*4 + 4) * 10 END DO
The following example shows how a loop with an unknown trip count that is partially unrolled may be transformed:
SUBROUTINE FOO (arr, n)
INTEGER :: i,n
INTEGER,DIMENSION (n) :: arr
!$OMP PARALLEL DO
!$OMP UNROLL PARTIAL(4)
DO i = 1, n
arr(i) = arr(i) * 10
END DO
END SUBROUTINE
Unrolling the above DO loop 4 times produces code equivalent to the following:
SUBROUTINE FOO (arr, n) INTEGER :: i,n INTEGER,DIMENSION (n) :: arr !$OMP PARALLEL DO DO i = 0, (n+3)/4 - 1 arr(i*4 + 1) = arr(i*4 + 1) * 10 if ((i*4 + 2) < n) arr(i*4 + 2) = arr(i*4 + 2) * 10 if ((i*4 + 3) < n) arr(i*4 + 3) = arr(i*4 + 3) * 10 if ((i*4 + 4) < n) arr(i*4 + 4) = arr(i*4 + 4) * 10 END DO END SUBROUTINE
See Also
To learn more about canonical form loops, see the OpenMP* specification.