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" 关键字添加到运算符的定义中,以便
方法内联到主循环中。在这种情况下,编译器
将有足够的信息来确定没有依赖关系。
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" 关键字添加到运算符的定义中,以便 方法内联到主循环中。在这种情况下,编译器 将有足够的信息来确定没有依赖关系。