From cb23f4a153af1a2087b1e0e6fe9fa056fcdd3f62 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 11 Dec 2025 09:01:47 -0500 Subject: [PATCH] Forward port of #1349 --- cuda_bindings/cuda/bindings/_nvml.pxd | 6 - cuda_bindings/cuda/bindings/_nvml.pyx | 691 +++++++++++++++++++++++--- 2 files changed, 631 insertions(+), 66 deletions(-) diff --git a/cuda_bindings/cuda/bindings/_nvml.pxd b/cuda_bindings/cuda/bindings/_nvml.pxd index 1059303fe4..d08b087b38 100644 --- a/cuda_bindings/cuda/bindings/_nvml.pxd +++ b/cuda_bindings/cuda/bindings/_nvml.pxd @@ -32,7 +32,6 @@ ctypedef nvmlProcessInfo_v2_t ProcessInfo_v2 ctypedef nvmlNvLinkUtilizationControl_t NvLinkUtilizationControl ctypedef nvmlViolationTime_t ViolationTime ctypedef nvmlUUIDValue_t UUIDValue -ctypedef nvmlPlatformInfo_v1_t PlatformInfo_v1 ctypedef nvmlVgpuPlacementList_v1_t VgpuPlacementList_v1 ctypedef nvmlNvLinkPowerThres_t NvLinkPowerThres ctypedef nvmlSystemEventData_v1_t SystemEventData_v1 @@ -40,11 +39,9 @@ ctypedef nvmlGpuInstanceProfileInfo_t GpuInstanceProfileInfo ctypedef nvmlComputeInstanceProfileInfo_t ComputeInstanceProfileInfo ctypedef nvmlMask255_t Mask255 ctypedef nvmlHostname_v1_t Hostname_v1 -ctypedef nvmlNvLinkInfo_v1_t NvLinkInfo_v1 ctypedef nvmlPowerValue_v2_t PowerValue_v2 ctypedef nvmlVgpuProcessUtilizationSample_t VgpuProcessUtilizationSample ctypedef nvmlGpuFabricInfo_t GpuFabricInfo -ctypedef nvmlGpuFabricInfo_v2_t GpuFabricInfo_v2 ctypedef nvmlSystemEventSetCreateRequest_v1_t SystemEventSetCreateRequest_v1 ctypedef nvmlSystemEventSetFreeRequest_v1_t SystemEventSetFreeRequest_v1 ctypedef nvmlSystemRegisterEventRequest_v1_t SystemRegisterEventRequest_v1 @@ -266,7 +263,6 @@ cpdef unsigned int device_get_pcie_link_max_speed(intptr_t device) except? 0 cpdef unsigned int device_get_pcie_speed(intptr_t device) except? 0 cpdef unsigned int device_get_adaptive_clock_info_status(intptr_t device) except? 0 cpdef unsigned int device_get_bus_type(intptr_t device) except? 0 -cpdef object device_get_gpu_fabric_info_v(intptr_t device) cpdef object system_get_conf_compute_capabilities() cpdef object system_get_conf_compute_state() cpdef object device_get_conf_compute_mem_size_info(intptr_t device) @@ -293,7 +289,6 @@ cpdef object device_get_row_remapper_histogram(intptr_t device) cpdef unsigned int device_get_architecture(intptr_t device) except? 0 cpdef object device_get_clk_mon_status(intptr_t device) cpdef object device_get_process_utilization(intptr_t device, unsigned long long last_seen_time_stamp) -cpdef object device_get_platform_info(intptr_t device) cpdef unit_set_led_state(intptr_t unit, int color) cpdef device_set_persistence_mode(intptr_t device, int mode) cpdef device_set_compute_mode(intptr_t device, int mode) @@ -445,7 +440,6 @@ cpdef object device_get_repair_status(intptr_t device) cpdef object device_get_power_mizer_mode_v1(intptr_t device) cpdef device_set_power_mizer_mode_v1(intptr_t device, intptr_t power_mizer_mode) cpdef object device_get_pdi(intptr_t device) -cpdef object device_get_nvlink_info(intptr_t device) cpdef device_read_write_prm_v1(intptr_t device, intptr_t buffer) cpdef object device_get_gpu_instance_profile_info_by_id_v(intptr_t device, unsigned int profile_id) cpdef object device_get_unrepairable_memory_flag_v1(intptr_t device) diff --git a/cuda_bindings/cuda/bindings/_nvml.pyx b/cuda_bindings/cuda/bindings/_nvml.pyx index 396034acce..8248d5acfb 100644 --- a/cuda_bindings/cuda/bindings/_nvml.pyx +++ b/cuda_bindings/cuda/bindings/_nvml.pyx @@ -13,6 +13,8 @@ from ._internal.utils cimport (get_buffer_pointer, get_nested_resource_ptr, from enum import IntEnum as _IntEnum +from cuda.bindings.cydriver cimport CUDA_VERSION + from libc.stdlib cimport calloc, free, malloc from cython cimport view @@ -5443,6 +5445,218 @@ cdef class EccSramErrorStatus_v1: return obj +cdef _get_platform_info_v1_dtype_offsets(): + cdef nvmlPlatformInfo_v1_t pod = nvmlPlatformInfo_v1_t() + return _numpy.dtype({ + 'names': ['version', 'ib_guid', 'rack_guid', 'chassis_physical_slot_number', 'compute_slot_ind_ex', 'node_ind_ex', 'peer_type', 'module_id'], + 'formats': [_numpy.uint32, _numpy.uint8, _numpy.uint8, _numpy.uint8, _numpy.uint8, _numpy.uint8, _numpy.uint8, _numpy.uint8], + 'offsets': [ + (&(pod.version)) - (&pod), + (&(pod.ibGuid)) - (&pod), + (&(pod.rackGuid)) - (&pod), + (&(pod.chassisPhysicalSlotNumber)) - (&pod), + (&(pod.computeSlotIndex)) - (&pod), + (&(pod.nodeIndex)) - (&pod), + (&(pod.peerType)) - (&pod), + (&(pod.moduleId)) - (&pod), + ], + 'itemsize': sizeof(nvmlPlatformInfo_v1_t), + }) + +platform_info_v1_dtype = _get_platform_info_v1_dtype_offsets() + +cdef class PlatformInfo_v1: + """Empty-initialize an instance of `nvmlPlatformInfo_v1_t`. + + + .. seealso:: `nvmlPlatformInfo_v1_t` + """ + cdef: + nvmlPlatformInfo_v1_t *_ptr + object _owner + bint _owned + bint _readonly + + def __init__(self): + self._ptr = calloc(1, sizeof(nvmlPlatformInfo_v1_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating PlatformInfo_v1") + self._owner = None + self._owned = True + self._readonly = False + + def __dealloc__(self): + cdef nvmlPlatformInfo_v1_t *ptr + if self._owned and self._ptr != NULL: + ptr = self._ptr + self._ptr = NULL + free(ptr) + + def __repr__(self): + return f"<{__name__}.PlatformInfo_v1 object at {hex(id(self))}>" + + @property + def ptr(self): + """Get the pointer address to the data as Python :class:`int`.""" + return (self._ptr) + + cdef intptr_t _get_ptr(self): + return (self._ptr) + + def __int__(self): + return (self._ptr) + + def __eq__(self, other): + cdef PlatformInfo_v1 other_ + if not isinstance(other, PlatformInfo_v1): + return False + other_ = other + return (memcmp((self._ptr), (other_._ptr), sizeof(nvmlPlatformInfo_v1_t)) == 0) + + def __setitem__(self, key, val): + if key == 0 and isinstance(val, _numpy.ndarray): + self._ptr = malloc(sizeof(nvmlPlatformInfo_v1_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating PlatformInfo_v1") + memcpy(self._ptr, val.ctypes.data, sizeof(nvmlPlatformInfo_v1_t)) + self._owner = None + self._owned = True + self._readonly = not val.flags.writeable + else: + setattr(self, key, val) + + @property + def version(self): + """int: the API version number""" + return self._ptr[0].version + + @version.setter + def version(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].version = val + + @property + def ib_guid(self): + """~_numpy.uint8: (array of length 16).Infiniband GUID reported by platform (for Blackwell, ibGuid is 8 bytes so indices 8-15 are zero)""" + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c", allocate_buffer=False) + arr.data = (&(self._ptr[0].ibGuid)) + return _numpy.asarray(arr) + + @ib_guid.setter + def ib_guid(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c") + arr[:] = _numpy.asarray(val, dtype=_numpy.uint8) + memcpy((&(self._ptr[0].ibGuid)), (arr.data), sizeof(unsigned char) * len(val)) + + @property + def rack_guid(self): + """~_numpy.uint8: (array of length 16).GUID of the rack containing this GPU (for Blackwell rackGuid is 13 bytes so indices 13-15 are zero)""" + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c", allocate_buffer=False) + arr.data = (&(self._ptr[0].rackGuid)) + return _numpy.asarray(arr) + + @rack_guid.setter + def rack_guid(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c") + arr[:] = _numpy.asarray(val, dtype=_numpy.uint8) + memcpy((&(self._ptr[0].rackGuid)), (arr.data), sizeof(unsigned char) * len(val)) + + @property + def chassis_physical_slot_number(self): + """int: The slot number in the rack containing this GPU (includes switches)""" + return self._ptr[0].chassisPhysicalSlotNumber + + @chassis_physical_slot_number.setter + def chassis_physical_slot_number(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].chassisPhysicalSlotNumber = val + + @property + def compute_slot_ind_ex(self): + """int: The index within the compute slots in the rack containing this GPU (does not include switches)""" + return self._ptr[0].computeSlotIndex + + @compute_slot_ind_ex.setter + def compute_slot_ind_ex(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].computeSlotIndex = val + + @property + def node_ind_ex(self): + """int: Index of the node within the slot containing this GPU.""" + return self._ptr[0].nodeIndex + + @node_ind_ex.setter + def node_ind_ex(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].nodeIndex = val + + @property + def peer_type(self): + """int: Platform indicated NVLink-peer type (e.g. switch present or not)""" + return self._ptr[0].peerType + + @peer_type.setter + def peer_type(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].peerType = val + + @property + def module_id(self): + """int: ID of this GPU within the node.""" + return self._ptr[0].moduleId + + @module_id.setter + def module_id(self, val): + if self._readonly: + raise ValueError("This PlatformInfo_v1 instance is read-only") + self._ptr[0].moduleId = val + + @staticmethod + def from_data(data): + """Create an PlatformInfo_v1 instance wrapping the given NumPy array. + + Args: + data (_numpy.ndarray): a single-element array of dtype `platform_info_v1_dtype` holding the data. + """ + return __from_data(data, "platform_info_v1_dtype", platform_info_v1_dtype, PlatformInfo_v1) + + @staticmethod + def from_ptr(intptr_t ptr, bint readonly=False, object owner=None): + """Create an PlatformInfo_v1 instance wrapping the given pointer. + + Args: + ptr (intptr_t): pointer address as Python :class:`int` to the data. + owner (object): The Python object that owns the pointer. If not provided, data will be copied. + readonly (bool): whether the data is read-only (to the user). default is `False`. + """ + if ptr == 0: + raise ValueError("ptr must not be null (0)") + cdef PlatformInfo_v1 obj = PlatformInfo_v1.__new__(PlatformInfo_v1) + if owner is None: + obj._ptr = malloc(sizeof(nvmlPlatformInfo_v1_t)) + if obj._ptr == NULL: + raise MemoryError("Error allocating PlatformInfo_v1") + memcpy((obj._ptr), ptr, sizeof(nvmlPlatformInfo_v1_t)) + obj._owner = None + obj._owned = True + else: + obj._ptr = ptr + obj._owner = owner + obj._owned = False + obj._readonly = readonly + return obj + + cdef _get_platform_info_v2_dtype_offsets(): cdef nvmlPlatformInfo_v2_t pod = nvmlPlatformInfo_v2_t() return _numpy.dtype({ @@ -11414,6 +11628,190 @@ cdef class ConfComputeGetKeyRotationThresholdInfo_v1: return obj +cdef _get_gpu_fabric_info_v2_dtype_offsets(): + cdef nvmlGpuFabricInfo_v2_t pod = nvmlGpuFabricInfo_v2_t() + return _numpy.dtype({ + 'names': ['version', 'cluster_uuid', 'status', 'clique_id', 'state', 'health_mask'], + 'formats': [_numpy.uint32, _numpy.uint8, _numpy.int32, _numpy.uint32, _numpy.uint8, _numpy.uint32], + 'offsets': [ + (&(pod.version)) - (&pod), + (&(pod.clusterUuid)) - (&pod), + (&(pod.status)) - (&pod), + (&(pod.cliqueId)) - (&pod), + (&(pod.state)) - (&pod), + (&(pod.healthMask)) - (&pod), + ], + 'itemsize': sizeof(nvmlGpuFabricInfo_v2_t), + }) + +gpu_fabric_info_v2_dtype = _get_gpu_fabric_info_v2_dtype_offsets() + +cdef class GpuFabricInfo_v2: + """Empty-initialize an instance of `nvmlGpuFabricInfo_v2_t`. + + + .. seealso:: `nvmlGpuFabricInfo_v2_t` + """ + cdef: + nvmlGpuFabricInfo_v2_t *_ptr + object _owner + bint _owned + bint _readonly + + def __init__(self): + self._ptr = calloc(1, sizeof(nvmlGpuFabricInfo_v2_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating GpuFabricInfo_v2") + self._owner = None + self._owned = True + self._readonly = False + + def __dealloc__(self): + cdef nvmlGpuFabricInfo_v2_t *ptr + if self._owned and self._ptr != NULL: + ptr = self._ptr + self._ptr = NULL + free(ptr) + + def __repr__(self): + return f"<{__name__}.GpuFabricInfo_v2 object at {hex(id(self))}>" + + @property + def ptr(self): + """Get the pointer address to the data as Python :class:`int`.""" + return (self._ptr) + + cdef intptr_t _get_ptr(self): + return (self._ptr) + + def __int__(self): + return (self._ptr) + + def __eq__(self, other): + cdef GpuFabricInfo_v2 other_ + if not isinstance(other, GpuFabricInfo_v2): + return False + other_ = other + return (memcmp((self._ptr), (other_._ptr), sizeof(nvmlGpuFabricInfo_v2_t)) == 0) + + def __setitem__(self, key, val): + if key == 0 and isinstance(val, _numpy.ndarray): + self._ptr = malloc(sizeof(nvmlGpuFabricInfo_v2_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating GpuFabricInfo_v2") + memcpy(self._ptr, val.ctypes.data, sizeof(nvmlGpuFabricInfo_v2_t)) + self._owner = None + self._owned = True + self._readonly = not val.flags.writeable + else: + setattr(self, key, val) + + @property + def version(self): + """int: Structure version identifier (set to nvmlGpuFabricInfo_v2)""" + return self._ptr[0].version + + @version.setter + def version(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + self._ptr[0].version = val + + @property + def cluster_uuid(self): + """~_numpy.uint8: (array of length 16).Uuid of the cluster to which this GPU belongs.""" + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c", allocate_buffer=False) + arr.data = (&(self._ptr[0].clusterUuid)) + return _numpy.asarray(arr) + + @cluster_uuid.setter + def cluster_uuid(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + cdef view.array arr = view.array(shape=(16,), itemsize=sizeof(unsigned char), format="B", mode="c") + arr[:] = _numpy.asarray(val, dtype=_numpy.uint8) + memcpy((&(self._ptr[0].clusterUuid)), (arr.data), sizeof(unsigned char) * len(val)) + + @property + def status(self): + """int: Probe Error status, if any. Must be checked only if Probe state returns "complete".""" + return (self._ptr[0].status) + + @status.setter + def status(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + self._ptr[0].status = val + + @property + def clique_id(self): + """int: ID of the fabric clique to which this GPU belongs.""" + return self._ptr[0].cliqueId + + @clique_id.setter + def clique_id(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + self._ptr[0].cliqueId = val + + @property + def state(self): + """int: Current Probe State of GPU registration process. See NVML_GPU_FABRIC_STATE_*.""" + return (self._ptr[0].state) + + @state.setter + def state(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + self._ptr[0].state = val + + @property + def health_mask(self): + """int: GPU Fabric health Status Mask. See NVML_GPU_FABRIC_HEALTH_MASK_*.""" + return self._ptr[0].healthMask + + @health_mask.setter + def health_mask(self, val): + if self._readonly: + raise ValueError("This GpuFabricInfo_v2 instance is read-only") + self._ptr[0].healthMask = val + + @staticmethod + def from_data(data): + """Create an GpuFabricInfo_v2 instance wrapping the given NumPy array. + + Args: + data (_numpy.ndarray): a single-element array of dtype `gpu_fabric_info_v2_dtype` holding the data. + """ + return __from_data(data, "gpu_fabric_info_v2_dtype", gpu_fabric_info_v2_dtype, GpuFabricInfo_v2) + + @staticmethod + def from_ptr(intptr_t ptr, bint readonly=False, object owner=None): + """Create an GpuFabricInfo_v2 instance wrapping the given pointer. + + Args: + ptr (intptr_t): pointer address as Python :class:`int` to the data. + owner (object): The Python object that owns the pointer. If not provided, data will be copied. + readonly (bool): whether the data is read-only (to the user). default is `False`. + """ + if ptr == 0: + raise ValueError("ptr must not be null (0)") + cdef GpuFabricInfo_v2 obj = GpuFabricInfo_v2.__new__(GpuFabricInfo_v2) + if owner is None: + obj._ptr = malloc(sizeof(nvmlGpuFabricInfo_v2_t)) + if obj._ptr == NULL: + raise MemoryError("Error allocating GpuFabricInfo_v2") + memcpy((obj._ptr), ptr, sizeof(nvmlGpuFabricInfo_v2_t)) + obj._owner = None + obj._owned = True + else: + obj._ptr = ptr + obj._owner = owner + obj._owned = False + obj._readonly = readonly + return obj + + cdef _get_nvlink_supported_bw_modes_v1_dtype_offsets(): cdef nvmlNvlinkSupportedBwModes_v1_t pod = nvmlNvlinkSupportedBwModes_v1_t() return _numpy.dtype({ @@ -14889,6 +15287,138 @@ cdef class GpuFabricInfo_v3: return obj +cdef _get_nv_link_info_v1_dtype_offsets(): + cdef nvmlNvLinkInfo_v1_t pod = nvmlNvLinkInfo_v1_t() + return _numpy.dtype({ + 'names': ['version', 'is_nvle_enabled'], + 'formats': [_numpy.uint32, _numpy.uint32], + 'offsets': [ + (&(pod.version)) - (&pod), + (&(pod.isNvleEnabled)) - (&pod), + ], + 'itemsize': sizeof(nvmlNvLinkInfo_v1_t), + }) + +nv_link_info_v1_dtype = _get_nv_link_info_v1_dtype_offsets() + +cdef class NvLinkInfo_v1: + """Empty-initialize an instance of `nvmlNvLinkInfo_v1_t`. + + + .. seealso:: `nvmlNvLinkInfo_v1_t` + """ + cdef: + nvmlNvLinkInfo_v1_t *_ptr + object _owner + bint _owned + bint _readonly + + def __init__(self): + self._ptr = calloc(1, sizeof(nvmlNvLinkInfo_v1_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating NvLinkInfo_v1") + self._owner = None + self._owned = True + self._readonly = False + + def __dealloc__(self): + cdef nvmlNvLinkInfo_v1_t *ptr + if self._owned and self._ptr != NULL: + ptr = self._ptr + self._ptr = NULL + free(ptr) + + def __repr__(self): + return f"<{__name__}.NvLinkInfo_v1 object at {hex(id(self))}>" + + @property + def ptr(self): + """Get the pointer address to the data as Python :class:`int`.""" + return (self._ptr) + + cdef intptr_t _get_ptr(self): + return (self._ptr) + + def __int__(self): + return (self._ptr) + + def __eq__(self, other): + cdef NvLinkInfo_v1 other_ + if not isinstance(other, NvLinkInfo_v1): + return False + other_ = other + return (memcmp((self._ptr), (other_._ptr), sizeof(nvmlNvLinkInfo_v1_t)) == 0) + + def __setitem__(self, key, val): + if key == 0 and isinstance(val, _numpy.ndarray): + self._ptr = malloc(sizeof(nvmlNvLinkInfo_v1_t)) + if self._ptr == NULL: + raise MemoryError("Error allocating NvLinkInfo_v1") + memcpy(self._ptr, val.ctypes.data, sizeof(nvmlNvLinkInfo_v1_t)) + self._owner = None + self._owned = True + self._readonly = not val.flags.writeable + else: + setattr(self, key, val) + + @property + def version(self): + """int: IN - the API version number.""" + return self._ptr[0].version + + @version.setter + def version(self, val): + if self._readonly: + raise ValueError("This NvLinkInfo_v1 instance is read-only") + self._ptr[0].version = val + + @property + def is_nvle_enabled(self): + """int: OUT - NVLINK encryption enablement.""" + return self._ptr[0].isNvleEnabled + + @is_nvle_enabled.setter + def is_nvle_enabled(self, val): + if self._readonly: + raise ValueError("This NvLinkInfo_v1 instance is read-only") + self._ptr[0].isNvleEnabled = val + + @staticmethod + def from_data(data): + """Create an NvLinkInfo_v1 instance wrapping the given NumPy array. + + Args: + data (_numpy.ndarray): a single-element array of dtype `nv_link_info_v1_dtype` holding the data. + """ + return __from_data(data, "nv_link_info_v1_dtype", nv_link_info_v1_dtype, NvLinkInfo_v1) + + @staticmethod + def from_ptr(intptr_t ptr, bint readonly=False, object owner=None): + """Create an NvLinkInfo_v1 instance wrapping the given pointer. + + Args: + ptr (intptr_t): pointer address as Python :class:`int` to the data. + owner (object): The Python object that owns the pointer. If not provided, data will be copied. + readonly (bool): whether the data is read-only (to the user). default is `False`. + """ + if ptr == 0: + raise ValueError("ptr must not be null (0)") + cdef NvLinkInfo_v1 obj = NvLinkInfo_v1.__new__(NvLinkInfo_v1) + if owner is None: + obj._ptr = malloc(sizeof(nvmlNvLinkInfo_v1_t)) + if obj._ptr == NULL: + raise MemoryError("Error allocating NvLinkInfo_v1") + memcpy((obj._ptr), ptr, sizeof(nvmlNvLinkInfo_v1_t)) + obj._owner = None + obj._owned = True + else: + obj._ptr = ptr + obj._owner = owner + obj._owned = False + obj._readonly = readonly + return obj + + cdef _get_nvlink_firmware_version_dtype_offsets(): cdef nvmlNvlinkFirmwareVersion_t pod = nvmlNvlinkFirmwareVersion_t() return _numpy.dtype({ @@ -22880,26 +23410,6 @@ cpdef unsigned int device_get_bus_type(intptr_t device) except? 0: return type -cpdef object device_get_gpu_fabric_info_v(intptr_t device): - """Versioned wrapper around nvmlDeviceGetGpuFabricInfo that accepts a versioned ``nvmlGpuFabricInfo_v2_t`` or later output structure. - - Args: - device (intptr_t): The identifier of the target device. - - Returns: - nvmlGpuFabricInfo_v3_t: Information about GPU fabric state. - - .. seealso:: `nvmlDeviceGetGpuFabricInfoV` - """ - cdef GpuFabricInfo_v3 gpu_fabric_info_py = GpuFabricInfo_v3() - cdef nvmlGpuFabricInfoV_t *gpu_fabric_info = (gpu_fabric_info_py._get_ptr()) - gpu_fabric_info.version = sizeof(nvmlGpuFabricInfo_v3_t) | (3 << 24) - with nogil: - __status__ = nvmlDeviceGetGpuFabricInfoV(device, gpu_fabric_info) - check_status(__status__) - return gpu_fabric_info_py - - cpdef object system_get_conf_compute_capabilities(): """Get Conf Computing System capabilities. @@ -23381,26 +23891,6 @@ cpdef object device_get_process_utilization(intptr_t device, unsigned long long return utilization -cpdef object device_get_platform_info(intptr_t device): - """Get platform information of this device. - - Args: - device (intptr_t): The identifier of the target device. - - Returns: - nvmlPlatformInfo_v2_t: Pointer to the caller-provided structure of nvmlPlatformInfo_t. - - .. seealso:: `nvmlDeviceGetPlatformInfo` - """ - cdef PlatformInfo_v2 platform_info_py = PlatformInfo_v2() - cdef nvmlPlatformInfo_t *platform_info = (platform_info_py._get_ptr()) - platform_info.version = sizeof(nvmlPlatformInfo_v2_t) | (2 << 24) - with nogil: - __status__ = nvmlDeviceGetPlatformInfo(device, platform_info) - check_status(__status__) - return platform_info_py - - cpdef unit_set_led_state(intptr_t unit, int color): """Set the LED state for the unit. The LED can be either green (0) or amber (1). @@ -26021,26 +26511,6 @@ cpdef object device_get_pdi(intptr_t device): return pdi_py -cpdef object device_get_nvlink_info(intptr_t device): - """Query NVLINK information associated with this device. - - Args: - device (intptr_t): The identifier of the target device. - - Returns: - nvmlNvLinkInfo_v2_t: Reference to ``nvmlNvLinkInfo_t``. - - .. seealso:: `nvmlDeviceGetNvLinkInfo` - """ - cdef NvLinkInfo_v2 info_py = NvLinkInfo_v2() - cdef nvmlNvLinkInfo_t *info = (info_py._get_ptr()) - info.version = sizeof(nvmlNvLinkInfo_v2_t) | (2 << 24) - with nogil: - __status__ = nvmlDeviceGetNvLinkInfo(device, info) - check_status(__status__) - return info_py - - cpdef device_read_write_prm_v1(intptr_t device, intptr_t buffer): """Read or write a GPU PRM register. The input is assumed to be in TLV format in network byte order. @@ -26930,3 +27400,104 @@ cpdef object device_get_sram_unique_uncorrected_ecc_error_counts(intptr_t device check_status(__status__) return errorCounts + + +cpdef object device_get_gpu_fabric_info_v(intptr_t device): + """Versioned wrapper around nvmlDeviceGetGpuFabricInfo that accepts a versioned ``nvmlGpuFabricInfo_v2_t`` or later output structure. + + Args: + device (intptr_t): The identifier of the target device. + + Returns: + nvmlGpuFabricInfo_v3_t: Information about GPU fabric state. + + .. seealso:: `nvmlDeviceGetGpuFabricInfoV` + """ + cdef GpuFabricInfo_v3 gpu_fabric_info_v3_py + cdef GpuFabricInfo_v2 gpu_fabric_info_v2_py + cdef nvmlGpuFabricInfoV_t *gpu_fabric_info + if CUDA_VERSION >= 13000: + gpu_fabric_info_v3_py = GpuFabricInfo_v3() + gpu_fabric_info = (gpu_fabric_info_v3_py._get_ptr()) + gpu_fabric_info.version = sizeof(nvmlGpuFabricInfo_v3_t) | (3 << 24) + with nogil: + __status__ = nvmlDeviceGetGpuFabricInfoV(device, gpu_fabric_info) + check_status(__status__) + return gpu_fabric_info_v3_py + + else: + gpu_fabric_info_v2_py = GpuFabricInfo_v2() + gpu_fabric_info = (gpu_fabric_info_v2_py._get_ptr()) + gpu_fabric_info.version = sizeof(nvmlGpuFabricInfo_v2_t) | (2 << 24) + with nogil: + __status__ = nvmlDeviceGetGpuFabricInfoV(device, gpu_fabric_info) + check_status(__status__) + return gpu_fabric_info_v2_py + + +cpdef object device_get_platform_info(intptr_t device): + """Get platform information of this device. + + Args: + device (intptr_t): The identifier of the target device. + + Returns: + nvmlPlatformInfo_v2_t: Pointer to the caller-provided structure of nvmlPlatformInfo_t. + + .. seealso:: `nvmlDeviceGetPlatformInfo` + """ + cdef PlatformInfo_v1 platform_info_v1_py + cdef PlatformInfo_v2 platform_info_v2_py + cdef nvmlPlatformInfo_t *platform_info + + if CUDA_VERSION >= 13000: + platform_info_v2_py = PlatformInfo_v2() + platform_info = (platform_info_v2_py._get_ptr()) + platform_info.version = sizeof(nvmlPlatformInfo_v2_t) | (2 << 24) + with nogil: + __status__ = nvmlDeviceGetPlatformInfo(device, platform_info) + check_status(__status__) + return platform_info_v2_py + + else: + platform_info_v1_py = PlatformInfo_v1() + platform_info = (platform_info_v1_py._get_ptr()) + platform_info.version = sizeof(nvmlPlatformInfo_v1_t) | (1 << 24) + with nogil: + __status__ = nvmlDeviceGetPlatformInfo(device, platform_info) + check_status(__status__) + return platform_info_v1_py + + +cpdef object device_get_nvlink_info(intptr_t device): + """Query NVLINK information associated with this device. + + Args: + device (intptr_t): The identifier of the target device. + + Returns: + nvmlNvLinkInfo_v2_t: Reference to ``nvmlNvLinkInfo_t``. + + .. seealso:: `nvmlDeviceGetNvLinkInfo` + """ + cdef NvLinkInfo_v1 info_v1_py + cdef NvLinkInfo_v2 info_v2_py + cdef nvmlNvLinkInfo_t *info + + if CUDA_VERSION >= 13000: + info_v2_py = NvLinkInfo_v2() + info = (info_v2_py._get_ptr()) + info.version = sizeof(nvmlNvLinkInfo_v2_t) | (2 << 24) + with nogil: + __status__ = nvmlDeviceGetNvLinkInfo(device, info) + check_status(__status__) + return info_v2_py + + else: + info_v1_py = NvLinkInfo_v1() + info = (info_v1_py._get_ptr()) + info.version = sizeof(nvmlNvLinkInfo_v1_t) | (1 << 24) + with nogil: + __status__ = nvmlDeviceGetNvLinkInfo(device, info) + check_status(__status__) + return info_v1_py