#pragma omp declare reduction

Forum for the public review of the OpenMP 4.0 API Release Candidates. (Read Only)
Forum rules
This forum is now closed.

#pragma omp declare reduction

Postby jakub » Wed Feb 20, 2013 10:22 am

In 2.12 the draft says:
"The visibility and accessibility of this declaration are the same as those of a variable declared at the same point in the program."
Does that imply #pragma omp declare reduction is for C++ only allowed in namespace or block scope, not at class scope (because at class scope you wouldn't declare a variable, but data member or static data member)?

Also, perhaps:
"A user-defined reduction may not be re-declared in the current scope."
should be worded better, from this it isn't clear if
#pragma omp declare reduction(foo : char, int : omp_out += omp_in)
#pragma omp declare reduction(foo : short, long : omp_out += omp_in)
is ok or not. If the standard means that the same reduction-idenfifier can be re-declared for different types, but can't be re-declared for the same type, then it should probably make it more clear. I guess
typedef char char2;
typedef int int2;
#pragma omp declare reduction(foo : char, int : omp_out += omp_in)
#pragma omp declare reduction(foo : char2, int2 : omp_out += omp_in)
is meant to be invalid, so the same type would probably mean not just identical types, but compatible types according to language rules.
jakub
 
Posts: 74
Joined: Fri Oct 26, 2007 3:19 am

Re: #pragma omp declare reduction

Postby aduran » Tue Feb 26, 2013 12:58 pm

In 2.12 the draft says:
"The visibility and accessibility of this declaration are the same as those of a variable declared at the same point in the program."
Does that imply #pragma omp declare reduction is for C++ only allowed in namespace or block scope, not at class scope (because at class scope you wouldn't declare a variable, but data member or static data member)?


No, the intent was that they would be allowed inside class scope as well but certainly the text could be improved there. We'll try to do that.

Also, perhaps:
"A user-defined reduction may not be re-declared in the current scope."
should be worded better, from this it isn't clear if
#pragma omp declare reduction(foo : char, int : omp_out += omp_in)
#pragma omp declare reduction(foo : short, long : omp_out += omp_in)
is ok or not. If the standard means that the same reduction-idenfifier can be re-declared for different types, but can't be re-declared for the same type, then it should probably make it more clear. I guess
typedef char char2;
typedef int int2;
#pragma omp declare reduction(foo : char, int : omp_out += omp_in)
#pragma omp declare reduction(foo : char2, int2 : omp_out += omp_in)
is meant to be invalid, so the same type would probably mean not just identical types, but compatible types according to language rules.


The first one would be ok. This is implied by "the reduction-identifier and the type identify the declare reduction directive" text so if the type is different they're not the same user-defined reduction anymore.

For the second, it is supposed to be invalid but the wording here probably needs some improvement as well.
aduran
 
Posts: 12
Joined: Wed Oct 24, 2007 8:33 am
Location: Barcelona, Spain

Re: #pragma omp declare reduction

Postby jakub » Tue Apr 30, 2013 3:26 am

What is the reason for allowing also operator-function-id as the operator name for C++?
I mean,+, -, *, &, |, ^, && and || are allowed too, and the reduction clause only allows identifier (which matches identifier in declare reduction) and the earlier mentioned binary operators.
By allowing both the binary operators and operator-function-id, one can have questions whether say:
Code: Select all
struct S { int i; S (int); S (const S &); };
#pragma omp declare reduction (+ : S : omp_out.i += omp_in.i ) initializer (omp_priv (0))
#pragma omp declare reduction (operator + : S : omp_out.i += omp_in.i) initializer (omp_priv {0})
#pragma omp declare reduction (operator new[] : S : omp_out.i += omp_in.i) initializer (omp_priv = { 0 })

is valid (i.e. whether + and operator + are the same thing or not (if they are the same thing, then that would be redeclaration error, if they are different, how should one choose which of those to use for S s; ... #pragma omp simd reduction (+ : s), and whether it is ok to specify something weird like operator for anything but the binary operators that reduction clause allows).

Also, in the restrictions there is a line that only omp_out and omp_in variables may appear in the combiner expression (and similarly omp_priv and omp_orig in the initializer clause. Does that mean the expression can't refer to any other vars or declare their own vars etc., or just that omp_priv and omp_orig may not be used in the combiner and similarly for the initializer clause?
Code: Select all
struct T { unsigned char t[16]; };
extern int var;
extern int foo (int &, int &, int), baz (int &, int);
void bar (int &x, int &y)
{
  x = (x + y) & var;
}
#pragma omp declare reduction (+ : T : [&]{ int i; for (i = 0; i < 16; i++) omp_out.t[i] += omp_in.t[i]; } ()) initializer (omp_priv = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } })
#pragma omp declare reduction (q : int : foo (omp_out, omp_in, var)) initializer (baz (omp_priv, var))
#pragma omp declare reduction (q2 : int : bar (omp_out, omp_in))


Are all 3 above invalid because of that? There is a variable (i) in the lambda inside of the expression, so a variable other than omp_out and omp_in appears in the combiner expression.
Or the second declare reduction calls a function referencing a variable other than omp_out and omp_in in the combiner, and calls another function with argument other than omp_priv and omp_orig in the initializer.
Or the third declare reduction call, which, while not using some other variable directly in the expression uses the variable in the function that the expression calls.

Also, is it valid to override the standard built-in reductions?
Say
Code: Select all
#pragma omp declare reduction (+ : int, float : omp_out *= omp_in)

? Given that 2.14.3.6 says those are implicitly declared, perhaps explicit declaration is supposed to be conflicting with the implicit declaration, rather than override it. As in C++ one can't override operators on arithmetic types either, not allowing this would be logical.
jakub
 
Posts: 74
Joined: Fri Oct 26, 2007 3:19 am


Return to OpenMP 4.0 Public Review Release Candidates

Who is online

Users browsing this forum: No registered users and 0 guests

cron