c++ - 在 openacc 中为每个帮派进行递归的私有(private)数组

标签 c++ parallel-processing gpu openacc pgi

如何在 openacc 中正确地使数组私有(private)化?为了我的使用,我声明了一个数组,它通过递归函数并 self 更新。在 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);
    }
  }
 }

但似乎数组没有传递给递归函数,因为我已经检查过它没有改变。执行此操作的完美方法是什么?

附注我也尝试过 #pragma acc data pcreate(array[0:N])#pragma acc parallel loop independent private(array[0:N]) 但结果是一样的

你可以找到完整的代码here .没有指令它可以完美运行。您唯一需要更改的是用 curand 注释该行,并在 251 268 行取消注释该行。请帮忙!

最佳答案

“私有(private)”数组未初始化,但您的代码期望它们具有初始值。您要么想要在循环中初始化数组,要么使用“firstprivate”子句,该子句将使用来自主机的初始值初始化每个私有(private)数组。

此外,您在私有(private)子句和数据子句中都有“random”和“ptr”。您应该从数据指令中删除它们,因为这将使它们成为全局的。

鉴于 GPU 上的堆栈非常小 (8MB),设备上的递归是有问题的。您可以通过将 PGI 环境变量“PGI_CUDA_STACKSIZE”设置为更大的值来增加此值,但如果递归太深,程序将崩溃。

我尝试运行您的程序,但它一直出错,可能是由于堆栈溢出。我不确定要使用什么输入值,所以这也可能是我的飞行员错误。

如果使用“firstprivate”没有帮助,请告诉我要使用的输入值,我会进一步研究。

关于c++ - 在 openacc 中为每个帮派进行递归的私有(private)数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47039512/

相关文章:

c++ - 链接时如何删除拷贝?

c++ - C++中最小堆的比较器

c++ - 谐波级数和 c++ openMP

c++ - std::list 中无锁的并行追加和迭代

c++ - Tensorflow C++ 不使用 GPU

c++ - 在套接字 C/C++ 上发送浮点值

c# - 使用第三方 DLL 对 PInvokeStackImbalance 进行故障排除

arrays - 并行数据处理

linux - OpenCL 设备仅对 root 可见

python - Keras 验证损失计算不正确