这是我的代码:
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()运行时API错误11:参数无效。
实际上,这个程序是从另一个可以正常运行的程序转换而来的。但在那一个中,我在主函数中使用了两个变量S * d和S h [3]而不是在类中。更奇怪的是,我在一个小程序中实现了这个A类,它运行正常。 我已经更新了我的驱动程序,错误仍然存在。
有人能给我一个暗示,为什么会发生这种情况以及如何解决它。感谢。
答案 0 :(得分:3)
因为CUDA中的内存操作是阻塞的,所以它们会产生同步点。因此,如果没有用cudaThreadSynchonize检查,其他错误看起来就像是内存调用上的错误。
因此,如果在内存操作上收到错误,请尝试在其前面放置一个cudaThreadSynchronize并检查结果。
确保正在执行第一个malloc语句。如果这是一个关于CUDA初始化的问题,就像@Harrism指出的那样,那么它会在这个语句中失败吗?尝试放置printf语句,并查看是否执行了正确的初始化。我认为由于使用未经注册的内存区域,通常会产生无效的参数错误。
将printf写入构造函数,显示cudaMalloc的内存区域的地址
A()
{
d = NULL;
cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
printf("D: %p\n", d);
}
尝试为本地分配的区域制作内存副本,即将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));
}