Skip to content

Commit fab1c99

Browse files
Synchronization functions and USM allocations functions release GIL (#736)
* Synchronization function release GIL DPCTLQueue_Wait and friends are declared nogil, and their use is moved into `with nogil` context. This allows us to use host_task to decrement reference count on a Python object without introducing a deadlock. * Used 1-line context manage syntax to avoid coverage drop * USM alloc. fns declared nogil, used inside `with nogil` context Large USM allocations can be constly, so releasing GIL while invoking them may be a good idea.
2 parents 6b81ed0 + 0ae7844 commit fab1c99

File tree

4 files changed

+34
-30
lines changed

4 files changed

+34
-30
lines changed

dpctl/_backend.pxd

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ cdef extern from "syclinterface/dpctl_sycl_device_selector_interface.h":
227227
cdef extern from "syclinterface/dpctl_sycl_event_interface.h":
228228
cdef DPCTLSyclEventRef DPCTLEvent_Create()
229229
cdef DPCTLSyclEventRef DPCTLEvent_Copy(const DPCTLSyclEventRef ERef)
230-
cdef void DPCTLEvent_Wait(DPCTLSyclEventRef ERef)
231-
cdef void DPCTLEvent_WaitAndThrow(DPCTLSyclEventRef ERef)
230+
cdef void DPCTLEvent_Wait(DPCTLSyclEventRef ERef) nogil
231+
cdef void DPCTLEvent_WaitAndThrow(DPCTLSyclEventRef ERef) nogil
232232
cdef void DPCTLEvent_Delete(DPCTLSyclEventRef ERef)
233233
cdef _event_status_type DPCTLEvent_GetCommandExecutionStatus(DPCTLSyclEventRef ERef)
234234
cdef _backend_type DPCTLEvent_GetBackend(DPCTLSyclEventRef ERef)
@@ -356,7 +356,7 @@ cdef extern from "syclinterface/dpctl_sycl_queue_interface.h":
356356
size_t NDims,
357357
const DPCTLSyclEventRef *DepEvents,
358358
size_t NDepEvents)
359-
cdef void DPCTLQueue_Wait(const DPCTLSyclQueueRef QRef)
359+
cdef void DPCTLQueue_Wait(const DPCTLSyclQueueRef QRef) nogil
360360
cdef DPCTLSyclEventRef DPCTLQueue_Memcpy(
361361
const DPCTLSyclQueueRef Q,
362362
void *Dest,
@@ -394,23 +394,25 @@ cdef extern from "syclinterface/dpctl_sycl_queue_manager.h":
394394
cdef extern from "syclinterface/dpctl_sycl_usm_interface.h":
395395
cdef DPCTLSyclUSMRef DPCTLmalloc_shared(
396396
size_t size,
397-
DPCTLSyclQueueRef QRef)
397+
DPCTLSyclQueueRef QRef) nogil
398398
cdef DPCTLSyclUSMRef DPCTLmalloc_host(
399399
size_t size,
400-
DPCTLSyclQueueRef QRef)
401-
cdef DPCTLSyclUSMRef DPCTLmalloc_device(size_t size, DPCTLSyclQueueRef QRef)
400+
DPCTLSyclQueueRef QRef) nogil
401+
cdef DPCTLSyclUSMRef DPCTLmalloc_device(
402+
size_t size,
403+
DPCTLSyclQueueRef QRef) nogil
402404
cdef DPCTLSyclUSMRef DPCTLaligned_alloc_shared(
403405
size_t alignment,
404406
size_t size,
405-
DPCTLSyclQueueRef QRef)
407+
DPCTLSyclQueueRef QRef) nogil
406408
cdef DPCTLSyclUSMRef DPCTLaligned_alloc_host(
407409
size_t alignment,
408410
size_t size,
409-
DPCTLSyclQueueRef QRef)
411+
DPCTLSyclQueueRef QRef) nogil
410412
cdef DPCTLSyclUSMRef DPCTLaligned_alloc_device(
411413
size_t alignment,
412414
size_t size,
413-
DPCTLSyclQueueRef QRef)
415+
DPCTLSyclQueueRef QRef) nogil
414416
cdef void DPCTLfree_with_queue(
415417
DPCTLSyclUSMRef MRef,
416418
DPCTLSyclQueueRef QRef)

dpctl/_sycl_event.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ cdef class _SyclEvent:
9898

9999
def __dealloc__(self):
100100
if (self._event_ref):
101-
DPCTLEvent_Wait(self._event_ref)
101+
with nogil: DPCTLEvent_Wait(self._event_ref)
102102
DPCTLEvent_Delete(self._event_ref)
103103
self._event_ref = NULL
104104
self.args = None
@@ -224,7 +224,7 @@ cdef class SyclEvent(_SyclEvent):
224224

225225
@staticmethod
226226
cdef void _wait(SyclEvent event):
227-
DPCTLEvent_WaitAndThrow(event._event_ref)
227+
with nogil: DPCTLEvent_WaitAndThrow(event._event_ref)
228228

229229
@staticmethod
230230
def wait_for(event):
@@ -370,4 +370,4 @@ cdef class SyclEvent(_SyclEvent):
370370

371371
cpdef void wait(self):
372372
"Synchronously wait for completion of this event."
373-
DPCTLEvent_Wait(self._event_ref)
373+
with nogil: DPCTLEvent_Wait(self._event_ref)

dpctl/_sycl_queue.pyx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ cdef class SyclQueue(_SyclQueue):
824824
return SyclEvent._create(Eref, args)
825825

