1 /*------------------------------------------------------------------------------------------------*
2  * Copyright (C) by the DBCSR developers group - All rights reserved                              *
3  * This file is part of the DBCSR library.                                                        *
4  *                                                                                                *
5  * For information on the license, see the LICENSE file.                                          *
6  * For further information please visit https://dbcsr.cp2k.org                                    *
7  * SPDX-License-Identifier: GPL-2.0+                                                              *
8  *------------------------------------------------------------------------------------------------*/
9 
10 #ifndef ACC_CUDA_H
11 #define ACC_CUDA_H
12 
13 #include <cuda.h>
14 #include <cuda_runtime.h>
15 #include <nvrtc.h>
16 #include "cublas_v2.h"
17 
18 #define ACC(x) cuda##x
19 #define ACC_DRV(x) CU##x
20 #define ACC_DRV_FUNC_PREFIX(x) cu##x
21 #define ACC_RTC(x) nvrtc##x
22 #define ACC_BLAS(x) cublas##x
23 #define BACKEND "CUDA"
24 
25 /* Macros for CUDA error handling
26  * Wrap calls to CUDA runtime API (CUDART)
27  */
28 #define ACC_API_CALL(func, args)                                  \
29   do {                                                            \
30     cudaError_t result = ACC(func) args;                          \
31     if (result != cudaSuccess) {                                  \
32       printf("\nCUDA RUNTIME API error: %s failed with error %s\n",\
33              #func, cudaGetErrorName(result));                    \
34       exit(1);                                                    \
35     }                                                             \
36   } while(0)
37 
38 /* Wrap calls to CUDA driver API */
39 #define ACC_DRV_CALL(func, args)                                  \
40   do {                                                            \
41     CUresult result = ACC_DRV_FUNC_PREFIX(func) args;             \
42     if (result != CUDA_SUCCESS) {                                 \
43       const char *msg;                                            \
44       cuGetErrorName(result, &msg);                               \
45       printf("\nCUDA DRIVER API ERROR: %s failed with error %s\n",\
46              #func, msg);                                         \
47       exit(1);                                                    \
48     }                                                             \
49   } while(0)
50 
51 /* Wrap calls to CUDA NVRTC API */
52 #define ACC_RTC_CALL(func, args)                                  \
53   do {                                                            \
54     nvrtcResult result = ACC_RTC(func) args;                      \
55     if (result != NVRTC_SUCCESS) {                                \
56       printf("\nNVRTC ERROR: %s failed with error %s\n",          \
57              #func, nvrtcGetErrorString(result));                 \
58       exit(1);                                                    \
59     }                                                             \
60   } while(0)
61 
62 
63 /* Wrap calls to CUDA CUBLAS API */
64 #define ACC_BLAS_CALL(func, args)                                 \
65   do {                                                            \
66     cublasStatus_t result = ACC_BLAS(func) args;                  \
67     if (result != CUBLAS_STATUS_SUCCESS) {                        \
68       const char* error_name = "CUBLAS_ERRROR";                   \
69       if (result == CUBLAS_STATUS_NOT_INITIALIZED){               \
70         error_name = "CUBLAS_STATUS_NOT_INITIALIZED";             \
71       } else if (result == CUBLAS_STATUS_ALLOC_FAILED){           \
72         error_name = "CUBLAS_STATUS_ALLOC_FAILED";                \
73       } else if (result == CUBLAS_STATUS_INVALID_VALUE){          \
74         error_name = "CUBLAS_STATUS_INVALID_VALUE";               \
75       } else if (result == CUBLAS_STATUS_ARCH_MISMATCH){          \
76         error_name = "CUBLAS_STATUS_ARCH_MISMATCH";               \
77       } else if (result == CUBLAS_STATUS_MAPPING_ERROR){          \
78         error_name = "CUBLAS_STATUS_MAPPING_ERROR";               \
79       } else if (result == CUBLAS_STATUS_EXECUTION_FAILED){       \
80         error_name = "CUBLAS_STATUS_EXECUTION_FAILED";            \
81       } else if (result == CUBLAS_STATUS_INTERNAL_ERROR){         \
82         error_name = "CUBLAS_STATUS_INTERNAL_ERROR";              \
83       }                                                           \
84       printf("\nCUBLAS ERROR: %s failed with error %s\n",         \
85              #func, error_name);                                  \
86       exit(1);                                                    \
87     }                                                             \
88   } while(0)
89 
90 
91 extern nvrtcResult nvrtcGetLowLevelCode(nvrtcProgram prog, char* code);
92 extern nvrtcResult nvrtcGetLowLevelCodeSize(nvrtcProgram prog, size_t* codeSizeRet);
93 extern CUresult cuLaunchJITKernel(CUfunction f, unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ,
94                                   unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ,
95                                   unsigned int sharedMemBytes, CUstream stream, void **kernelParams, void **extra);
96 
97 /* CUDA Runtime API: flag values */
98 extern CUevent_flags CUEventDefault;
99 extern CUstream_flags CUStreamDefault;
100 extern CUsharedconfig CUSharedMemBankSizeEightByte;
101 
102 /* CUBLAS status and operations */
103 extern cublasStatus_t ACC_BLAS_STATUS_SUCCESS;
104 extern cublasOperation_t ACC_BLAS_OP_N;
105 extern cublasOperation_t ACC_BLAS_OP_T;
106 
107 #endif /*ACC_CUDA_H*/
108