如何在openacc中正确地使数组成为私有?为了我的使用,我已经声明了一个通过递归函数并自行更新的数组。在C ++中我这样做了,
int recursion(int array[],int i)
{
....
return array[i] = recursion(array,i);
}
int main()
{
....
for(int run=0;run<N;++run)
{
....
for(int i=0;i<some N;++i)
int f = recursion(array,i);
}
.....
}
现在,当我尝试使用openacc指令并行执行此操作时,主要问题就开始了。我想将这个数组复制到并行for循环区域,这样每个组都将拥有该数组的副本,并且能够使用递归函数更改自己的array []版本而不是其他版本。我尝试这样做的方式是
#pragma acc routine seq
int recursion(int array[],int i)
{
....
return array[i] = recursion(array,i);
}
int main()
{
....
#pragma acc data copyin(array[0:N])
#pragma acc parallel loop gang private(array[0:N])
for(int run=0;run<N;++run)
{
....
for(int i=0;i<N;++i)
{
....
int f = recursion(array,i);
}
}
}
但似乎数组没有传递给递归函数,因为我已经检查过它没有改变。这样做的最佳方式是什么?
P.S。我也尝试了#pragma acc data pcreate(array[0:N])
与#pragma acc parallel loop independent private(array[0:N])
,但结果是相同的
您可以找到整个代码here。它在没有指令的情况下完美运行。你需要改变的只是用curand注释该行,并在251 268行用rand取消注释该行。请帮助!
答案 0 :(得分:1)
“私有”数组未初始化但您的代码期望它们具有初始值。你要么想要在循环中初始化数组,我们使用“firstprivate”子句,它将使用来自主机的初始值初始化每个私有数组。
此外,私有子句和数据子句中都有“random”和“ptr”。您应该从data指令中删除它们,因为这会使它们成为全局的。
设备上的递归是有问题的,因为GPU上的堆栈非常小(8MB)。您可以通过将PGI环境变量“PGI_CUDA_STACKSIZE”设置为更大的值来增加此值,但如果递得太深,程序将崩溃。
我尝试运行你的程序,但它一直出错,大概是由于堆栈溢出。我不确定要使用哪些输入值,所以它也可能是我的导航错误。
如果使用“firstprivate”没有帮助,请告诉我要使用的输入值,我会进一步研究。