linear(ref) seems impossible to express in C++

Comments and discussion of the 4.1 OpenMP Draft specifications. Comment period ends September 30, 2015. See http://openmp.org/wp/openmp-specifications/ to download the specifications. (Read Only)
Forum rules
The OpenMP Forums are now closed to new posts. Please visit Stack Overflow if you are in need of help: https://stackoverflow.com/questions/tagged/openmp
Locked
Spreis
Posts: 12
Joined: Tue Jul 14, 2015 9:35 am

linear(ref) seems impossible to express in C++

Post by Spreis »

The definition of linear(ref) is following:
15 If the ref modifier is used, the value of the new list item on each iteration of the
16 associated loop(s) corresponds to the value of the variable resulting from applying the linear-step
17 times the logical number of the iteration as a subscript to the original list item
This may mean different 2 things, but none of those cannot be expressed in C++ consistently with OpenMP specification.

Consider the following code (1):

Code: Select all

T& V = A[0];
#pragma omp for linear(ref(V))
for(int i = 0; i < N; i++) {
// V = A[i]; <-- Bind to indexed value: impossible 
   B[i] = V;
// V++ <-- Incorrect - will not advance pointer
}
Here have reference of a simple type. The definition implies that it will be replaced by new list item V_new of type T which will get values as V. But this is incorrect operation: V is not an array. Another possible reading is that indexing applied as if reference were a pointer *(&V + i). But syntactically it is impossible to advance underlying pointer for V to express this behavior in C++, so it is impossible to write C++ program to match linear(ref) OpenMP specification. I am not so familiar with Fortran, but it seems to me that there is no way to advance implicit reference in Fortran either.

Let's consider another code, reference is now of array type:

Code: Select all

T (&V) [N] = A;
#pragma omp for linear(ref(V))
for(int i = 0; i < N; i++) {
   B[i] = V[i];
}
In this case V could be replaced by V_new which is initialized to V, but it is unclear which type V_new has in this case and what V_new means granted it is already V_new = V. I don't see how the code after replacement will semantically match original code.

I understand that examples are usually written after publishing spec, but it would be great to see motivating example for having linear(ref) for OpenMP loops where base language and OpenMP specification semantically aligned.

fewl9012
Posts: 73
Joined: Mon Jul 27, 2015 4:50 pm

Re: linear(ref) seems impossible to express in C++

Post by fewl9012 »

I have to agree that linear(ref:V) seems to be focused on C array pointer arithmetic in a loop. The wording is not precise. It seems that
#pragma omp simd linear(ref:V)
for(i=0;i<n;++i){ A[i]=*V; ++V; }
is going to replace *V with *(V[i]) [applying the ... as a subscript to the original list item]. That's not quite what you want.

I don't think any of this applies to Fortran, so perhaps it should be in a C/C++ only section.

Spreis
Posts: 12
Joined: Tue Jul 14, 2015 9:35 am

Re: linear(ref) seems impossible to express in C++

Post by Spreis »

fewl9012 wrote:I have to agree that linear(ref:V) seems to be focused on C array pointer arithmetic in a loop. The wording is not precise. It seems that

Code: Select all

   #pragma omp simd linear(ref:V)
   for(i=0;i<n;++i){    A[i]=*V;  ++V; }
is going to replace *V with *(V) [applying the ... as a subscript to the original list item]. That's not quite what you want.

I don't think any of this applies to Fortran, so perhaps it should be in a C/C++ only section.


'ref' and 'uval' seem not applicable to C at all: they only mentioned in C++only and Fortran-only sections and only apply to cases where reference nature is hidden by language (access is done as to base type on surface, while done indirectly internally). For C++ this is reference type and for Fortran this is non-VALUE dummy argument.

So I agree that your code is exactly what linear(ref) is aimed for, but it is only applicable to cases where 'V++' (reference increment) is impossible to express due to hidden nature of a reference. If V was not a pointer, but reference (*V) would look like just 'V' and in this sense V would be OK expression of desirable behavior, but there is no way to advance V as a reference.

fewl9012
Posts: 73
Joined: Mon Jul 27, 2015 4:50 pm

Re: linear(ref) seems impossible to express in C++

Post by fewl9012 »

I think you're confusing 'ref' with C++ reference types. I read this as saying that the pointer ref (V in this case) is linear.

Spreis
Posts: 12
Joined: Tue Jul 14, 2015 9:35 am

Re: linear(ref) seems impossible to express in C++

Post by Spreis »

I don't think so. Wording is precise and explicit about C++ and Fortran. For C++ pointers and references are generally allowed, but only references allowed with ref/uval modifiers.
p.207 wrote: 8 A list-item that appears in a linear clause without the ref modifier must be of integral or
9 pointer type, or must be a reference to an integral or pointer type
10 The ref or uval modifier can only be used if the list-item is of a reference type.
...
13 The ref or uval modifier can only be used if the list-item is a dummy argument without the
14 VALUE attribute.
Applicability to C is unclear.

fewl9012
Posts: 73
Joined: Mon Jul 27, 2015 4:50 pm

Re: linear(ref) seems impossible to express in C++

Post by fewl9012 »

I stand corrected. In which case, perhaps linear(ref) only applies with declare target on a dummy argument, where it would state that the address passed in is linearly increasing. I can't come up with any other usage.

Spreis
Posts: 12
Joined: Tue Jul 14, 2015 9:35 am

Re: linear(ref) seems impossible to express in C++

Post by Spreis »

Exactly: linear(ref) is really useful extension for #omp declare simd.
In this case specification applies to parameters/dummy arguments which are already represent chunk of values and means that address passed is linearly increasing (data occupies consecutive memory) which is good because all the values may be read/written SIMD load/store operation instead of gather/scatter.
As I pointed in my another comment I just don't see how this extension fits loop constructs and suggest limiting it to omp declare simd only.

Locked