Skip to content
Merged
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
28 changes: 19 additions & 9 deletions cuda_core/cuda/core/_device.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ cdef class DeviceProperties:
self._cache = {}
return self

cdef inline _get_attribute(self, cydriver.CUdevice_attribute attr):
cdef inline int _get_attribute(self, cydriver.CUdevice_attribute attr, default=0) except? -2:
"""Retrieve the attribute value directly from the driver."""
cdef int val
cdef cydriver.CUresult err
with nogil:
err = cydriver.cuDeviceGetAttribute(&val, attr, self._handle)
if err == cydriver.CUresult.CUDA_ERROR_INVALID_VALUE:
return 0
if err == cydriver.CUresult.CUDA_ERROR_INVALID_VALUE and default is not None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tiny tweak will make it possible to specify None as the default.

@@ -32,6 +32,7 @@ if TYPE_CHECKING:
 # but it seems it is very convenient to expose them for testing purposes...
 _tls = threading.local()
 _lock = threading.Lock()
+_NO_DEFAULT = object()
 cdef bint _is_cuInit = False


@@ -61,7 +62,7 @@ cdef class DeviceProperties:
         cdef cydriver.CUresult err
         with nogil:
             err = cydriver.cuDeviceGetAttribute(&val, attr, self._handle)
-        if err == cydriver.CUresult.CUDA_ERROR_INVALID_VALUE and default is not None:
+        if err == cydriver.CUresult.CUDA_ERROR_INVALID_VALUE and default is not _NO_DEFAULT:
             return default
         HANDLE_RETURN(err)
         return val

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After updating the type signatures to return int for slight efficiency, it was no longer possible to return None so I updated the two related functions locally to convert 0 to None.

return <int>default
HANDLE_RETURN(err)
return val

cdef _get_cached_attribute(self, attr):
cdef inline int _get_cached_attribute(self, attr, default=0) except? -2:
"""Retrieve the attribute value, using cache if applicable."""
if attr not in self._cache:
self._cache[attr] = self._get_attribute(attr)
self._cache[attr] = self._get_attribute(attr, default)
return self._cache[attr]

@property
Expand Down Expand Up @@ -787,6 +787,8 @@ cdef class DeviceProperties:
"""bool: Device supports buffer sharing with dma_buf mechanism."""
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED))

# Start of CUDA 12 device attributes

@property
def ipc_event_supported(self) -> bool:
"""bool: Device supports IPC Events."""
Expand All @@ -795,7 +797,7 @@ cdef class DeviceProperties:
@property
def mem_sync_domain_count(self) -> int:
"""int: Number of memory domains the device supports."""
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEM_SYNC_DOMAIN_COUNT)
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEM_SYNC_DOMAIN_COUNT, default=1)

@property
def tensor_map_access_supported(self) -> bool:
Expand Down Expand Up @@ -824,7 +826,7 @@ cdef class DeviceProperties:
@property
def host_numa_id(self) -> int:
"""int: NUMA ID of the host node closest to the device. Returns -1 when system does not support NUMA."""
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_ID)
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_ID, default=-1)

@property
def d3d12_cig_supported(self) -> bool:
Expand All @@ -848,12 +850,18 @@ cdef class DeviceProperties:

@property
def gpu_pci_device_id(self) -> int:
"""int: The combined 16-bit PCI device ID and 16-bit PCI vendor ID."""
"""int: The combined 16-bit PCI device ID and 16-bit PCI vendor ID.

Returns 0 if the driver does not support this query.
"""
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_GPU_PCI_DEVICE_ID)

@property
def gpu_pci_subsystem_id(self) -> int:
"""int: The combined 16-bit PCI subsystem ID and 16-bit PCI subsystem vendor ID."""
"""int: The combined 16-bit PCI subsystem ID and 16-bit PCI subsystem vendor ID.

Returns 0 if the driver does not support this query.
"""
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_GPU_PCI_SUBSYSTEM_ID)

@property
Expand All @@ -872,6 +880,8 @@ cdef class DeviceProperties:
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_MEMORY_POOLS_SUPPORTED)
)

# Start of CUDA 13 device attributes

@property
def host_numa_multinode_ipc_supported(self) -> bool:
"""bool: Device supports HOST_NUMA location IPC between nodes in a multi-node system."""
Expand Down
Loading