# UNROLL (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.

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

Parent topic: T to Z

## See Also

OpenMP Fortran Compiler Directives
Syntax Rules for Compiler Directives

To learn more about canonical form loops, see the OpenMP* specification.