2017-04-03 7 views
0

次のように私は、構造体があるとします。今コピー配列

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私は不正なメモリアクセスを取得しようとするとエラーが発生しました。あなたは__device__ポインタ変数を使用して、これまでに示されているものについては

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

だけで不必要な複雑を作成します。

は、ここに私の現在の試みです。デバイスの格納にはcudaMallocを使用する通常の動的割り当てを使用してください。それ以外の場合は、vectorAddなどのCUDAサンプルコードのいずれかと同様の方法に従ってください。次に例を示します。

$ 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で解決された例に従うことができます。

$ 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

こんにちは:

はその一例に続き、ここではそれが__device__ポインタ変数の代わりに、カーネルパラメータとして渡されたポインタを動作させるために上記のコードへの変更のセットです。役に立った返信ありがとう。私は私の質問であまりにも明確ではなかった、申し訳ありません。これは、myKernelがmainから呼び出されないため、デバイスポインタを使用する必要があることです。代わりに、私はいくつかの外部コードからランダムなイベントを受け取った後に呼び出されます。言い換えれば、私はd_ptrをカーネルのパラメータとして渡すことができません。どこかへの参照を保つ必要があります。 – William

+0

変更は比較的軽微ですので、変更を示す例を追加しました。 –