연구개발/C, C++, CUDA

[CUDA] Error Handling (오류 처리)

대로아빠 2020. 10. 6. 16:43
cudaError_t err;
err = cudaMallocManaged(&a, N)                    // Assume the existence of `a` and `N`.

if (err != cudaSuccess)                           // `cudaSuccess` is provided by CUDA.
{
  printf("Error: %s\n", cudaGetErrorString(err)); // `cudaGetErrorString` is provided by CUDA.
}

위 코드처럼 cudaError_t type을 통해 오류를 확인하는 것이 가능한데, 우리가 종종 만들게될 kernel의 경우 return type이 void 이므로 위와 같이 확인이 불가능하다. 그 때에는 아래 코드와 같이 오류를 확인한다.

someKernel<<<1, -1>>>();  // -1 is not a valid number of threads.

cudaError_t err;
err = cudaGetLastError(); // `cudaGetLastError` will return the error from above.
if (err != cudaSuccess)
{
  printf("Error: %s\n", cudaGetErrorString(err));
}

비동기적으로 발생하는 오류를 탐지하기 위해서는 (비동기 kernel을 실행하는 때 처럼), CUDA runtime API call을 필수적으로 체크해야 한다 (cudaDeviceSynchronize와 같은).


CUDA Error를 처리하기 위해 inline 함수를 아래와 같이 구성하면 보다 편한 오류 점검이 가능하다.

 

#include <stdio.h>
#include <assert.h>

inline cudaError_t checkCuda(cudaError_t result)
{
  if (result != cudaSuccess) {
    fprintf(stderr, "CUDA Runtime Error: %s\n", cudaGetErrorString(result));
    assert(result == cudaSuccess);
  }
  return result;
}

int main()
{

/*
 * The macro can be wrapped around any function returning
 * a value of type `cudaError_t`.
 */

  checkCuda( cudaDeviceSynchronize() )
}