代码之家  ›  专栏  ›  技术社区  ›  JimBamFeng

OpenACC中的运算符重载问题

  •  0
  • JimBamFeng  · 技术社区  · 6 年前
    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 回复  |  直到 6 年前
        1
  •  1
  •   Mat Colgrove    6 年前

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

    您在这里有几个选项:

    • 将“independent”子句添加到每个循环指令中 向编译器断言循环没有依赖项。
    • 使用“并行”而不是“内核”。使用“parallel”,您可以告诉 要并行化的循环的编译器,因此不需要 发现它的并行性本身。
    • 最后,您可以使用“-Minline” 或者将“inline”关键字添加到操作符的定义中,以便 方法内联到主循环中。在本例中,编译器 将有足够的信息来查看是否存在依赖关系。