Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_context.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class Context:
def _handle(self) -> cuda.bindings.driver.CUcontext | None:
...

def __bool__(self) -> bool:
...

@property
def is_green(self) -> bool:
"""True if this context was created from device resources."""
Expand Down
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_context.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ cdef class Context:
def _handle(self) -> cuda.bindings.driver.CUcontext | None:
return self.handle

def __bool__(self) -> bool:
return self._h_context.get() != NULL

@property
def is_green(self) -> bool:
"""True if this context was created from device resources."""
Expand Down
2 changes: 2 additions & 0 deletions cuda_core/cuda/core/_device.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,8 @@ class Device:
if ctx is not None:
# TODO: revisit once Context is cythonized
assert_type(ctx, Context)
if not ctx:
raise RuntimeError("Context has been closed")
if ctx._device_id != self._device_id:
raise RuntimeError(
"the provided context was created on the device with"
Expand Down
4 changes: 4 additions & 0 deletions cuda_core/cuda/core/_event.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ cdef class Event:
cdef Event _from_handle(EventHandle h_event)

cpdef close(self)


cdef Event Event_accept(object arg)
cdef int Event_check_open(Event self) except -1
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_event.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class Event:
def __init__(self, *args, **kwargs) -> None:
...

def __bool__(self) -> bool:
...

def __isub__(self, other: object):
...

Expand Down
31 changes: 29 additions & 2 deletions cuda_core/cuda/core/_event.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ cdef class Event:
"""
self._h_event.reset()

def __bool__(self) -> bool:
return self._h_event.get() != NULL

def __isub__(self, other: object):
return NotImplemented

Expand All @@ -165,14 +168,16 @@ cdef class Event:

def __sub__(self, other: Event) -> float:
# return self - other (in milliseconds)
Event_check_open(self)
cdef Event other_event = Event_accept(other)
cdef float timing
with nogil:
err = cydriver.cuEventElapsedTime(&timing, as_cu((<Event>other)._h_event), as_cu(self._h_event))
err = cydriver.cuEventElapsedTime(&timing, as_cu(other_event._h_event), as_cu(self._h_event))
if err == 0:
return timing
else:
if err == cydriver.CUresult.CUDA_ERROR_INVALID_HANDLE:
if not self.is_timing_enabled or not other.is_timing_enabled:
if not self.is_timing_enabled or not other_event.is_timing_enabled:
explanation = (
"Both Events must be created with timing enabled in order to subtract them; "
"use EventOptions(timing_enabled=True) when creating both events."
Expand Down Expand Up @@ -208,6 +213,7 @@ cdef class Event:
@property
def ipc_descriptor(self) -> IPCEventDescriptor:
"""Descriptor for sharing this event with other processes."""
Event_check_open(self)
if self._ipc_descriptor is not None:
return self._ipc_descriptor
if not self.is_ipc_enabled:
Expand Down Expand Up @@ -255,18 +261,21 @@ cdef class Event:
@property
def is_ipc_enabled(self) -> bool:
"""Return True if the event can be shared across process boundaries, otherwise False."""
Event_check_open(self)
return get_event_ipc_enabled(self._h_event)

@property
def is_timing_enabled(self) -> bool:
"""Return True if the event records timing data, otherwise False."""
Event_check_open(self)
return get_event_timing_enabled(self._h_event)

@property
def is_blocking_sync(self) -> bool:
"""Return True if the event uses blocking synchronization (the CPU
thread blocks on :meth:`sync` instead of busy-waiting), otherwise False.
"""
Event_check_open(self)
return get_event_is_blocking_sync(self._h_event)

def sync(self) -> None:
Expand All @@ -278,12 +287,14 @@ cdef class Event:
thread busy-waits until the event has completed.

"""
Event_check_open(self)
with nogil:
HANDLE_RETURN(cydriver.cuEventSynchronize(as_cu(self._h_event)))

@property
def is_done(self) -> bool:
"""Return True if all captured works have been completed, otherwise False."""
Event_check_open(self)
with nogil:
result = cydriver.cuEventQuery(as_cu(self._h_event))
if result == cydriver.CUresult.CUDA_SUCCESS:
Expand Down Expand Up @@ -314,6 +325,7 @@ cdef class Event:
context is set current after a event is created.

"""
Event_check_open(self)
cdef int dev_id = get_event_device_id(self._h_event)
if dev_id >= 0:
from ._device import Device # avoid circular import
Expand All @@ -322,12 +334,27 @@ cdef class Event:
@property
def context(self) -> Context:
"""Return the :obj:`~_context.Context` associated with this event."""
Event_check_open(self)
cdef ContextHandle h_ctx = get_event_context(self._h_event)
cdef int dev_id = get_event_device_id(self._h_event)
if h_ctx and dev_id >= 0:
return Context._from_handle(Context, h_ctx, dev_id)


cdef int Event_check_open(Event self) except -1:
if not self._h_event:
raise RuntimeError("Event has been closed")
return 0


cdef Event Event_accept(object arg):
if not isinstance(arg, Event):
raise TypeError(f"Event expected, got {type(arg).__name__}")
cdef Event event = <Event>arg
Event_check_open(event)
return event


cdef class IPCEventDescriptor:
"""Serializable object describing an event that can be shared between processes."""

Expand Down
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_graphics.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ class GraphicsResource:
def handle(self) -> int:
"""The raw ``CUgraphicsResource`` handle as a Python int."""

def __bool__(self) -> bool:
...

@property
def resource_handle(self) -> int:
"""Alias for :attr:`handle`."""
Expand Down
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_graphics.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ cdef class GraphicsResource:
"""The raw ``CUgraphicsResource`` handle as a Python int."""
return as_intptr(self._handle)

def __bool__(self) -> bool:
return self._handle.get() != NULL

@property
def resource_handle(self) -> int:
"""Alias for :attr:`handle`."""
Expand Down
4 changes: 4 additions & 0 deletions cuda_core/cuda/core/_kernel_arg_handler.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ cdef class ParamHolder:
for i, arg in enumerate(kernel_args):
arg_type = type(arg)
if arg_type is Buffer:
if not arg:
raise RuntimeError("Buffer has been closed")
# we need the address of where the actual buffer address is stored
if type(arg.handle) is int:
# see note below on handling int arguments
Expand Down Expand Up @@ -327,6 +329,8 @@ cdef class ParamHolder:
continue
# If no exact types are found, fallback to slower `isinstance` check
elif isinstance(arg, Buffer):
if not arg:
raise RuntimeError("Buffer has been closed")
if isinstance(arg.handle, int):
prepare_arg[intptr_t](self.data, self.data_addresses, arg.handle, i)
continue
Expand Down
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_linker.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class Linker:
def __init__(self, options: LinkerOptions | None=None, *object_codes: ObjectCode):
...

def __bool__(self) -> bool:
...

def link(self, target_type: ObjectCodeFormatType | str) -> ObjectCode:
"""Link the provided object codes into a single output of the specified target type.

Expand Down
11 changes: 11 additions & 0 deletions cuda_core/cuda/core/_linker.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ cdef class Linker:
def __init__(self, *object_codes: ObjectCode, options: LinkerOptions | None = None):
Linker_init(self, object_codes, options)

def __bool__(self) -> bool:
if self._use_nvjitlink:
return self._nvjitlink_handle.get() != NULL
return self._culink_handle.get() != NULL

def link(self, target_type: ObjectCodeFormatType | str) -> ObjectCode:
"""Link the provided object codes into a single output of the specified target type.

Expand All @@ -99,6 +104,8 @@ cdef class Linker:
Ensure that input object codes were compiled with appropriate
flags for linking (e.g., relocatable device code enabled).
"""
if not self:
raise RuntimeError("Linker has been closed")
return Linker_link(self, str(target_type))

def get_error_log(self) -> str:
Expand All @@ -112,6 +119,8 @@ cdef class Linker:
# After link(), the decoded log is cached here.
if self._error_log is not None:
return self._error_log
if not self:
raise RuntimeError("Linker has been closed")
cdef cynvjitlink.nvJitLinkHandle c_h
cdef size_t c_log_size = 0
cdef char* c_log_ptr
Expand All @@ -138,6 +147,8 @@ cdef class Linker:
# After link(), the decoded log is cached here.
if self._info_log is not None:
return self._info_log
if not self:
raise RuntimeError("Linker has been closed")
cdef cynvjitlink.nvJitLinkHandle c_h
cdef size_t c_log_size = 0
cdef char* c_log_ptr
Expand Down
1 change: 1 addition & 0 deletions cuda_core/cuda/core/_memory/_buffer.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ cdef Buffer Buffer_from_deviceptr_handle(
# prefetch_batch, discard_batch, discard_prefetch_batch). `single_hint`
# names the per-buffer API to use instead when a bare Buffer is passed.
cdef tuple Buffer_coerce_batch(object buffers, str what, str single_hint)
cdef int Buffer_check_open(Buffer self) except -1
3 changes: 3 additions & 0 deletions cuda_core/cuda/core/_memory/_buffer.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ class Buffer:
handle, call ``int(Buffer.handle)``.
"""

def __bool__(self) -> bool:
...

def __eq__(self, other: object) -> bool:
...

Expand Down
Loading
Loading