2017-04-03 74 views
0

假设我有一个结构如下:复制阵列从主机到设备的CUDA

typedef struct values{ 
int one, int two, int three 
} values; 

现在,假设我在主机上创建值的阵列,并用随机数据

values vals*; 
__device__ values* d_vals; 
int main(){ 
    vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER); 
    PopulateWithDate(); //populates vals with random data 
} 
填充

现在,我希望能够将值复制到设备上,这样我可以访问他们在我的内核像这样:

__global__ void myKernel(){ 
    printf("%d", d_vals[0].one);//I don't really want to print, but whenever I try to access I get an error 
} 

Whate ver我尝试我得到一个非法的内存访问被遇到错误。

这是我当前的尝试:

int main(){ 
    vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER); 
    PopulateWithDate(); //populates vals with random data 

    values* d_ptr; 
    cudaGetSymbolAddress((void**)&d_ptr, d_vals); 
    cudaMalloc((void**)&d_ptr, A_LARGE_NUMBER * sizeof(values)); 

    cudaMemcpyToSymbol(d_ptr, &vals, sizeof(values) * A_LARGE_NUMBER); 
    cudaDeviceSynchronize(); 
    dim3 blocksPerGrid(2, 2); 
    dim3 threadsPerBlock(16, 16); 

    myKernel<< <blocksPerGrid, threadsPerBlock >> >(); 
} 

回答

1

对于到目前为止你已经证明什么,使用__device__指针变量只是创建不必要的复杂性。只需使用cudaMalloc用于设备存储的普通动态分配,然后按照类似于任何CUDA示例代码(如vectorAdd)的方法使用。这里有一个例子:

$ cat t1315.cu 
#include <stdio.h> 
#define A_LARGE_NUMBER 10 

struct values{ 
int one, two, three; 
}; 

values *vals; 

__global__ void myKernel(values *d_vals){ 
    printf("%d\n", d_vals[0].one); 
} 

void PopulateWithData(){ 
    for (int i = 0; i < A_LARGE_NUMBER; i++){ 
    vals[i].one = 1; 
    vals[i].two = 2; 
    vals[i].three = 3; 
    } 
} 


int main(){ 
    vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER); 
    PopulateWithData(); //populates vals with random data 

    values* d_ptr; 
    cudaMalloc((void**)&d_ptr, A_LARGE_NUMBER * sizeof(values)); 
    cudaMemcpy(d_ptr, vals, A_LARGE_NUMBER *sizeof(values),cudaMemcpyHostToDevice); 
    dim3 blocksPerGrid(1,1); 
    dim3 threadsPerBlock(1, 1); 

    myKernel<< <blocksPerGrid, threadsPerBlock >> >(d_ptr); 
    cudaDeviceSynchronize(); 
} 
$ nvcc -arch=sm_35 -o t1315 t1315.cu 
$ cuda-memcheck ./t1315 
========= CUDA-MEMCHECK 
1 
========= ERROR SUMMARY: 0 errors 
$ 

您有一些其它的基本(非CUDA)在你已经表明了什么,我不会尝试,并通过他们所有运行的代码错误。

如果你真的想留住你__device__指针变量,并用它来指向设备的数据(结构的数组),那么你还需要使用cudaMalloc,整体过程需要额外的步骤。你可以按照解答here中的例子。

此之后例如,这里有一组更改上面的代码,使其与__device__指针变量,而不是作为内核参数传递的指针工作:

$ cat t1315.cu 
#include <stdio.h> 
#define A_LARGE_NUMBER 10 

struct values{ 
int one, two, three; 
}; 

values *vals; 
__device__ values *d_vals; 

__global__ void myKernel(){ 
    printf("%d\n", d_vals[0].one); 
} 

void PopulateWithData(){ 
    for (int i = 0; i < A_LARGE_NUMBER; i++){ 
    vals[i].one = 1; 
    vals[i].two = 2; 
    vals[i].three = 3; 
    } 
} 


int main(){ 
    vals = (values*)malloc(sizeof(values) * A_LARGE_NUMBER); 
    PopulateWithData(); //populates vals with random data 

    values* d_ptr; 
    cudaMalloc((void**)&d_ptr, A_LARGE_NUMBER * sizeof(values)); 
    cudaMemcpy(d_ptr, vals, A_LARGE_NUMBER *sizeof(values),cudaMemcpyHostToDevice); 
    cudaMemcpyToSymbol(d_vals, &d_ptr, sizeof(values*)); 
    dim3 blocksPerGrid(1,1); 
    dim3 threadsPerBlock(1, 1); 

    myKernel<< <blocksPerGrid, threadsPerBlock >> >(); 
    cudaDeviceSynchronize(); 
} 
$ nvcc -arch=sm_35 -o t1315 t1315.cu 
$ cuda-memcheck ./t1315 
========= CUDA-MEMCHECK 
1 
========= ERROR SUMMARY: 0 errors 
$ 
+0

嗨。感谢您的有益回应。对不起,我的问题不太清楚。事情是我必须使用设备指针,因为myKernel不会从main调用。相反,它会在我从外部代码收到一个随机事件后被调用。换句话说,我将无法将d_ptr作为参数传递给内核,我必须在某处保留对其的引用 – William

+0

确定这些更改相对较小,因此我添加了一个演示变化的示例。 –

相关问题