#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:
- Используйте дополнительный амперсанд, подобный
(void**)amp;d_a
в malloc - Не используйте
(void**)
в memcpy - Обязательно проверьте наличие ошибок с
cudaGetLastError
и возвращаемыми значениями. - В конце обязательно освободите выделенные ресурсы с помощью
cudaFree
- Также
cudaSetDevice
иcudaThreadExit
не повредит.
Смотрите справочное руководство и руководство по программированию для получения более подробной информации.
Комментарии:
1. Спасибо, ЛумпН, но мы пытались сделать все это, но все равно безрезультатно!! Может ли быть какая-либо другая возможность??
Ответ №3:
проверьте свои статусы cuda:
cudaMalloc((void**)amp;d_a,sizeof(point));
Комментарии:
1. @Vikesh: Обратите внимание на дополнительный амперсанд
amp;
передd_a
!