来自简单循环的OpenAcc错误:内核执行期间的非法地址

时间:2018-06-25 18:00:03

标签: c++ openacc

当我尝试并行化此简单循环时,出现“调用cuMemcpyDtoHsync返回错误700:内核执行期间的非法地址”错误。

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<float> xF = {0, 1, 2, 3};

    #pragma acc parallel loop
    for (int i = 0; i < 4; ++i) {
        xF[i] = 0.0;
    }
    return 0;
}

编译为:$ pgc ++ -fast -acc -std = c ++ 11 -Minfo = accel -o test test.cpp

main:
  6, Accelerator kernel generated
     Generating Tesla code
      9, #pragma acc loop gang, vector(4) /* blockIdx.x threadIdx.x */
std::vector<float, std::allocator<float>>::operator [](unsigned long):
  1, include "vector"
      64, include "stl_vector.h"
          771, Generating implicit acc routine seq
               Generating acc routine seq
               Generating Tesla code
T3 std::__copy_move_a2<(bool)0, const float *,     decltype((std::allocator_traits<std::allocator<float>>::_S_pointer_helper<std::allocator<float>>((std::allocator<float>*)0)))>(T2, T2, T3):
  1, include "vector"
      64, include "stl_vector.h"
/usr/bin/ld: error in /tmp/pgc++cAUEgAXViQSY.o(.eh_frame); no .eh_frame_hdr table will be created.

$ ./test
call to cuStreamSynchronize returned error 700: Illegal address during kernel execution

代码在没有#pragma的情况下可以正常运行,但我想使其并行。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

尝试使用“ -ta = tesla:managed”进行编译。

这里的问题是您没有显式管理主机和设备之间的数据移动,并且编译器无法为您隐式管理数据,因为std :: vector只是指针类,因此编译器可以告诉数据的大小。因此,设备正在使用主机地址,从而导致非法的内存访问。

虽然您可以通过获取向量的原始指针然后使用data子句复制向量的数据以及将向量本身复制到设备来自己管理数据,但是使用CUDA统一内存要容易得多(即“托管”标志),并让CUDA运行时为您管理数据移动。

正如Jerry指出的那样,通常不建议在并行代码中使用向量,因为它们不是线程安全的。在这种情况下可以,但是您可能会遇到其他问题,尤其是当您尝试推送或弹出数据时。更好地使用数组。 Plus阵列更易于在主机副本和设备副本之间进行管理。

% cat test.cpp
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<float> xF = {0, 1, 2, 3};

    #pragma acc parallel loop
    for (int i = 0; i < 4; ++i) {
        xF[i] = 0.0;
    }
    for (int i = 0; i < 4; ++i) {
        std::cout << xF[i] << std::endl;
    }
    return 0;
}
% pgc++ -ta=tesla:cc70,managed -Minfo=accel test.cpp --c++11 ; a.out
main:
      6, Accelerator kernel generated
         Generating Tesla code
          9, #pragma acc loop gang, vector(4) /* blockIdx.x threadIdx.x */
      6, Generating implicit copy(xF)
std::vector<float, std::allocator<float>>::operator [](unsigned long):
      1, include "vector"
          64, include "stl_vector.h"
              771, Generating implicit acc routine seq
                   Generating acc routine seq
                   Generating Tesla code
0
0
0
0