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循环seq247,#pragma acc循环seq250,#pragma acc loop seq247,携带的复杂循环依赖性阻止并行化250,携带的复杂回路依赖性阻止并行化
传递参考与此有关吗?
带有"内核"构造,编译器必须证明循环在可以并行化之前不包含任何依赖项。这里有一个函数调用类方法来更新数据。由于它不知道该方法在做什么(它可以将每个迭代映射到数组中的同一元素(,因此必须假设可能存在依赖关系。
您在这里有几个选择:
- 将"独立"子句添加到您的每个循环指令中向编译器断言,循环没有依赖关系。
- 使用"并行"而不是"内核"。使用"平行",您正在告诉编译器要平行循环,因此不需要发现它本身。
- 最后,您可以使用" -minline"或将"内联"关键字添加到操作员的定义中,以便方法被内衬到主循环中。在这种情况下,编译器将有足够的信息来了解没有依赖关系。