# SIMD Loop Directive

General Compiler Directive: Requires and controls SIMD vectorization of loops. This directive is deprecated and will be removed in a future release.

## Syntax

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

- clause | Is an optional vectorization clause. It can be one or more of the following: [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. FIRSTPRIVATE(list)
  list | Is a list of names of one or more variables or common blocks that are accessible to the scoping unit.
- Provides a superset of the functionality provided by the PRIVATE clause. Variables that appear in a FIRSTPRIVATE list are subject to PRIVATE clause semantics. In addition, each variable has its initial value broadcast to all private instances for each iteration upon entering the SIMD loop. A variable in a FIRSTPRIVATE clause can appear in a LASTPRIVATE clause. A variable in a FIRSTPRIVATE clause cannot appear in a LINEAR, REDUCTION, or PRIVATE clause. LASTPRIVATE (list)
  list | Is a list of names of one or more variables or common blocks that are accessible to the scoping unit.
- Provides a superset of the functionality provided by the PRIVATE clause. Variables that appear in a LASTPRIVATE list are subject to PRIVATE clause semantics. In addition, when the SIMD loop is exited, each variable has the value that resulted from the sequentially last iteration of the SIMD loop (which may be undefined if the last iteration does not assign to the variable). A variable in a LASTPRIVATE clause can appear in a FIRSTPRIVATE clause. A variable in a LASTPRIVATE clause cannot appear in a LINEAR, REDUCTION, or PRIVATE clause. LINEAR (var1:step1 [, var2:step2]...)
  var | Is a scalar variable.
  step | Is a positive, integer, scalar expression.
- For each iteration of a scalar loop, var1 is incremented by step1, var2 is incremented by step2, and so on. Therefore, every iteration of the vector loop increments the variables by VL (vector length)*step1, VL*step2, …, to VL*stepN, respectively. If more than one step is specified for a var, a compile-time error occurs. Multiple LINEAR clauses are merged as a union. A variable in a LINEAR clause cannot appear in a REDUCTION, PRIVATE, FIRSTPRIVATE, or LASTPRIVATE clause. PRIVATE (list)
  list | Is a list of names of one or more variables or common blocks that are accessible to the scoping unit. A variable that is part of another variable (for example, subobjects such as an array or structure element) cannot appear. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).
- Causes each variable to be private to each iteration of a loop. Its initial and last values are undefined upon entering and exiting the SIMD loop. Multiple PRIVATE clauses are merged as a union. A variable in a PRIVATE clause cannot appear in a LINEAR, REDUCTION, FIRSTPRIVATE, or LASTPRIVATE clause. REDUCTION (reduction-identifier : var1 [, var2]...)
  reduction-identifier | Is a predefined reduction identifier ( +, *, -, .AND., .OR., .EQV., or .NEQV.), or an accessible user-defined reduction identifier declared in a DECLARE REDUCTION directive.
  var | Is a scalar variable.
- Applies the vector reduction indicated by reduction-identifier to var1, var2, …, varN. A SIMD directive can have multiple REDUCTION clauses using the same or different operators. If more than one reduction operator is associated with a var, a compile-time error occurs. A variable in a REDUCTION clause cannot appear in a LINEAR, PRIVATE, FIRSTPRIVATE, or LASTPRIVATE clause. [NO]VECREMAINDER VECTORLENGTH (n1 [, n2]...)
  n | Is a vector length (VL). It must be an integer that is a power of 2; the value must be 2, 4, 8, 16, 32 or 64. If you specify more than one n, the vectorizor will choose the VL from the values specified.
- Causes each iteration in the vector loop to execute the computation equivalent to n iterations of scalar loop execution. The VECTORLENGTH and VECTORLENGTHFOR clauses are mutually exclusive. You cannot use the VECTORLENGTH clause with the VECTORLENGTHFOR clause, and vice versa. Multiple VECTORLENGTH clauses cause a syntax error. VECTORLENGTHFOR (data-type)
  data-type | Is one of the following intrinsic data types:
  Data Type | Fortran Intrinsic Type
  --- | ---
  INTEGER | Default INTEGER
  INTEGER(1) | INTEGER (KIND=1)
  INTEGER(2) | INTEGER (KIND=2)
  INTEGER(4) | INTEGER (KIND=4)
  INTEGER(8) | INTEGER (KIND=8)
  REAL | Default REAL
  REAL(4) | REAL (KIND=4)
  REAL(8) | REAL (KIND=8)
  COMPLEX | Default COMPLEX
  COMPLEX(4) | COMPLEX (KIND=4)
  COMPLEX(8) | COMPLEX (KIND=8)
