CUDA cudaMemcpy:参数无效

Ton*_*Lic 3 memory cuda invalid-argument

这是我的代码:

struct S {
    int a, b;
    float c, d;
};
class A {
private:
    S* d;
    S h[3];
public:
    A() {
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
    }
void Init();
};

void A::Init() {
    for (int i=0;i<3;i++) {
        h[i].a = 0;
        h[i].b = 1;
        h[i].c = 2;
        h[i].d = 3;
    }
    cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
}

A a;
Run Code Online (Sandbox Code Playgroud)

事实上它是一个包含CUDA和OpenGL的复杂程序。当我调试这个程序时,在 cudaMemcpy 上运行时失败并显示错误信息

cudaSafeCall() 运行时 API 错误 11:参数无效。

实际上,这个程序是由另一个可以正确运行的程序改造而来的。但在那一例中,我在主函数中而不是在类中使用了两个变量 S* d 和 Sh[3]。更奇怪的是我在一个小程序中实现了这个A类,它运行得很好。我已经更新了驱动程序,错误仍然存​​在。

谁能给我提示为什么会发生这种情况以及如何解决它。谢谢。

pho*_*oad 5

由于 CUDA 中的内存操作是阻塞的,因此它们会创建一个同步点。因此,如果不使用 cudaThreadSynchonize 检查其他错误,这些错误将看起来像是内存调用上的错误。

因此,如果内存操作收到错误,请尝试在其之前放置 cudaThreadSynchronize 并检查结果。


确保第一个 malloc 语句正在执行。如果是关于 CUDA 初始化的问题,就像@Harrism 指出的那样,那么在这个语句中它会失败?尝试放置 printf 语句,并查看是否执行了正确的初始化。我认为通常无效参数错误是由于使用未初始化的内存区域而产生的。

  1. 将 printf 写入构造函数,显示 cudaMalloc 的内存区域的地址

    A()
    {
        d = NULL;
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
        printf("D: %p\n", d);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 尝试为本地分配的区域创建内存副本,即将 cudaMalloc 移至 cudaMemcopy 上方(仅用于测试)。

    void A::Init()
    {
        for (int i=0;i<3;i++)
        {
            h[i].a = 0;
            h[i].b = 1;
            h[i].c = 2;
            h[i].d = 3;
        }
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3)); // here!..
        cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
    }
    
    Run Code Online (Sandbox Code Playgroud)

祝你好运。