在 openacc 中为每个帮派进行递归的私有数组
Private Array that goes through recursion for each gang in openacc
如何在 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 行取消注释该行。请帮忙!
"private" 数组未初始化,但您的代码期望它们具有初始值。您要么想要在循环中初始化数组,要么使用 "firstprivate" 子句,该子句将使用主机的初始值初始化每个私有数组。
此外,您在私有子句和数据子句中都有 "random" 和 "ptr"。您应该将它们从数据指令中删除,因为这将使它们成为全局的。
设备上的递归存在问题,因为 GPU 上的堆栈非常小 (8MB)。您可以通过将 PGI 环境变量 "PGI_CUDA_STACKSIZE" 设置为更大的值来增加此值,但如果递归太深,程序将崩溃。
我试过 运行 你的程序,但它一直出错,可能是由于堆栈溢出。我不确定要使用什么输入值,所以也可能是我的飞行员错误。
如果使用 "firstprivate" 没有帮助,请告诉我要使用的输入值,我会进一步研究。
如何在 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 行取消注释该行。请帮忙!
"private" 数组未初始化,但您的代码期望它们具有初始值。您要么想要在循环中初始化数组,要么使用 "firstprivate" 子句,该子句将使用主机的初始值初始化每个私有数组。
此外,您在私有子句和数据子句中都有 "random" 和 "ptr"。您应该将它们从数据指令中删除,因为这将使它们成为全局的。
设备上的递归存在问题,因为 GPU 上的堆栈非常小 (8MB)。您可以通过将 PGI 环境变量 "PGI_CUDA_STACKSIZE" 设置为更大的值来增加此值,但如果递归太深,程序将崩溃。
我试过 运行 你的程序,但它一直出错,可能是由于堆栈溢出。我不确定要使用什么输入值,所以也可能是我的飞行员错误。
如果使用 "firstprivate" 没有帮助,请告诉我要使用的输入值,我会进一步研究。