CUDA ランタイム API を使用してエラーをチェックする標準的な方法は何ですか? 質問する

CUDA ランタイム API を使用してエラーをチェックする標準的な方法は何ですか? 質問する

CUDAの質問に対する回答やコメント、そしてCUDA タグ ウィキ、すべての API 呼び出しの戻りステータスでエラーをチェックすることがよく提案されています。API ドキュメントには、、、などの関数が含まれていますcudaGetLastErrorcudaPeekAtLastErrorcudaGetErrorString余分なコードを必要とせずにエラーを確実にキャッチして報告するには、これらを組み合わせる最適な方法は何でしょうか。

ベストアンサー1

おそらく、ランタイム API コードのエラーをチェックする最良の方法は、次のようにアサート スタイルのハンドラー関数とラッパー マクロを定義することです。

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess) 
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

次に、各 API 呼び出しをマクロでラップしますgpuErrchk。このマクロは、ラップした API 呼び出しの戻りステータスを処理します。次に例を示します。

gpuErrchk( cudaMalloc(&a_d, size*sizeof(int)) );

呼び出しでエラーが発生した場合、エラーの内容と、エラーが発生したコード内のファイルと行を示すテキスト メッセージが出力されstderr、アプリケーションが終了します。必要に応じて、より高度なアプリケーションでgpuAssert呼び出しを行うのではなく、例外を発生させるように変更することも可能です。exit()

2 つ目の関連する質問は、標準のランタイム API 呼び出しのようにマクロ呼び出しで直接ラップできないカーネル起動時のエラーをどのようにチェックするかです。カーネルの場合は次のようになります。

kernel<<<1,1>>>(a);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaDeviceSynchronize() );

まず無効な起動引数をチェックし、次にカーネルが停止して実行エラーをチェックするまでホストを待機させます。次のような後続のブロッキング API 呼び出しがあれば、同期を省略できます。

kernel<<<1,1>>>(a_d);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaMemcpy(a_h, a_d, size * sizeof(int), cudaMemcpyDeviceToHost) );

この場合、cudaMemcpy呼び出しはカーネル実行中に発生したエラーか、メモリコピー自体からのエラーのいずれかを返すことができます。これは初心者にとっては混乱を招く可能性があるため、問題が発生している場所を理解しやすくするために、デバッグ中にカーネルを起動した後、明示的な同期を使用することをお勧めします。

使用する際は注意してくださいCUDA 動的並列処理非常によく似た方法論は、デバイス カーネル内の CUDA ランタイム API の使用や、デバイス カーネルの起動後にも適用できます。また、適用する必要があります。

#include <assert.h>
#define cdpErrchk(ans) { cdpAssert((ans), __FILE__, __LINE__); }
__device__ void cdpAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess)
   {
      printf("GPU kernel assert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) assert(0);
   }
}

CUDA Fortranのエラーチェックも同様です。ここそしてここ一般的な関数エラー戻り構文。CUDA C++ に似た方法を使用して、カーネルの起動に関連するエラーを収集します。

おすすめ記事