Causes each iteration in the vector loop to execute the computation equivalent to n iterations of scalar loop execution where n is computed from size_of_vector_register/sizeof(data_type). For example, VECTORLENGTHFOR (REAL (KIND=4)) results in n=4 for SSE2 to SSE4.2 targets (packed float operations available on 128-bit XMM registers) and n=8 for AVX target (packed float operations available on 256-bit YMM registers). VECTORLENGTHFOR(INTEGER (KIND=4)) results in n=4 for SSE2 to AVX targets. The VECTORLENGTHFOR and VECTORLENGTH clauses are mutually exclusive. You cannot use the VECTORLENGTHFOR clause with the VECTORLENGTH clause, and vice versa. Multiple VECTORLENGTHFOR clauses cause a syntax error. Without explicit VECTORLENGTH and VECTORLENGTHFOR clauses, the compiler will choose a VECTORLENGTH using its own cost model. Misclassification of variables into PRIVATE, FIRSTPRIVATE, LASTPRIVATE, LINEAR, and REDUCTION, or the lack of appropriate classification of variables, may lead to unintended consequences such as runtime failures and/or incorrect results.

If you specify the SIMD directive with no clause, default rules are in effect for variable attributes, vector length, and so forth.

If you do not explicitly specify a VECTORLENGTH clause, the compiler will choose a VECTORLENGTH using its own cost model. Misclassification of variables into PRIVATE, FIRSTPRIVATE, LASTPRIVATE, LINEAR, and REDUCTION, or the lack of appropriate classification of variables, may lead to unintended consequences such as runtime failures and/or incorrect results.

You can only specify a particular variable in at most one instance of a PRIVATE, LINEAR, or REDUCTION clause.

If the compiler is unable to vectorize a loop, a warning occurs by default. However, if ASSERT is specified, an error occurs instead.

If the vectorizer has to stop vectorizing a loop for some reason, the fast floating-point model is used for the SIMD loop.

A SIMD loop may contain one or more nested loops or be contained in a loop nest. Only the loop preceded by the SIMD directive is processed for SIMD vectorization.

The vectorization performed on this loop by the SIMD directive overrides any setting you may specify for options -fp-model (Linux* and macOS) and /fp (Windows*) for this loop.

Note that the SIMD directive may not affect all auto-vectorizable loops. Some of these loops do not have a way to describe the SIMD vector semantics.

The following restrictions apply to the SIMD directive:

- The countable loop for the SIMD directive has to conform to the DO-loop style of an OpenMP worksharing loop construct. Additionally, the loop control variable must be a signed integer type.

- The vector values must be signed 8-, 16-, 32-, or 64-bit integers, single or double-precision floating-point numbers, or single- or double-precision complex numbers.

- A SIMD directive loop performs memory references unconditionally. Therefore, all address computations must result in valid memory addresses, even though such locations may not be accessed if the loop is executed sequentially.

To disable the SIMD transformations for vectorization, specify option -no-simd (Linux* and macOS) or /Qsimd- (Windows*).

To disable transformations that enable more vectorization, specify options -no-vec-no-simd (Linux and macOS) or /Qvec-/Qsimd- (Windows).

## Example

Consider the following:

      ...
    subroutine add(A, N, X)
       integer N, X
       real    A(N)
    cDIR$ SIMD
       DO I=X+1, N
          A(I) = A(I) + A(I-X)
       ENDDO
    end
      ...

When the program containing this subroutine is compiled, the DO loop will be vectorized.

Because no optional clause was specified for the directive, default rules will apply for variable attributes, vector length, and so forth.

Parent topic: S

## See Also

General Compiler Directives
Syntax Rules for Compiler Directives
simd, Qsimd compiler option
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
vec, Qvec compiler option