OpenACC 中的运算符重载问题

operator overloading issue in OpenACC

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 ;
    }
    }
    }
    }

// 编译器错误: 238、生成隐式拷贝(P1) 244, 复杂循环携带的依赖性阻止并行化 生成的加速器标量内核 加速器内核生成 生成特斯拉代码 244,#pragma acc循环序列 247、#pragma acc循环序列 250,#pragma acc循环序列 247, 复杂循环承载的依赖性阻止并行化 250, 复杂循环承载的依赖性阻止并行化

传引用跟这个有关系吗?

使用 "kernels" 构造,编译器必须先证明循环不包含任何依赖项,然后才能对其进行并行化。这里有一个函数调用 class 方法来更新数据。因为它不知道该方法在做什么(它可能将每次迭代映射到数组中的相同元素),所以它必须假设可能存在依赖关系。

这里有几个选项:

  • 将 "independent" 子句添加到每个循环指令中 向编译器断言循环没有依赖性。
  • 使用 "parallel" 而不是 "kernels"。使用 "parallel",您是在告诉 编译器循环并行化,因此不需要 发现它是并行性本身。
  • 终于可以使用“-Minline”了 或将 "inline" 关键字添加到运算符的定义中,以便 方法内联到主循环中。在这种情况下,编译器 将有足够的信息来确定没有依赖关系。