Прочитав несколько примеров в предыдущих постах Роберта, я смог переписать код так, чтобы он работал:
struct dummy
{
double *arr;
};
__global__ void test( dummy *dum , int n )
{
printf( "test\n" );
for( int ii = 0 ; ii < n ; ii++ )
printf( "dum->arr[%d] = %f\n" , ii , dum->arr[ii] );
}
int main()
{
int n = 10;
dummy *dum_d , *dum_h;
srand( time(0) );
dum_h = new dummy;
dum_h->arr = new double[n];
for( int ii = 0 ; ii < n ; ii++ ){
dum_h->arr[ii] = double( rand() ) / RAND_MAX;
printf( "reference data %d = %f\n" , ii , dum_h->arr[ii] );
}
cudaMalloc( &dum_d , sizeof(dummy) * 1 );
cudaMemcpy( dum_d , dum_h , sizeof(dummy) * 1 , cudaMemcpyHostToDevice );
double *tmp;
cudaMalloc( &tmp , sizeof(double) * n );
cudaMemcpy( &( dum_d->arr ) , &tmp , sizeof(double*) , cudaMemcpyHostToDevice ); // copy the pointer (host) to the device structre to a device pointer
cudaMemcpy( tmp , dum_h->arr , sizeof(double) * n , cudaMemcpyHostToDevice );
delete [] dum_h->arr;
delete dum_h;
test<<< 1 , 1 >>>( dum_d , n );
gpu_err_chk( cudaDeviceSynchronize() );
cudaFree( tmp );
cudaFree( dum_d );
return 1;
}
Однако я все еще не понимаю, почему это работает. У кого-нибудь есть визуальная схема того, что происходит? Я теряюсь с разными указателями ...
Более того, есть одна вещь, которая действительно поражает меня: я могу освободить tmp
прямо перед запуском ядра, и код все еще работает, то есть:
cudaFree( tmp );
test<<< 1 , 1 >>>( dum_d , n );
gpu_err_chk( cudaDeviceSynchronize() );
Как это так? На мой взгляд (явно неправильно), массив устройств, содержащий случайные значения, пропал ...
Еще одна путаница в том, что я не могу освободить dum_d->arr
напрямую (freeCuda(dum_d->arr)
), это бросает ошибка сегментации.