77
88#include < ceed/ceed.h>
99#include < ceed/backend.h>
10+ #include < ceed/jit-tools.h>
1011#include < cuda.h>
1112#include < cuda_runtime.h>
1213#include < nvrtc.h>
14+ #include < sstream>
15+ #include < stdarg.h>
1316#include < string.h>
1417#include " ceed-cuda-common.h"
1518#include " ceed-cuda-compile.h"
1619
1720#define CeedChk_Nvrtc (ceed, x ) \
1821do { \
19- nvrtcResult result = x ; \
22+ nvrtcResult result = static_cast <nvrtcResult>(x) ; \
2023 if (result != NVRTC_SUCCESS) \
2124 return CeedError ((ceed), CEED_ERROR_BACKEND, nvrtcGetErrorString (result)); \
2225} while (0 )
@@ -25,50 +28,60 @@ do { \
2528// Compile CUDA kernel
2629// ------------------------------------------------------------------------------
2730int CeedCompileCuda (Ceed ceed, const char *source, CUmodule *module ,
28- const CeedInt num_opts , ...) {
31+ const CeedInt num_defines , ...) {
2932 int ierr;
3033 cudaFree (0 ); // Make sure a Context exists for nvrtc
3134 nvrtcProgram prog;
32- CeedChk_Nvrtc (ceed , nvrtcCreateProgram (& prog , source , NULL , 0 , NULL , NULL ));
35+
36+ std::ostringstream code;
3337
3438 // Get kernel specific options, such as kernel constants
35- const int opts_len = 32 ;
36- const int opts_extra = 4 ;
37- const char * opts [num_opts + opts_extra ];
38- char buf [num_opts ][opts_len ];
39- if (num_opts > 0 ) {
39+ if (num_defines > 0 ) {
4040 va_list args;
41- va_start (args , num_opts );
41+ va_start (args, num_defines );
4242 char *name;
4343 int val;
44- for (int i = 0 ; i < num_opts ; i ++ ) {
44+ for (int i = 0 ; i < num_defines ; i++) {
4545 name = va_arg (args, char *);
4646 val = va_arg (args, int );
47- snprintf (& buf [i ][0 ], opts_len ,"-D%s=%d" , name , val );
48- opts [i ] = & buf [i ][0 ];
47+ code << " #define " << name << " " << val << " \n " ;
4948 }
5049 va_end (args);
5150 }
5251
53- // Standard backend options
54- if (CEED_SCALAR_TYPE == CEED_SCALAR_FP32 ) {
55- opts [num_opts ] = "-DCeedScalar=float" ;
56- } else {
57- opts [num_opts ] = "-DCeedScalar=double" ;
58- }
59- opts [num_opts + 1 ] = "-DCeedInt=int" ;
60- opts [num_opts + 2 ] = "-default-device" ;
52+ // Standard libCEED definitions for CUDA backends
53+ char *jit_defs_path, *jit_defs_source;
54+ ierr = CeedGetJitAbsolutePath (ceed,
55+ " ceed/jit-source/cuda/cuda-jit.h" ,
56+ &jit_defs_path); CeedChkBackend (ierr);
57+ ierr = CeedLoadSourceToBuffer (ceed, jit_defs_path, &jit_defs_source);
58+ CeedChkBackend (ierr);
59+ code << jit_defs_source;
60+ code << " \n\n " ;
61+ ierr = CeedFree (&jit_defs_path); CeedChkBackend (ierr);
62+ ierr = CeedFree (&jit_defs_source); CeedChkBackend (ierr);
63+
64+ // Non-macro options
65+ const int num_opts = 3 ;
66+ const char *opts[num_opts];
67+ opts[0 ] = " -default-device" ;
6168 struct cudaDeviceProp prop;
6269 Ceed_Cuda *ceed_data;
6370 ierr = CeedGetData (ceed, &ceed_data); CeedChkBackend (ierr);
6471 ierr = cudaGetDeviceProperties (&prop, ceed_data->device_id );
6572 CeedChk_Cu (ceed, ierr);
66- char buff [opts_len ];
67- snprintf (buff , opts_len ,"-arch=compute_%d%d" , prop .major , prop .minor );
68- opts [num_opts + 3 ] = buff ;
73+ std::string arch_arg = " -arch=compute_" + std::to_string (prop.major ) + std::to_string (prop.minor );
74+ opts[1 ] = arch_arg.c_str ();
75+ opts[2 ] = " -Dint32_t=int" ;
76+
77+ // Add string source argument provided in call
78+ code << source;
79+
80+ // Create Program
81+ CeedChk_Nvrtc (ceed, nvrtcCreateProgram (&prog, code.str ().c_str (), NULL , 0 , NULL , NULL ));
6982
7083 // Compile kernel
71- nvrtcResult result = nvrtcCompileProgram (prog , num_opts + opts_extra , opts );
84+ nvrtcResult result = nvrtcCompileProgram (prog, num_opts, opts);
7285 if (result != NVRTC_SUCCESS) {
7386 size_t log_size;
7487 CeedChk_Nvrtc (ceed, nvrtcGetProgramLogSize (prog, &log_size));
0 commit comments