OpenACC: struct/class partially shared and partially private

This problem was extracted from the EuroHack17 GPU programming hackathon, reported by Andreas Jocksch. I feel the functionality they want is not advisable, but am not sure what a good workaround is.
– Will

You can find below a simplified OpenMP example program. The hackathon group has a similar problem with a more complex c++ class. The example does not compile with the 4 compilers PGI, Cray, Intel and Gnu. Is it planned to support constructs -- with variables of a struct/class partially shared and partially private -- like the shown one in OpenACC? If not it is not a big problem for us.

Regards

Andreas


#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

struct mystruct {
int a;
int b;
} ;

int main (int argc, char *argv) {
mystruct istruct;
istruct.a = 0;
istruct.b = 1;
#pragma omp parallel shared(istruct.a) private(istruct.b)
{
#pragma omp for
for (int i=0; i<10; i++){
istruct.a = istruct.b + i;
}
}
return(0);
}

<\andreas>

Hi Will,

What’s the goal of doing this? That might help in giving ideas as to the best work-around.

The problem I see with this is that by privatizing a variable, every thread needs it’s own copy of the variable. But in order to maintain the data structure and allow access to it’s members, i.e. “istruct.b”, you’d need to privatize the parent object as well. While not explicitly illegal in OpenACC, I don’t see a way for an implementation can safely support it. Though, I can ask Michael Wolfe his thoughts since he’ll know more about what can and can’t be done by the compiler.

Note that this code is explicitly illegal in the OpenMP 4.5 standard. See section 1.2.6, lines 20-21. http://www.openmp.org/wp-content/uploads/openmp-4.5.pdf

A variable that is part of another variable (as an array or structure element) cannot be made private independently of other components.

While I don’t know if this fits in with their overall goal, the work around is to make “b” a local integer which can then be privatized.

-Mat

Hi Mat,

Thanks for the quick answer. It enforces the conviction that the user needs to restructure the code, particularly in view of the fact that it would not work with OpenMP. Here Andreas’s response:

The user wants to write loops in a very abstract way.

class… x;

nested OpenACC loop over iii, jjj, kkk hidden in a macro
// This line is the last line of the macro it sets an internal variable of the class to the 3d index
x.setIndex(iiii + (lattice_sizelocal0+2lattice_halo)(jjjj + (lattice_sizelocal1+2*lattice_halo)*kkkk));

// This line and further following similar ones use the class for all purposes, index variable and other variables with pointers to scalars and arrays, many operators are overwritten
rho(x)=(long) ((void *) &(x.lattice()));

end of the nested loop hidden in a macro

I think one needs to split the class and create variables x and y private and shared, respectively.