c++ 如何在OpenACC中'std::shuffle' CSR数组

tquggr8v  于 2023-01-06  发布在  其他
关注(0)|答案(1)|浏览(134)

为了设置上下文,我有一个正在运行的C++代码(一个图形算法),我试图在GPU和多核上使用OpenACC /nvc++来加速它。我使用vectorvector来存储邻接列表。由于向量会影响性能,我决定使用CSR数组来重写--这在GPU程序中最常见。目标是随机化每个顶点的邻居。
创建CSR阵列后,我使用std::shuffle来实现相同的操作。

int* offset;
  int* value;
  
  convert_VecOfVec_to_CSR(a, offset, value); 
  shuffleIt(offset, value, n);
  
  // DEFINITION
void shuffleIt(int *&offset, int* &value, int n){
  #pragma acc parallel loop
  for (int i = 0; i < n; ++i) {
    std::shuffle(value+offset[i], value+offset[i+1] ,std::default_random_engine(rand()));
  }
}

当使用acc=multicore时,代码编译和运行正常。但是我得到了下面的gpu错误。这是否意味着我不能在我的OpenACC的gpu代码中使用std::shufflerandom函数?我记得math.h函数工作正常。请提供建议。谢谢。

$ nvc++ -acc -gpu=managed -Minfo=all shuffle-2D-csr2.cpp -o shuffle-2D-csr2.out && ./shuffle-2D-csr2.out
NVC++-S-1061-Procedures called in a compute region must have acc routine information - std::linear_congruential_engine<unsigned long, (unsigned long)16807, (unsigned long)0, (unsigned long)2147483647>::linear_... (shuffle-2D-csr2.cpp: 66)
shuffleIt(int *&, int *&, int):
     66, Accelerator restriction: call to 'std::linear_congruential_engine<unsigned long, (unsigned long)16807, (unsigned long)0, (unsigned long)2147483647>::linear_congruential_engine(unsigned long)' with no acc routine information
std::linear_congruential_engine<unsigned long, (unsigned long)16807, (unsigned long)0, (unsigned long)2147483647>::operator ()():
      7, include "random"
          49, include "random.h"
              348, Generating implicit acc routine seq
                   Generating acc routine seq
                   Generating NVIDIA GPU code
...
NVC++/x86-64 Linux 22.7-0: compilation completed with severe errors

我还没有添加任何data子句,为了首先使功能正确。
Full Gist code
我正在学习OpenACC。

eoxn13cs

eoxn13cs1#

为了调用一个设备函数,需要有一个可用的设备版本的例程。如果你正在使用模板或者当函数的定义在编译时对编译器可见时,那么nvc通常可以为你自动生成设备函数。否则,你需要用“acc routine”指令来修饰函数,以便生成例程的设备版本。然而,我怀疑你是否能在这里添加一个“例程”指令,因为它是一个系统调用。
某些libc
已移植到设备(请参见:https://nvidia.github.io/libcudacxx/),但目前还不是全部。
尽管一般来说,你需要小心设备上的随机数生成。RNG不是线程安全的,你可以在状态变量上得到冲突。几年前我写了一个详细的回应,你可以在这里阅读:Portable random number generation with OpenACC
这篇文章可能也有帮助:https://www.openacc.org/blog/pseudo-random-number-generation-lightweight-threads

相关问题