Visible to Intel only — GUID: GUID-7E4C8279-995B-44DE-9C4E-4BC4EAFF5DE1
Visible to Intel only — GUID: GUID-7E4C8279-995B-44DE-9C4E-4BC4EAFF5DE1
LINEAR Clause
Parallel Directive Clause: Specifies that all variables in a list are private to a SIMD lane and that they have a linear relationship within the iteration space of a loop.
Syntax
LINEAR (linear-list [: linear-modifier [, linear-modifier]])
-or deprecated form-
LINEAR (old-linear-list[: linear-step])
linear-list |
Is a comma-separated list of one or more integer variables or dummy arguments. If the clause appears in a declarative directive, linear-list items must be dummy arguments of the procedure that will be invoked concurrently on each SIMD lane. List items must be scalar and of type integer, unless the linear-modifier REF is specified, in which case list items can be dummy arguments of any type and rank. Each list item must comply with PRIVATE clause semantics. List items cannot have the POINTER attribute or be Cray* pointers. |
linear-modifier |
Is step-modifier or modifier. |
step-modifier |
Is STEP (linear-step) or linear-step. linear-step must appear if STEP appears. If step-modifier is present, it must be the first (leftmost) linear-modifer specified. |
linear-step |
Is a compile-time positive, integer, scalar constant expression. If linear-step is not specified, it is assumed to be 1. |
modifier |
Is one of the following:
If modifier is not specified or it is VAL or UVAL, the value of each linear-list item on each lane corresponds to the value of the linear-list item upon entry to the function plus the logical number of the lane times linear-step. You can only use REF or VAL if the linear-list item is a dummy argument without the Fortran Standard VALUE attribute. |
old-linear-list |
Is one of the following:
|
A LINEAR clause can specify at most one step-modifier and one modifier. Multiple LINEAR clauses can be used to specify different values for linear-step and/or modifiers. The linear-step expression must be invariant (must not be changed) during the execution of the associated construct. Multiple LINEAR clauses are merged as a union.
The value of the linear-list item on a given iteration is equal to the value of the original list item plus the logical number of the iteration times linear-step. The value corresponding to the sequentially last iteration of the associated loops is assigned to the original linear-list item. If modifier is not REF and the linear-list item has the ALLOCATABLE attribute, in the sequentially last iteration the allocation status of the linear-list item must be allocated upon completion of that iteration.
A linear-list item in a LINEAR clause cannot appear in any other data scope attribute clause, in another LINEAR clause in the same directive, or more than once in linear-list. For a list of data scope attribute clauses, see the first table in Clauses Used in Multiple OpenMP* Fortran Directives.
If a linear-list item is a dummy argument without the Fortran Standard VALUE attribute and the REF modifier is not specified, then a read of the linear-list item must be executed before any writes to the linear-list item.
If a LINEAR clause appears in a directive that also contains a REDUCTION clause with the INSCAN modifier, only a loop iteration variable of a loop associated with the construct can appear as a linear-list item in the LINEAR clause.
The REF modifier is very important because Fortran passes dummy arguments by reference. By default, the compiler places consecutive addresses in a vector register, which leads to an inefficient gather of the addresses.
In the following example, linear(x, y:ref) tells the compiler that the 4 addresses for the dummy argument x are consecutive, and the 4 addresses for the dummy argument y are consecutive, so the code only needs to dereference x and y once each and then copy consecutive values to vector registers.
subroutine test_linear(x, y)
!$omp declare simd (test_linear) linear(x, y:ref) ! arguments by reference
real(8),intent(in) :: x(4)
real(8),intent(out) :: y(4)
y = 1. + sin(x)**3
end subroutine test_linear
… ! procedure that calls test_linear
interface ! test_linear needs an explicit interface
…
do j = 1,n
call test_linear(a(j), b(j)) ! loop vectorized via qopenmp-simd
enddo
…
Example
Consider the following:
! universal but slowest definition; it matches the use of func in loops 1, 2, and 3:
!$OMP DECLARE SIMD
!
! matches the use of func in loop 1:
!$OMP DECLARE SIMD LINEAR(in1) LINEAR (in2: REF) UNIFORM(mul)
!
! matches the use of func in loops 2 and 3:
!$OMP DECLARE SIMD LINEAR (in2: REF)
!
! matches the use of func in loop 2:
!$OMP DECLARE SIMD LINEAR (in2: REF) LINEAR(mul)
!
! matches the use of func in loop 3:
!$OMP DECLARE SIMD LINEAR (in2: STEP(2), VAL)
function func(in1, in2, mul)
integral in1
integral in2
integral mul
...
integral a, k
integral b(100)
integral c(100)
integral ndx(100)
...
The following are the loop examples referenced above.
!loop 1
!$OMP SIMD
DO i=1,100
c(i) = func(a + i, b(i), mul) ! the value of the 1st parameter is changed linearly,
! the 2nd parameter reference is changed linearly,
! the 3rd parameter is not changed
END DO
!loop 2
!$OMP SIMD
DO i=1,100
c(i) = func(b(ndx(i)), b(i), i + 1 ! the value of the 1st parameter is unpredictable,
! the 2nd reference is changed linearly,
! the 3rd parameter is changed linearly
END DO
!loop 3
!$OMP SIMD
DO i=1,100
k = i * 2 ! during vectorization, private variables are
c(i) = func(b(ndx(i)), k, b(i)) ! transformed into arrays: k -> k_vec(simdlen)
! the value of the 1st parameter is unpredictable,
! for the 2nd parameter both value and reference
! to its location can be considered linear,
! the value for the 3rd parameter is unpredictable
!
! the !$OMP DECLARE SIMD LINEAR(VAL(in2:2))) will
END DO ! be chosen from the two matching variants)