826826
cpdef void wait(self):
827-
DPCTLQueue_Wait(self._queue_ref)
827+
with nogil: DPCTLQueue_Wait(self._queue_ref)
828828

829829
cpdef memcpy(self, dest, src, size_t count):
830830
cdef void *c_dest
@@ -846,7 +846,7 @@ cdef class SyclQueue(_SyclQueue):
846846
raise RuntimeError(
847847
"SyclQueue.memcpy operation encountered an error"
848848
)
849-
DPCTLEvent_Wait(ERef)
849+
with nogil: DPCTLEvent_Wait(ERef)
850850
DPCTLEvent_Delete(ERef)
851851

852852
cpdef prefetch(self, mem, size_t count=0):
@@ -866,7 +866,7 @@ cdef class SyclQueue(_SyclQueue):
866866
raise RuntimeError(
867867
"SyclQueue.prefetch encountered an error"
868868
)
869-
DPCTLEvent_Wait(ERef)
869+
with nogil: DPCTLEvent_Wait(ERef)
870870
DPCTLEvent_Delete(ERef)
871871

872872
cpdef mem_advise(self, mem, size_t count, int advice):
@@ -886,7 +886,7 @@ cdef class SyclQueue(_SyclQueue):
886886
raise RuntimeError(
887887
"SyclQueue.mem_advise operation encountered an error"
888888
)
889-
DPCTLEvent_Wait(ERef)
889+
with nogil: DPCTLEvent_Wait(ERef)
890890
DPCTLEvent_Delete(ERef)
891891

892892
@property

dpctl/memory/_memory.pyx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,15 @@ cdef void copy_via_host(void *dest_ptr, SyclQueue dest_queue,
9494
src_ptr,
9595
nbytes
9696
)
97-
DPCTLEvent_Wait(E1Ref)
97+
with nogil: DPCTLEvent_Wait(E1Ref)
9898

9999
E2Ref = DPCTLQueue_Memcpy(
100100
dest_queue.get_queue_ref(),
101101
dest_ptr,
102102
<void *>&host_buf[0],
103103
nbytes
104104
)
105-
DPCTLEvent_Wait(E2Ref)
105+
with nogil: DPCTLEvent_Wait(E2Ref)
106106
DPCTLEvent_Delete(E1Ref)
107107
DPCTLEvent_Delete(E2Ref)
108108

@@ -142,34 +142,36 @@ cdef class _Memory:
142142
cdef _cinit_alloc(self, Py_ssize_t alignment, Py_ssize_t nbytes,
143143
bytes ptr_type, SyclQueue queue):
144144
cdef DPCTLSyclUSMRef p = NULL
145+
cdef DPCTLSyclQueueRef QRef = NULL
145146

146147
self._cinit_empty()
147148

148149
if (nbytes > 0):
149150
if queue is None:
150151
queue = dpctl.SyclQueue()
151152

153+
QRef = queue.get_queue_ref()
152154
if (ptr_type == b"shared"):
153155
if alignment > 0:
154-
p = DPCTLaligned_alloc_shared(
155-
alignment, nbytes, queue.get_queue_ref()
156+
with nogil: p = DPCTLaligned_alloc_shared(
157+
alignment, nbytes, QRef
156158
)
157159
else:
158-
p = DPCTLmalloc_shared(nbytes, queue.get_queue_ref())
160+
with nogil: p = DPCTLmalloc_shared(nbytes, QRef)
159161
elif (ptr_type == b"host"):
160162
if alignment > 0:
161-
p = DPCTLaligned_alloc_host(
162-
alignment, nbytes, queue.get_queue_ref()
163+
with nogil: p = DPCTLaligned_alloc_host(
164+
alignment, nbytes, QRef
163165
)
164166
else:
165-
p = DPCTLmalloc_host(nbytes, queue.get_queue_ref())
167+
with nogil: p = DPCTLmalloc_host(nbytes, QRef)
166168
elif (ptr_type == b"device"):
167169
if (alignment > 0):
168-
p = DPCTLaligned_alloc_device(
169-
alignment, nbytes, queue.get_queue_ref()
170+
with nogil: p = DPCTLaligned_alloc_device(
171+
alignment, nbytes, QRef
170172
)
171173
else:
172-
p = DPCTLmalloc_device(nbytes, queue.get_queue_ref())
174+
with nogil: p = DPCTLmalloc_device(nbytes, QRef)
173175
else:
174176
raise RuntimeError(
175177
"Pointer type is unknown: {}".format(
@@ -398,7 +400,7 @@ cdef class _Memory:
398400
<void *>self.memory_ptr, # source
399401
<size_t>self.nbytes
400402
)
401-
DPCTLEvent_Wait(ERef)
403+
with nogil: DPCTLEvent_Wait(ERef)
402404
DPCTLEvent_Delete(ERef)
403405

404406
return obj
@@ -423,7 +425,7 @@ cdef class _Memory:
423425
<void *>&host_buf[0], # source
424426
<size_t>buf_len
425427
)
426-
DPCTLEvent_Wait(ERef)
428+
with nogil: DPCTLEvent_Wait(ERef)
427429
DPCTLEvent_Delete(ERef)
428430

429431
cpdef copy_from_device(self, object sycl_usm_ary):
@@ -465,7 +467,7 @@ cdef class _Memory:
465467
<void *>src_buf.p,
466468
<size_t>src_buf.nbytes
467469
)
468-
DPCTLEvent_Wait(ERef)
470+
with nogil: DPCTLEvent_Wait(ERef)
469471
DPCTLEvent_Delete(ERef)
470472
else:
471473
copy_via_host(

0 commit comments

Comments
 (0)