From cd9ee070e2fcaa49fe35944ea0fd60ed5d197ba2 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Mon, 19 Feb 2024 20:39:39 -0500 Subject: Split SAFE() macro into API-specific typed variants Avoids incorrectly interpreting CUDA Driver Library error codes as though they were CUDA Runtime Library error codes (the numbering is similar, but not identical). Also cleans up how we initialize and terminate a context for capability checking in `mon_cross_ctx_copies`. --- testbench.h | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'testbench.h') diff --git a/testbench.h b/testbench.h index 5b47bd4..5e77410 100644 --- a/testbench.h +++ b/testbench.h @@ -2,10 +2,34 @@ * Header for miscellaneous experimental helper functions. */ +// cudaError_t and CUResult can both safely be cast to an unsigned int +static __thread unsigned int __SAFE_err; + +// The very strange cast in these macros is to satisfy two goals at tension: +// 1. This file should be able to be included in non-CUDA-using files, and thus +// should use no CUDA types outside of this macro. +// 2. We want to typecheck uses of these macros. The driver and runtime APIs +// do not have identical error numbers and/or meanings, so runtime library +// calls should use SAFE, and driver library calls should use SAFE_D. +// Our design allows typechecking while keeping a non-CUDA per-thread error var. + +// For CUDA Runtime Library functions; typically those prefixed with `cuda` #define SAFE(x) \ - if ((err = (cudaError_t)(x)) != 0) { \ - printf("CUDA error %d! %s\n", err, cudaGetErrorString(err)); \ - printf("Suspect line: %s\n", #x); \ + if ((*(cudaError_t*)(&__SAFE_err) = (x)) != 0) { \ + printf("(%s:%d) CUDA error %d: %s i.e. \"%s\" returned by %s. Aborting...\n", \ + __FILE__, __LINE__, __SAFE_err, cudaGetErrorName((cudaError_t)__SAFE_err), cudaGetErrorString((cudaError_t)__SAFE_err), #x); \ + exit(1); \ + } + +// For CUDA Driver Library functions; typically those prefixed with just `cu` +#define SAFE_D(x) \ + if ((*(CUresult*)&(__SAFE_err) = (x)) != 0) { \ + const char* name; \ + const char* desc; \ + cuGetErrorName((CUresult)__SAFE_err, &name); \ + cuGetErrorString((CUresult)__SAFE_err, &desc); \ + printf("(%s:%d) CUDA error %d: %s i.e. \"%s\" returned by %s. Aborting...\n", \ + __FILE__, __LINE__, __SAFE_err, name, desc, #x); \ exit(1); \ } -- cgit v1.2.2