# SIMD Directive (OpenMP* API)

OpenMP* Fortran Compiler Directive: Transforms a loop into a loop that will be executed concurrently using Single Instruction Multiple Data (SIMD) instructions.

## Syntax

!$OMP SIMD [clause[[,] clause]... ]

do-loop

[!$OMP END SIMD]

clause | Is one of the following: ALIGNED (list [:n]) [NO]ASSERT Directs the compiler to assert (produce an error) or not to assert (produce a warning) when the vectorization fails. The default is NOASSERT. If this clause is specified more than once, a compile-time error occurs. COLLAPSE (n) EARLY_EXIT Allows vectorization of multiple exit loops. When this clause is specified the following occurs: Each operation before the last lexical early exit of the loop may be executed as if the early exit were not triggered within the SIMD chunk. After the last lexical early exit of the loop, all operations are executed as if the last iteration of the loop was found. The last value for LINEARs and conditional LASTPRIVATEs are preserved with respect to scalar execution. The last value for REDUCTIONs are computed as if the last iteration in the last SIMD chunk was executed upon exiting the loop. The shared memory state may not be preserved with regard to scalar execution. Exceptions are not allowed. When a SIMD loop is specified with the EARLY_EXIT clause, each list item specified in the LINEAR clause is computed based on the last iteration number upon exiting the loop. IF ([SIMD:] scalar-logical-expression) LASTPRIVATE ([CONDITIONAL:] list) LINEAR (var-list[: linear-step]) NONTEMPORAL [(var1 [, var2]...)]) Directs the compiler to use non-temporal (that is, streaming) stores. By default, the compiler automatically determines whether a streaming store should be used for each variable. Streaming stores may cause significant performance improvements over non-streaming stores for large trip-count loops on certain processors. However, the misuse of streaming stores can significantly degrade performance. A variable cannot appear more than once in a NONTEMPORAL clause, and it cannot appear in more than one NONTEMPORAL clause. ORDER (CONCURRENT) Indicates that the iterations of the loop may execute in any order or simultaneously. This feature is only available for ifx. PRIVATE (list) REDUCTION (reduction-identifier : list) SAFELEN(m) Limits the number of iterations in a SIMD chunk (set of concurrent iterations). The m must be a constant positive integer expression; it indicates the number of iterations allowed in a SIMD chunk. When this clause is used, no two iterations executed concurrently with SIMD instructions can have a greater distance in the logical iteration space than m. The number of iterations that are executed concurrently at any given time is defined by the implementation. Each concurrent iteration is executed by a different SIMD vector lane. At most one SAFELEN clause can appear in a SIMD directive. SIMDLEN(n) Specifies the preferred number of iterations to be executed concurrently. n must be a positive scalar integer constant. The number of iterations that are executed concurrently at any given time is implementation defined. Each concurrent iteration will be executed by a different SIMD lane. If both SIMDLEN (n) and SAFELEN (m) are specified, the value of the n must be less than or equal to the value of m. At most one SIMDLEN clause can appear in a SIMD directive.
do-loop | Is one or more DO iterations (DO loops). The DO iteration cannot be a DO WHILE or a DO loop without loop control. The DO loop iteration variable must be of type integer. All loops associated with the construct must be structured and perfectly nested; that is, there must be no intervening code and no other OpenMP* Fortran directives between any two loops. The iterations of the DO loop are distributed across the existing team of threads. The values of the loop control parameters of the DO loop associated with a DO directive must be the same for all the threads in the team. You cannot branch out of a DO loop associated with a SIMD directive.

A SIMD construct binds to the current task region. The binding thread set of the SIMD region is the current team.

If used, the END SIMD directive must appear immediately after the end of the loop. If you do not specify an END SIMD directive, an END SIMD directive is assumed at the end of do-loop.

The SIMD construct enables the execution of multiple iterations of the associated loops concurrently by means of SIMD instructions. No other OpenMP* Fortran construct can appear in a SIMD directive.

A SIMD region binds to the current task region. The binding thread set of the SIMD region is the current team.

When any thread encounters a SIMD construct, the iterations of the loop associated with the construct may be executed concurrently using the SIMD lanes that are available to the thread.

If an ORDERED directive with the SIMD clause is specified inside the SIMD region, the ordered regions encountered by any thread will use only a single SIMD lane to execute the ordered regions in the order of the loop iterations.

## Example

The following is an example using the SIMD directive:

       subroutine subr(a, b, c, n)
         implicit none
         real(kind=kind(0.0d0)),dimension(*) :: a, b, c
         integer                             :: n, i

         !$omp simd
           do i = 1, n
             a(i) = a(i) * b(i) + c(i)
           end do

        end subroutine

The following example demonstrates the EARLY_EXIT clause:

      !$omp simd early_exit
        do i = 1, n
           if (a(i) == i) exit
        enddo

Parent topic: S

## See Also

OpenMP Fortran Compiler Directives
Syntax Rules for Compiler Directives
qsimd-honor-fp-model, Qsimd-honor-fp-model compiler option
qsimd-serialize-fp-reduction, Qsimd-serialize-fp-reduction compiler option
fp-model, fp compiler option
Nested DO Constructs
Parallel Processing Model for information about Binding Sets