Копирование структурных данных с хоста на устройство на CUDA с использованием cudaMemcpy

#struct #cuda

#структура #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 %lfn",a->x,a->y);
}  

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

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

Ответ №1:

Синтаксис обоих вызовов 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 amp;amp; 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**)amp;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 %lfn",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.

Комментарии:

1. Я запустил это, и мой терминал все еще печатает 10 дважды!! Что-то не так с моей картой cuda?

Ответ №2:

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

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

Смотрите справочное руководство и руководство по программированию для получения более подробной информации.

Комментарии:

1. Спасибо, ЛумпН, но мы пытались сделать все это, но все равно безрезультатно!! Может ли быть какая-либо другая возможность??

Ответ №3:

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

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

Комментарии:

1. @Vikesh: Обратите внимание на дополнительный амперсанд amp; перед d_a !