1

caps openacc コンパイラを使用しています。自分でメモリを管理できるのだろうか?

たとえば、CUDA を使用した通常の openacc コードは次のとおりです。

 #pragma acc kernels copyin(a,b) copy(c)
  for (i = 0; i < SIZE; ++i)
    for (j = 0; j < SIZE; ++j)
      for (k = 0; k < SIZE; ++k)
        c[i][j] += a[i][k] * b[k][j];

こんな風に変化してほしい

//allocation
cudaMalloc((void**)&a, num_bytes);
cudaMalloc((void**)&b, num_bytes);
cudaMalloc((void**)&c, num_bytes);

//transfer-in
cudaMemcpy(hostA, a, num_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(hostB, b, num_bytes, cudaMemcpyHostToDevice);

//computation
//i think it will be generated as codelet by CAPS openACC compiler.
#pragma acc kernels
  for (i = 0; i < SIZE; ++i)
    for (j = 0; j < SIZE; ++j)
      for (k = 0; k < SIZE; ++k)
        c[i][j] += a[i][k] * b[k][j];

cudaMemcpy(c, hostC, num_bytes, cudaMemcpyDeviceToHost);
cudaFree(&a);cudaFree(&b);cudaFree(&c);
4

2 に答える 2

3

はい、メモリを自分で割り当てることができます。あなたの例では、プラグマを使用してこれを達成できるはず device_ptrなので、次のようになります。

cudaMalloc((void**)&a, num_bytes);
cudaMalloc((void**)&b, num_bytes);
cudaMalloc((void**)&c, num_bytes);

cudaMemcpy(hostA, a, num_bytes, cudaMemcpyHostToDevice);
cudaMemcpy(hostB, b, num_bytes, cudaMemcpyHostToDevice);

#pragma acc data deviceptr(a, b, c)
#pragma acc kernels
  for (i = 0; i < SIZE; ++i)
    for (j = 0; j < SIZE; ++j)
      for (k = 0; k < SIZE; ++k)
        c[i][j] += a[i][k] * b[k][j];

cudaMemcpy(c, hostC, num_bytes, cudaMemcpyDeviceToHost);
cudaFree(a);cudaFree(b);cudaFree(c);

[免責事項: ブラウザで書かれ、コンパイルもテストもされていません。自己責任で使用してください]

aこれは、bcがコンパイラへの既存の割り当てであることを宣言する必要があります。必要に応じて、OpenACCacc_mallocルーチンを使用して の代わりにメモリを割り当てることもできcudaMallocます。

device_residentこの回答の最初のバージョンでの誤った使用を指摘してくれた @ user2054656 に感謝します。

于 2013-05-03T08:03:03.313 に答える
2

プラグマのdeviceptr句を使用する必要があることを除いて、タロンミーの投稿に同意します。dataこれdevice_residentは、OpenACC 実装にメモリの割り当てを要求するのに対し、device_ptr は要求しないためです。ユーザーによって既に割り当てられているため、メモリを割り当てる必要はありませんcudaMalloc()

于 2013-05-03T09:02:21.133 に答える