Copying struct data from host to device on CUDA us

2019-04-09 16:24发布

I am facing a problem in copying struct data from host to device in the CUDA architecture.
Following is the code snippet.

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

The x and y fields of point a should have been changed to 100. Instead, it is still 10 as initialized. What is happening here? Please help.

标签: struct cuda
4条回答
smile是对你的礼貌
2楼-- · 2019-04-09 16:49

To conclude and extend the answers of Anycorn and talonmies:

  1. Use an additional ampersand like (void**)&d_a in malloc
  2. Don't use (void**) in memcpy
  3. Make sure to check for errors with cudaGetLastError and return values.
  4. Make sure to free allocated resources at the end with cudaFree
  5. Also cudaSetDevice and cudaThreadExit won't hurt.

See the reference manual and the progamming guide for more details.

查看更多
走好不送
3楼-- · 2019-04-09 16:52

check your cuda statuses:

cudaMalloc((void**)&d_a,sizeof(point));  
查看更多
Lonely孤独者°
4楼-- · 2019-04-09 16:57

Use

cudaDeviceSynchronize();

after

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

otherwise the gpu threads may not have finished yet, and you'll just be copying back the original values from the memory on the gpu.

查看更多
祖国的老花朵
5楼-- · 2019-04-09 17:03

The syntax of both cudaMemcpy() calls is incorrect, they should be

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

and

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

EDIT:

This:

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

works precisely as expected with CUDA 3.2 running on 64 bit linux:

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

So if you cannot replicate this, then something is probably wrong with your CUDA installation.

查看更多
登录 后发表回答