0
votes
I am trying to overload a simple parenthesis in the following class



   class MyClass{

    private:
    double *P;
    // some code to allocate required variables on the device on the device
    #pragma acc routine
     public:
    double &operator()( int i, int j, int k );

    }
// constructor


   MyClass::MyClass( int n )
    {
    N = n;
    P=new double[N*N*N];

    for(int i=0;i<N*N*N;i++)
    {
    P[i]=0.0;
    }
    #pragma acc enter data create(this[0:1])
    #pragma acc enter data create(P[0:N*N*N])
    #pragma acc update device(this)
    }





 #pragma acc routine
    double& MyClass::operator()(int i, int j,int k)
    {

    // some assertion to catch bugs
    //
    return P[i+N*j+N*N*k];
    }



  int main()
    {
    MyClass P1;
    // using a very simple assignment
    #pragma acc kernels
    #pragma acc loop
    for ( int i = 0; i < N; i++ )
    {
    #pragma acc loop
    for ( int j = 0; j < N; j++ )
    {
    #pragma acc loop
    for ( int k = 0; k < N; k++ )
    {

    P1( i, j, k )=2.0 ;
    }
    }
    }
    }

// the compiler errors : 238, Generating implicit copy(P1) 244, Complex loop carried dependence of prevents parallelization Accelerator scalar kernel generated Accelerator kernel generated Generating Tesla code 244, #pragma acc loop seq 247, #pragma acc loop seq 250, #pragma acc loop seq 247, Complex loop carried dependence of prevents parallelization 250, Complex loop carried dependence of prevents parallelization

Is passing a reference has anything to do with this?

1

1 Answers

1
votes

With the "kernels" construct, the compiler must prove that the loop does not contain any dependencies before it can parallelize it. Here there's a function call to a class method to update the data. Since it doesn't know what that method is doing (it could be mapping each iteration to the same element in an array), it must assume that there could be a dependency.

You have several options here:

  • Add the "independent" clause to each of your loop directives to assert to the compiler that the loops don't have dependencies.
  • Use "parallel" instead of "kernels". With "parallel", you're telling the compiler which loop to parallelize and therefore it doesn't need to discover it the parallelism itself.
  • Finally, you can use "-Minline" or add the "inline" keyword to the operator's definition so that the method is inlined into the main loop. In this case, the compiler will have enough information to see that there's no dependencies.