CUDA cudaMemcpy:无效参数

3
这是我的代码:
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;

实际上这是一个包含CUDA和OpenGL的复杂程序。当我调试这个程序时,它在执行cudaMemcpy时失败,并显示以下错误信息:cudaSafeCall() Runtime API error 11: invalid argument。
事实上,这个程序是由另一个可以运行正确的程序转换而来的。但在那个程序中,我在主函数中使用了两个变量S* d和S h[3],而不是在类中使用。更奇怪的是,在一个小程序中,我实现了这个A类,它可以正常工作。我已经更新了驱动程序,但错误仍然存在。
请问有谁能够给我提示为什么会出现这种情况以及如何解决它?谢谢。

顺便提一下,cudaMemcpy 函数将返回 cudaErrorInvalidValue。 - TonyLic
2
变量 A a; 在哪里定义?它是在函数内还是全局的?如果它是全局的,那么在你获得一个有效的设备上下文之前,构造函数可能会被调用 (我不确定这一点,但有可能)。如果是这种情况,那么传递给 cudaMemcpy 的 d 指针就会是无效的。 - harrism
дҪ иғҪеҲҶдә«дёҖдёӢдҪ дҪҝз”Ёзҡ„CUDAй…ҚзҪ®еҗ—пјҹжҲ‘ж— жі•еңЁж—§зҡ„GeForce 9400mе’ҢCUDA 5.0йў„и§ҲзүҲдёҠйҮҚзҺ°дҪ зҡ„й”ҷиҜҜгҖӮ - jopasserat
1个回答

5
由于CUDA中的内存操作是阻塞式的,它们会产生同步点。因此,如果不使用cudaThreadSynchronize检查其他错误,这些错误可能会像内存调用错误一样。
因此,如果在内存操作中收到错误,请尝试在其前面放置一个cudaThreadSynchronize并检查结果。
请确保第一个malloc语句被执行。如果出现CUDA初始化问题,例如@Harrism所指示的那样,则会在此语句中失败吗?尝试放置printf语句,并查看是否执行了适当的初始化。我认为通常会生成无效参数错误,因为使用了未初始化的内存区域。
  1. Write a printf to your constructor showing the address of the cudaMalloc'ed memory area

    A()
    {
        d = NULL;
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
        printf("D: %p\n", d);
    }
    
  2. Try to make a memory copy for an area that is locally allocated, namely move the cudaMalloc to above of cudaMemcopy (just for testing).

    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));
    }
    

祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接