90 likes | 212 Views
Error Handling. ITCS 6/8010 CUDA Programming, UNC-Charlotte, B. Wilkinson, March 3, 2011. Run-Time Errors. Every CUDA call (except kernel launches) return an error code of type cudaError_t No error = “ cudaSuccess ” otherwise an error code. Example cudaError_t cudaMalloc(…);
E N D
Error Handling ITCS 6/8010 CUDA Programming, UNC-Charlotte, B. Wilkinson, March 3, 2011
Run-Time Errors Every CUDA call (except kernel launches) return an error code of type cudaError_t No error = “cudaSuccess” otherwise an error code. Example cudaError_t cudaMalloc(…); returns cudaSuccess or cudaErrorMemoryAllocation
Getting Error Message Human-readable error obtained from: char* cudaGetErrorString(cudaError_t error); returns an error message string that can then be printed out. Note: Regular C programming uses similar approach of returning an error code errno that can be converted to a message with strerror.
Getting the last error Errors are reported to the corresponding thread cudaError_t cudaGetLastError(void); returns last error produced by any runtime call in same host thread and resets it to cudaSuccess.
Multiple Errors Only the last error reported by cudaGetLastError
Getting error after kernel launch Because kernel calls return before completing, cannot immediately use cudaGetLastError to get errors First use cudaThreadSynchonize() as a synchronization point Then call cudaGetLastError: myKernel<<<…>>>(); cudaThreadSynchonize(); cudaError_t code = cudaGetLastError(); if (code != cudaSuccess) printf ("Cuda error -- %s\n", cudaGetErrorString(code)); cudaThreadSynchonize() also returns an error code “if preceding task failed” so could read that?
For clarity could have a separate routine: myKernel<<<…>>>(); cudaThreadSynchonize(); checkCUDAError("kernel invocation"); void checkCUDAError(const char *msg) { cudaError_t code = cudaGetLastError(); if ( code != cudaSuccess) { fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) ); exit(EXIT_FAILURE); } } Source: CUDA, Supercomputing for the Masses: Part 3 by Rob Farber http://www.drdobbs.com/high-performance-computing/207603131;jsessionid=ZZAVB4EQTNT4VQE1GHPCKH4ATMY32JVN
Textbook Approach Uses macro substitution: #define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ )) static void HandleError( cudaError_t err, const char *file, int line ) { if (err != cudaSuccess) { printf( "%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); exit( EXIT_FAILURE ); } } which works with any CUDA call that returns an error code: HANDLE_ERROR( cudaMalloc( … ) ); HANDLE_ERROR( cudaMemcpy( … ) );