在CUDA上使用cudaMemcpy将结构体数据从主机复制到设备

7
我在CUDA架构中复制主机到设备的结构数据时遇到了问题。
以下是代码片段。
struct point  
{  
     double x,y;  
};

int main()  
{  
   point * a = (point*)malloc(sizeof(point));  
   a->x=10.0;   
   a->y=10.0;    
   point * d_a;  
   cudaMalloc((void**)d_a,sizeof(point));  
   cudaMemcpy((void**)d_a,a,sizeof(point),cudaMemcpyHostToDevice);  
   dim3 dimblock(16,16);  
   dim3 dimgrid(1,1);  

   MyFunc<<<dimgrid,dimblock>>>(d_a);  
   cudaMemcpy((void**)a,d_a,sizeof(point),cudaMemcpyDeviceToHost);    
   printf("%lf %lf\n",a->x,a->y);
}  

__global__ void MyFunc(point* d_a)  
{  
     if(threadIdx.x == 0 && threadIdx.y == 0)
     {  
        d_a->x=100.0;  
        d_a->y = 100.0;    
     }
}  

点a的x和y字段应该已经更改为100。但事实上,它仍然是初始化时的10。这里发生了什么?请帮忙解决。
3个回答

5

两个cudaMemcpy()调用的语法不正确,应该改为:

cudaMemcpy(d_a,a,sizeof(point),cudaMemcpyHostToDevice);

并且

cudaMemcpy(a,d_a,sizeof(point),cudaMemcpyDeviceToHost);    

编辑:

这个:

#include <cstdio>
#include <cstdlib>

struct point  
{  
     double x,y;  
};

__global__ void MyFunc(point* d_a)  
{  
     if(threadIdx.x == 0 && threadIdx.y == 0)
     {  
        d_a->x=100.0;  
        d_a->y = 100.0;    
     }
}  

int main(void)  
{  
   point * a = (point*)malloc(sizeof(point));  
   a->x=10.0;   
   a->y=10.0;    
   point * d_a;  
   cudaMalloc((void**)&d_a,sizeof(point));  
   cudaMemcpy(d_a,a,sizeof(point),cudaMemcpyHostToDevice);  
   dim3 dimblock(16,16);  
   dim3 dimgrid(1,1);  

   MyFunc<<<dimgrid,dimblock>>>(d_a);  
   cudaMemcpy(a,d_a,sizeof(point),cudaMemcpyDeviceToHost);    
   printf("%lf %lf\n",a->x,a->y);

   return cudaThreadExit();
} 

在64位Linux上运行CUDA 3.2时,它的表现与预期一致:

cuda:~$ nvcc -arch=sm_20 -o bungle bungle.cu 
cuda:~$ ./bungle 
100.000000 100.000000

如果您无法复制此操作,则可能是您的CUDA安装存在问题。

2
我运行了这个程序,但我的终端仍然打印两次10!! 我的CUDA显卡有问题吗? - Srini

3
为了总结和扩展Anycorn和talonmies的答案:
  1. 在malloc中使用额外的“&”符号,如(void**)&d_a
  2. 不要在memcpy中使用(void**)
  3. 确保使用cudaGetLastError检查错误并返回值。
  4. 确保在最后使用cudaFree释放已分配的资源
  5. cudaSetDevicecudaThreadExit也不会有问题。

有关更多详细信息,请参见参考手册编程指南


谢谢LumpN,但我们尝试了所有的方法,仍然没有帮助!难道还有其他可能性吗? - Vikesh

1

检查您的CUDA状态:

cudaMalloc((void**)&d_a,sizeof(point));  

@Vikesh:注意在 d_a 前面有额外的和号 & - Jonas Bötel

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