2012-03-29 8 views
2

私はcudaMemcpy(...)を呼び出してGPU上のメモリを取得しても、配列内の値もコピーされているかどうかを知りたいと思います。私はもっ​​とうまく説明します:ある配列から別の配列に値をコピーしてから、私はcudaMallocとcudaMemcpyを呼び出します。だから、cudaMemcpyの後の配列の値

// Copying values of the arrays 
for(int i = 0; i<16; i++){ 
    array_device_1[i] = array_host_1[i]; 
    array_device_2[i] = array_host_2[i]; 
} 

// Memory allocation of array_device_1 and array_device_2 
cudaMalloc((void**) &array_device_1, SIZE_INT*size); 
cudaMalloc((void**) &array_device_2, SIZE_INT*size); 

// Transfer array_device_1 and array_device_2 
cudaMemcpy(array_device_1, array_host_1, SIZE_INT*size, cudaMemcpyHostToDevice); 
cudaMemcpy(array_device_2, array_host_2, SIZE_INT*size, cudaMemcpyHostToDevice); 

kernel<<<N, N>>>(array_device_1, array_device_2); 

cudaMemcpy(array_host_1, array_device_1, SIZE_INT*size, cudaMemcpyDeviceToHost); 
cudaMemcpy(array_host_2, array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost); 

cudaFree(array_device_1); 
cudaFree(array_device_2); 

、私はこれらすべての命令を実行していると私はカーネル内部のすべてのアレイを使用していたときに、値array_device_1とarray_device_2内部のかそうでありませんか?私はカーネルの後に印刷しようとしましたが、私はすべての配列が空であることに気付きました!本当に私はどのように私はそれらの内部の値を保持することができますし、カーネル関数でそれらの値を変更することを理解できません。

+1

あなたの '//がarrays'一部の値をコピーすると、いずれかを行うことはありませんセンス。このように、ホストからデバイスメモリにデータをコピーすることはできません。それは 'cudaMemcpy'がそこにあるのです! – leftaroundabout

答えて

4

はいこれらの値は内部にあります。しかし、あなたはそれらをホスト上に印刷することはできません。このためには、バック

cudaMemcpy((void *) array_host_2, (void *) array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost); 

を使用してデータをコピーする必要があります。そして、あなたはarray_host_2の値を印刷することができます。

少し説明:あなたのarray_device_*は、GPUとあなたのCPUから(あなたの出力を印刷しています)、このデータに直接アクセスすることはできません。だからあなたはそれを印刷する前にまずあなたのCPUメモリにコピーし直す必要があります。

+0

私はGPU部分を悪用せずに私のカーネルをテストしました。私はアルゴリズムをテストしてうまく動作することを意味します。私は本当に私が行方不明を説明することはできません – davideberdin

1

あなたが指定したコードスニペットは、最初の数行を除いて正しいと思われます。カーネルが正しいと確信していますか?おそらく、変更された値をグローバルメモリに書き戻しているとは限りません。別のホスト配列セットを作成し、カーネルを実行する前にGPUアレイをコピーした場合、それらは正しいのでしょうか?あなたが持っているものから、array_host_ *内の値はarray_device_ *に正しくコピーされているはずです。

1

バックホストにコピーし、カーネルの値を変更すること、デバイスにデータを配列にコピーし、新しい値を印刷する例:

// Function to run on device by many threads 
__global__ void myKernel(int *d_arr) { 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 
    d_arr[idx] = d_arr[idx]*2; 
} 

int main(void) { 
    int *h_arr, *d_arr; 
    h_arr = (int *)malloc(10*sizeof(int)); 
    for (int i=0; i<10; ++i) 
     h_arr[i] = i; // Or other values 

    // Sends data to device 
    cudaMalloc((void**) &d_arr, 10*sizeof(int)); 
    cudaMemcpy(d_arr, h_arr, 10*sizeof(int), cudaMemcpyHostToDevice); 

    // Runs kernel on device 
    myKernel<<< 2, 5 >>>(d_arr); 

    // Retrieves data from device 
    cudaMemcpy(h_arr, d_arr, 10*sizeof(int), cudaMemcpyDeviceToHost); 

    for (int i = 0; i<10; ++i) 
     printf("Post kernel value in h_arr[%d] is: %d\n", i,h_arr[i]); 

    cudaFree(d_arr); 
    free(h_arr); 
    return 0; 
}