@@ -280,6 +280,66 @@ struct CudaKernel {
280280 CUkernel kernel;
281281};
282282
283+ static Status enable_maximum_dynamic_shared_memory (const DriverApi *driver,
284+ const CUkernel kernel,
285+ const char *func_name) {
286+ int device_count;
287+ CUresult res = driver->cuDeviceGetCount (&device_count);
288+ if (res != CUDA_SUCCESS ) {
289+ return raise (PyExc_RuntimeError, " Failed to get device count: %s" ,
290+ get_cuda_error (driver, res));
291+ }
292+
293+ for (int device_ordinal = 0 ; device_ordinal < device_count;
294+ device_ordinal++) {
295+ CUdevice device;
296+ res = driver->cuDeviceGet (&device, device_ordinal);
297+ if (res != CUDA_SUCCESS ) {
298+ return raise (PyExc_RuntimeError, " Failed to get device %d: %s" ,
299+ device_ordinal, get_cuda_error (driver, res));
300+ }
301+
302+ int max_smem;
303+ res = driver->cuDeviceGetAttribute (
304+ &max_smem, CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK_OPTIN ,
305+ device);
306+ if (res != CUDA_SUCCESS ) {
307+ return raise (PyExc_RuntimeError,
308+ " Failed to get maximum shared memory for device %d: %s" ,
309+ device_ordinal, get_cuda_error (driver, res));
310+ }
311+
312+ int static_smem;
313+ res = driver->cuKernelGetAttribute (
314+ &static_smem, CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES , kernel, device);
315+ if (res != CUDA_SUCCESS ) {
316+ return raise (PyExc_RuntimeError,
317+ " Failed to get static shared memory for kernel %s: %s" ,
318+ func_name, get_cuda_error (driver, res));
319+ }
320+
321+ if (max_smem < static_smem) {
322+ // If the user's program uses more static shared memory than the
323+ // current device has available, then we cannot request enough
324+ // shared memory. If the user has another device capable of running
325+ // their program, they must run on that device and errors will be
326+ // reported at launch time.
327+ continue ;
328+ }
329+ int largest_possible_dynamic_smem = max_smem - static_smem;
330+ res = driver->cuKernelSetAttribute (
331+ CU_FUNC_ATTRIBUTE_MAX_DYNAMIC_SHARED_SIZE_BYTES ,
332+ largest_possible_dynamic_smem, kernel, device);
333+ if (res != CUDA_SUCCESS ) {
334+ return raise (PyExc_RuntimeError,
335+ " Failed to set dynamic shared memory for kernel %s: %s" ,
336+ func_name, get_cuda_error (driver, res));
337+ }
338+ }
339+
340+ return OK ;
341+ }
342+
283343static Result<CudaKernel> load_cuda_kernel (const DriverApi* driver,
284344 const char * cubin_data,
285345 size_t cubin_size,
@@ -291,11 +351,12 @@ static Result<CudaKernel> load_cuda_kernel(const DriverApi* driver,
291351
292352 CUkernel kernel;
293353 CUresult res = driver->cuLibraryGetKernel (&kernel, lib->get (), func_name);
294- if (res == CUDA_SUCCESS )
295- return CudaKernel{std::move (*lib), kernel};
354+ if (res != CUDA_SUCCESS ) {
355+ return raise (PyExc_RuntimeError, " Failed to get kernel %s from library: %s" ,
356+ func_name, get_cuda_error (driver, res));
357+ }
296358
297- return raise (PyExc_RuntimeError, " Failed to get kernel %s from library: %s" ,
298- func_name, get_cuda_error (driver, res));
359+ return CudaKernel{std::move (*lib), kernel};
299360}
300361
301362
@@ -2156,6 +2217,12 @@ static Result<TileKernel> compile(const DriverApi* driver,
21562217 Result<CudaKernel> cukernel = load_cuda_kernel (driver, cubin_data, cubin_size, cufunc_name);
21572218 if (!cukernel.is_ok ()) return ErrorRaised;
21582219
2220+ if (py_dyn_smem_size_prog != Py_None) {
2221+ Status status = enable_maximum_dynamic_shared_memory (
2222+ driver, cukernel->kernel , cufunc_name);
2223+ if (!status) return ErrorRaised;
2224+ }
2225+
21592226 Result<HostProgram> dyn_smem_size_prog = host_program_parse (py_dyn_smem_size_prog, 1 );
21602227 if (!dyn_smem_size_prog.is_ok ()) return ErrorRaised;
21612228
0 commit comments