66#include " cuda_loader.h"
77
88
9- const char * get_cuda_error (CUresult res) {
9+ const char * get_cuda_error (const DriverApi* driver, CUresult res) {
1010 const char * str = nullptr ;
11- g_cuGetErrorString (res, &str);
11+ driver-> cuGetErrorString (res, &str);
1212 return str ? str : " Unknown error" ;
1313}
1414
15- void try_init_cuda ( ) {
16- ErrorGuard guard ;
17- CUresult res = g_cuInit ( 0 );
15+ Status check_driver_version ( const DriverApi* driver, int minimum_version ) {
16+ int version ;
17+ CUresult res = driver-> cuDriverGetVersion (&version );
1818 if (res != CUDA_SUCCESS) {
19- raise (PyExc_RuntimeError, " cuInit: %s" , get_cuda_error (res));
20- SavedException exc = save_raised_exception ();
21- LOG_PYTHON_ERROR (" warning" , exc, " Failed to initialized CUDA" );
19+ PyErr_Format (PyExc_RuntimeError, " cuDriverGetVersion: %s" , get_cuda_error (driver, res));
20+ return ErrorRaised;
21+ }
22+ if (version < minimum_version) {
23+ int major = version / 1000 ;
24+ int minor = (version % 1000 ) / 10 ;
25+ int required_major = minimum_version / 1000 ;
26+ PyErr_Format (PyExc_RuntimeError,
27+ " Minimum driver version required is %d.0, got %d.%d" ,
28+ required_major, major, minor);
29+ return ErrorRaised;
2230 }
31+ return OK;
2332}
2433
2534PyObject* get_max_grid_size (PyObject *self, PyObject *args) {
2635 int device_id;
2736 if (!PyArg_ParseTuple (args, " i" , &device_id))
2837 return NULL ;
2938
39+ Result<const DriverApi*> driver = get_driver_api ();
40+ if (!driver.is_ok ()) return NULL ;
41+
3042 CUdevice dev;
31- CUresult res = g_cuDeviceGet (&dev, device_id);
43+ CUresult res = (*driver)-> cuDeviceGet (&dev, device_id);
3244 if (res != CUDA_SUCCESS)
33- return PyErr_Format (PyExc_RuntimeError, " cuDeviceGet: %s" , get_cuda_error (res));
45+ return PyErr_Format (PyExc_RuntimeError, " cuDeviceGet: %s" , get_cuda_error (*driver, res));
3446
3547 int max_grid_size[3 ];
3648 for (int i = 0 ; i < 3 ; ++i) {
37- res = g_cuDeviceGetAttribute (&max_grid_size[i],
49+ res = (*driver)-> cuDeviceGetAttribute (&max_grid_size[i],
3850 static_cast <CUdevice_attribute>(CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X + i),
3951 dev);
4052 if (res != CUDA_SUCCESS) {
4153 return PyErr_Format (PyExc_RuntimeError,
42- " cuDeviceGetAttribute: %s" , get_cuda_error (res));
54+ " cuDeviceGetAttribute: %s" , get_cuda_error (*driver, res));
4355 }
4456 }
4557 return Py_BuildValue (" (iii)" , max_grid_size[0 ], max_grid_size[1 ], max_grid_size[2 ]);
@@ -48,26 +60,36 @@ PyObject* get_max_grid_size(PyObject *self, PyObject *args) {
4860PyObject* get_compute_capability (PyObject *self, PyObject *Py_UNUSED (ignored)) {
4961 int major, minor;
5062 CUdevice dev;
51- CUresult res = g_cuDeviceGet (&dev, 0 );
63+
64+ Result<const DriverApi*> driver_result = get_driver_api ();
65+ if (!driver_result.is_ok ()) return NULL ;
66+ const DriverApi* d = *driver_result;
67+
68+ CUresult res = d->cuDeviceGet (&dev, 0 );
5269 if (res != CUDA_SUCCESS) {
53- return PyErr_Format (PyExc_RuntimeError, " cuDeviceGet: %s" , get_cuda_error (res));
70+ return PyErr_Format (PyExc_RuntimeError, " cuDeviceGet: %s" , get_cuda_error (d, res));
5471 }
55- res = g_cuDeviceGetAttribute (&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, dev);
72+ res = d-> cuDeviceGetAttribute (&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, dev);
5673 if (res != CUDA_SUCCESS) {
57- return PyErr_Format (PyExc_RuntimeError, " cuDeviceGetAttribute: %s" , get_cuda_error (res));
74+ return PyErr_Format (PyExc_RuntimeError, " cuDeviceGetAttribute: %s" , get_cuda_error (d, res));
5875 }
59- res = g_cuDeviceGetAttribute (&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, dev);
76+ res = d-> cuDeviceGetAttribute (&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, dev);
6077 if (res != CUDA_SUCCESS) {
61- return PyErr_Format (PyExc_RuntimeError, " cuDeviceGetAttribute: %s" , get_cuda_error (res));
78+ return PyErr_Format (PyExc_RuntimeError, " cuDeviceGetAttribute: %s" , get_cuda_error (d, res));
6279 }
6380 return Py_BuildValue (" (ii)" , major, minor);
6481}
6582
6683PyObject* get_driver_version (PyObject *self, PyObject *Py_UNUSED (ignored)) {
6784 int major, minor;
68- CUresult res = g_cuDriverGetVersion (&major);
85+
86+ Result<const DriverApi*> driver_result = get_driver_api ();
87+ if (!driver_result.is_ok ()) return NULL ;
88+ const DriverApi* d = *driver_result;
89+
90+ CUresult res = d->cuDriverGetVersion (&major);
6991 if (res != CUDA_SUCCESS) {
70- return PyErr_Format (PyExc_RuntimeError, " cuDriverGetVersion: %s" , get_cuda_error (res));
92+ return PyErr_Format (PyExc_RuntimeError, " cuDriverGetVersion: %s" , get_cuda_error (d, res));
7193 }
7294 minor = (major % 1000 ) / 10 ;
7395 major = major / 1000 ;
0 commit comments