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

时间:2011-05-12 21:04:54

标签: struct cuda

我在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。这里发生了什么?请帮忙。

4 个答案:

答案 0 :(得分:4)

两个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安装可能会出现问题。

答案 1 :(得分:3)

总结和扩展Anycorn和talonmies的答案:

  1. 在malloc
  2. 中使用额外的&符号,例如(void**)&d_a
  3. 请勿在memcpy中使用(void**)
  4. 请务必使用cudaGetLastError检查错误并返回值。
  5. 确保使用cudaFree
  6. 在最后释放已分配的资源
  7. cudaSetDevicecudaThreadExit也不会受到伤害。
  8. 有关详细信息,请参阅reference manualprogamming guide

答案 2 :(得分:1)

检查你的cuda状态:

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

答案 3 :(得分:0)

使用

cudaDeviceSynchronize();

之后

MyFunc<<<dimgrid,dimblock>>>(d_a);

否则gpu线程可能还没有完成,你只需要从gpu内存中复制原始值。