@@ -55,7 +55,8 @@ cdef class DeviceProperties:
5555 cdef inline _get_attribute(self , cydriver.CUdevice_attribute attr):
5656 """ Retrieve the attribute value directly from the driver."""
5757 cdef int val
58- HANDLE_RETURN(cydriver.cuDeviceGetAttribute(& val, attr, self ._handle))
58+ with nogil:
59+ HANDLE_RETURN(cydriver.cuDeviceGetAttribute(& val, attr, self ._handle))
5960 return val
6061
6162 cdef _get_cached_attribute(self , attr):
@@ -949,7 +950,8 @@ cdef cydriver.CUcontext _get_primary_context(int dev_id) except?NULL:
949950 primary_ctxs = _tls.primary_ctxs = [0 ] * total
950951 cdef cydriver.CUcontext ctx = < cydriver.CUcontext>< uintptr_t> (primary_ctxs[dev_id])
951952 if ctx == NULL:
952- HANDLE_RETURN(cydriver.cuDevicePrimaryCtxRetain(&ctx , dev_id ))
953+ with nogil:
954+ HANDLE_RETURN(cydriver.cuDevicePrimaryCtxRetain(&ctx , dev_id ))
953955 primary_ctxs[dev_id] = <uintptr_t>(ctx )
954956 return ctx
955957
@@ -985,19 +987,21 @@ class Device:
985987 def __new__(cls , device_id: Optional[int] = None ):
986988 global _is_cuInit
987989 if _is_cuInit is False :
988- with _lock:
990+ with _lock, nogil :
989991 HANDLE_RETURN(cydriver.cuInit(0 ))
990992 _is_cuInit = True
991993
992994 # important: creating a Device instance does not initialize the GPU!
993995 cdef cydriver.CUdevice dev
994996 cdef cydriver.CUcontext ctx
995997 if device_id is None :
996- err = cydriver.cuCtxGetDevice(& dev)
998+ with nogil:
999+ err = cydriver.cuCtxGetDevice(& dev)
9971000 if err == cydriver.CUresult.CUDA_SUCCESS:
9981001 device_id = int (dev)
9991002 elif err == cydriver.CUresult.CUDA_ERROR_INVALID_CONTEXT:
1000- HANDLE_RETURN(cydriver.cuCtxGetCurrent(& ctx))
1003+ with nogil:
1004+ HANDLE_RETURN(cydriver.cuCtxGetCurrent(& ctx))
10011005 assert < void * > (ctx) == NULL
10021006 device_id = 0 # cudart behavior
10031007 else :
@@ -1010,18 +1014,20 @@ class Device:
10101014 try :
10111015 devices = _tls.devices
10121016 except AttributeError :
1013- HANDLE_RETURN(cydriver.cuDeviceGetCount(& total))
1017+ with nogil:
1018+ HANDLE_RETURN(cydriver.cuDeviceGetCount(& total))
10141019 devices = _tls.devices = []
10151020 for dev_id in range (total):
10161021 device = super ().__new__(cls )
10171022 device._id = dev_id
10181023 # If the device is in TCC mode, or does not support memory pools for some other reason,
10191024 # use the SynchronousMemoryResource which does not use memory pools.
1020- HANDLE_RETURN(
1021- cydriver.cuDeviceGetAttribute(
1022- & attr, cydriver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEMORY_POOLS_SUPPORTED, dev_id
1025+ with nogil:
1026+ HANDLE_RETURN(
1027+ cydriver.cuDeviceGetAttribute(
1028+ & attr, cydriver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEMORY_POOLS_SUPPORTED, dev_id
1029+ )
10231030 )
1024- )
10251031 if attr == 1 :
10261032 device._mr = DeviceMemoryResource(dev_id)
10271033 else :
@@ -1042,16 +1048,18 @@ class Device:
10421048 f" Device {self._id} is not yet initialized, perhaps you forgot to call .set_current() first?"
10431049 )
10441050
1045- def _get_current_context (self , check_consistency = False ) -> driver.CUcontext:
1051+ def _get_current_context (self , bint check_consistency = False ) -> driver.CUcontext:
10461052 cdef cydriver.CUcontext ctx
1047- HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx ))
1048- if ctx == NULL:
1049- raise CUDAError("No context is bound to the calling CPU thread.")
10501053 cdef cydriver.CUdevice dev
1051- if check_consistency:
1052- HANDLE_RETURN(cydriver.cuCtxGetDevice(&dev ))
1053- if <int>(dev ) != self._id:
1054- raise CUDAError("Internal error (current device is not equal to Device.device_id )")
1054+ cdef cydriver.CUdevice this_dev = self ._id
1055+ with nogil:
1056+ HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx ))
1057+ if ctx == NULL:
1058+ raise CUDAError("No context is bound to the calling CPU thread.")
1059+ if check_consistency:
1060+ HANDLE_RETURN(cydriver.cuCtxGetDevice(&dev ))
1061+ if dev != this_dev:
1062+ raise CUDAError("Internal error (current device is not equal to Device.device_id )")
10551063 return driver.CUcontext(<uintptr_t>ctx )
10561064
10571065 @property
@@ -1080,10 +1088,12 @@ class Device:
10801088
10811089 """
10821090 cdef cydriver.CUuuid uuid
1083- IF CUDA_CORE_BUILD_MAJOR == "12":
1084- HANDLE_RETURN(cydriver.cuDeviceGetUuid_v2(&uuid , self._id ))
1085- ELSE: # 13.0+
1086- HANDLE_RETURN(cydriver.cuDeviceGetUuid(&uuid , self._id ))
1091+ cdef cydriver.CUdevice this_dev = self ._id
1092+ with nogil:
1093+ IF CUDA_CORE_BUILD_MAJOR == "12":
1094+ HANDLE_RETURN(cydriver.cuDeviceGetUuid_v2(&uuid , this_dev ))
1095+ ELSE: # 13.0+
1096+ HANDLE_RETURN(cydriver.cuDeviceGetUuid(&uuid , this_dev ))
10871097 cdef bytes uuid_b = cpython.PyBytes_FromStringAndSize(uuid.bytes, sizeof(uuid.bytes))
10881098 cdef str uuid_hex = uuid_b.hex()
10891099 # 8-4-4-4-12
@@ -1095,7 +1105,10 @@ class Device:
10951105 # Use 256 characters to be consistent with CUDA Runtime
10961106 cdef int LENGTH = 256
10971107 cdef bytes name = bytes(LENGTH)
1098- HANDLE_RETURN(cydriver.cuDeviceGetName(<char*>name , LENGTH , self._id ))
1108+ cdef char* name_ptr = name
1109+ cdef cydriver.CUdevice this_dev = self ._id
1110+ with nogil:
1111+ HANDLE_RETURN(cydriver.cuDeviceGetName(name_ptr , LENGTH , this_dev ))
10991112 name = name.split(b" \0" )[0 ]
11001113 return name.decode()
11011114
@@ -1198,7 +1211,8 @@ class Device:
11981211 >>> # ... do work on device 0 ...
11991212
12001213 """
1201- cdef cydriver.CUcontext _ctx
1214+ cdef cydriver.CUcontext prev_ctx
1215+ cdef cydriver.CUcontext curr_ctx
12021216 if ctx is not None:
12031217 # TODO: revisit once Context is cythonized
12041218 assert_type(ctx , Context )
@@ -1207,16 +1221,19 @@ class Device:
12071221 "the provided context was created on the device with"
12081222 f" id = {ctx._id}, which is different from the target id = {self ._id}"
12091223 )
1210- # _ctx is the previous context
1211- HANDLE_RETURN(cydriver.cuCtxPopCurrent(&_ctx ))
1212- HANDLE_RETURN(cydriver.cuCtxPushCurrent(<cydriver.CUcontext>(ctx._handle )))
1224+ # prev_ctx is the previous context
1225+ curr_ctx = < cydriver.CUcontext> (ctx._handle)
1226+ with nogil:
1227+ HANDLE_RETURN(cydriver.cuCtxPopCurrent(&prev_ctx ))
1228+ HANDLE_RETURN(cydriver.cuCtxPushCurrent(curr_ctx ))
12131229 self._has_inited = True
1214- if _ctx != NULL:
1215- return Context._from_ctx(<uintptr_t>(_ctx ), self._id )
1230+ if prev_ctx != NULL:
1231+ return Context._from_ctx(<uintptr_t>(prev_ctx ), self._id )
12161232 else:
12171233 # use primary ctx
1218- _ctx = _get_primary_context(self ._id)
1219- HANDLE_RETURN(cydriver.cuCtxSetCurrent(_ctx ))
1234+ curr_ctx = _get_primary_context(self ._id)
1235+ with nogil:
1236+ HANDLE_RETURN(cydriver.cuCtxSetCurrent(curr_ctx ))
12201237 self._has_inited = True
12211238
12221239 def create_context(self , options: ContextOptions = None ) -> Context:
0 commit comments