Копирование данных структуры с хоста на устройство в CUDA с использованием cudaMemcpy - PullRequest
5 голосов
/ 13 мая 2011

Я столкнулся с проблемой при копировании структурных данных с хоста на устройство в архитектуре 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;    
     }
}  

Поля x и y точки a должны были бытьизменено на 100. Вместо этого оно все еще равно 10 инициализированным.Что здесь происходит?Пожалуйста, помогите.

Ответы [ 4 ]

4 голосов
/ 13 мая 2011

Синтаксис обоих вызовов 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();
} 

работает точно так, как и ожидалось, с CUDA 3.2, работающей на 64-разрядной Linux:

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

Так что, если вы не можете повторить это, то, вероятно, что-то не так с вашей установкой CUDA.

3 голосов
/ 13 мая 2011

Чтобы сделать вывод и расширить ответы Anycorn и talonmies:

  1. Используйте дополнительный амперсанд как (void**)&d_a в malloc
  2. Не используйте (void**) в memcpy
  3. Обязательно проверьте наличие ошибок с cudaGetLastError и верните значения.
  4. Обязательно освободите выделенные ресурсы в конце с cudaFree
  5. Также cudaSetDevice и cudaThreadExit не повредят.

Подробнее см. Справочное руководство и руководство по программированию .

1 голос
/ 13 мая 2011

проверьте свои статусы cuda:

cudaMalloc((void**)&d_a,sizeof(point));  
0 голосов
/ 04 июня 2018

Использование

cudaDeviceSynchronize();

после

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

в противном случае потоки графического процессора, возможно, еще не закончили, и вы просто скопируете исходные значения из памяти в графическом процессоре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...