OpenACC中的运算符重载问题

时间:2018-02-16 20:58:04

标签: operator-overloading gpu 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 loop seq 247,#pragma acc loop seq 250,#pragma acc loop seq 247,复杂循环携带依赖性防止并行化 250,复杂循环携带依赖性阻止并行化

传递引用是否与此有关?

1 个答案:

答案 0 :(得分:1)

使用&#34;内核&#34;构造,编译器必须证明循环在它可以并行化之前不包含任何依赖关系。这里有一个函数调用类方法来更新数据。由于它不知道该方法正在做什么(它可能将每次迭代映射到数组中的相同元素),因此它必须假设可能存在依赖。

这里有几个选项:

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