From 4d9ab72ca38436a0ac7d019f37057cd9a254452b Mon Sep 17 00:00:00 2001 From: Aviral Nigam Date: Thu, 5 Nov 2026 15:43:09 +0530 Subject: [PATCH] feature: Add pyzes support for device index and GPU topology properties Add python bindings, unit tests, black box test coverage and README entries for: 1. zes_device_index_ext_properties_t 2. zes_device_gpu_topology_ext_properties_t Related-To: SYSM-474, SYSM-475, SYSM-476 Signed-off-by: Aviral Nigam --- bindings/sysman/python/README.md | 2 + .../sysman/python/source/pyzes/__init__.py | 23 +++++ .../pyzes/examples/pyzes_black_box_test.py | 17 +++- .../test/unit_tests/test_global_operations.py | 87 +++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/bindings/sysman/python/README.md b/bindings/sysman/python/README.md index 9ce7df96..949ac751 100644 --- a/bindings/sysman/python/README.md +++ b/bindings/sysman/python/README.md @@ -177,6 +177,8 @@ The Linux Dependencies and Windows Dependencies columns list the external librar | `zesDriverGetDeviceByUuidExp` | Device | 0.1.0 | Experimental API | None | None | | `zesDeviceGetSubDevicePropertiesExp` | Device | 0.1.0 | Experimental API | None | None | | `zesDeviceProcessesGetState` | Device | 0.1.0 | None | None | None | +| `zes_device_index_ext_properties_t` | Device | 0.1.5 | None | None | None | +| `zes_device_gpu_topology_ext_properties_t` | Device | 0.1.5 | None | None | None | | **Driver Management** |-|-|-|-|-| | `zesDriverGetProperties` | Driver | 0.1.4 | None | None | None | | `zesDriverGetExtensionProperties` | Driver | 0.1.4 | None | None | None | diff --git a/bindings/sysman/python/source/pyzes/__init__.py b/bindings/sysman/python/source/pyzes/__init__.py index 823f73f3..3d2df2cf 100644 --- a/bindings/sysman/python/source/pyzes/__init__.py +++ b/bindings/sysman/python/source/pyzes/__init__.py @@ -509,6 +509,8 @@ class zes_firmware_handle_t(c_void_p): ZES_STRUCTURE_TYPE_INFO_LOG_READ_STATUS_EXT = 0x00020023 ZES_STRUCTURE_TYPE_DRIVER_PROPERTIES = 0x2F ZES_STRUCTURE_TYPE_FIRMWARE_PROPERTIES = 0x8 +ZES_STRUCTURE_TYPE_DEVICE_INDEX_EXT_PROPERTIES = 0x00020026 +ZES_STRUCTURE_TYPE_DEVICE_GPU_TOPOLOGY_EXT_PROPERTIES = 0x00020027 ## Core ze_device UUID struct ## @@ -743,6 +745,27 @@ class zes_subdevice_exp_properties_t(_PrintableStructure): ] +class zes_device_index_ext_properties_t(_PrintableStructure): + _fields_ = [ + ("stype", c_int32), + ("pNext", c_void_p), + ("deviceIndex", c_uint32), + ] + + +class zes_device_gpu_topology_ext_properties_t(_PrintableStructure): + _fields_ = [ + ("stype", c_int32), + ("pNext", c_void_p), + ("numSlices", c_uint32), + ("numXeCores", c_uint32), + ("numVectorEngines", c_uint32), + ("numMatrixEngines", c_uint32), + ("numThreads", c_uint32), + ("generationName", c_char * ZES_STRING_PROPERTY_SIZE), + ] + + ## Memory structures ## class zes_mem_properties_t(_PrintableStructure): _fields_ = [ diff --git a/bindings/sysman/python/source/pyzes/examples/pyzes_black_box_test.py b/bindings/sysman/python/source/pyzes/examples/pyzes_black_box_test.py index 1748a9a8..80233ce4 100755 --- a/bindings/sysman/python/source/pyzes/examples/pyzes_black_box_test.py +++ b/bindings/sysman/python/source/pyzes/examples/pyzes_black_box_test.py @@ -580,7 +580,13 @@ def test_global_operation(driver_handle, device_handle, device_index): # Initialize properties structure properties = pz.zes_device_properties_t() properties.stype = pz.ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES - properties.pNext = None + index_properties = pz.zes_device_index_ext_properties_t() + index_properties.stype = pz.ZES_STRUCTURE_TYPE_DEVICE_INDEX_EXT_PROPERTIES + topology_properties = pz.zes_device_gpu_topology_ext_properties_t() + topology_properties.stype = pz.ZES_STRUCTURE_TYPE_DEVICE_GPU_TOPOLOGY_EXT_PROPERTIES + topology_properties.pNext = None + index_properties.pNext = cast(pointer(topology_properties), c_void_p) + properties.pNext = cast(pointer(index_properties), c_void_p) rc = pz.zesDeviceGetProperties(device_handle, byref(properties)) if not check_rc(f"zesDeviceGetProperties(device {device_index})", rc): @@ -615,6 +621,15 @@ def test_global_operation(driver_handle, device_handle, device_index): ) print_verbose(f" Vendor ID: 0x{properties.core.vendorId:04X}") print_verbose(f" Device ID: 0x{properties.core.deviceId:04X}") + print_verbose(f" Device Index: {index_properties.deviceIndex}") + print_verbose(f" Slices: {topology_properties.numSlices}") + print_verbose(f" Xe Cores: {topology_properties.numXeCores}") + print_verbose(f" Vector Engines: {topology_properties.numVectorEngines}") + print_verbose(f" Matrix Engines: {topology_properties.numMatrixEngines}") + print_verbose(f" Threads: {topology_properties.numThreads}") + print_verbose( + f" Generation Name: {topology_properties.generationName.decode('utf-8', errors='ignore')}" + ) # Test Subdevice Properties (Experimental API) print_verbose("\n=== Subdevice Properties Test (Experimental) ===") diff --git a/bindings/sysman/python/test/unit_tests/test_global_operations.py b/bindings/sysman/python/test/unit_tests/test_global_operations.py index c0c71231..3f4c5c7b 100644 --- a/bindings/sysman/python/test/unit_tests/test_global_operations.py +++ b/bindings/sysman/python/test/unit_tests/test_global_operations.py @@ -101,6 +101,93 @@ def mock_get_properties(device_handle, properties_ptr): mock_get_func.assert_called_with("zesDeviceGetProperties") mock_func.assert_called_once() + def test_GivenDeviceIndexExtPropertiesInChainWhenCallingZesDeviceGetPropertiesThenDeviceIndexIsReturned( + self, mock_get_func + ): + mock_device_index = 1 + + def mock_get_properties(device_handle, properties_ptr): + index_props = cast( + properties_ptr._obj.pNext, + POINTER(self.pyzes.zes_device_index_ext_properties_t), + ).contents + self.assertEqual( + index_props.stype, + self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_INDEX_EXT_PROPERTIES, + ) + index_props.deviceIndex = mock_device_index + return self.pyzes.ZE_RESULT_SUCCESS + + mock_func = MagicMock(side_effect=mock_get_properties) + mock_get_func.return_value = mock_func + + device_handle = self.pyzes.zes_device_handle_t() + index_props = self.pyzes.zes_device_index_ext_properties_t() + index_props.stype = self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_INDEX_EXT_PROPERTIES + index_props.pNext = None + device_props = self.pyzes.zes_device_properties_t() + device_props.stype = self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES + device_props.pNext = cast(pointer(index_props), c_void_p) + + result = self.pyzes.zesDeviceGetProperties(device_handle, byref(device_props)) + + self.assertEqual(result, self.pyzes.ZE_RESULT_SUCCESS) + self.assertEqual(index_props.deviceIndex, mock_device_index) + mock_get_func.assert_called_with("zesDeviceGetProperties") + mock_func.assert_called_once() + + def test_GivenGpuTopologyExtPropertiesInChainWhenCallingZesDeviceGetPropertiesThenGpuTopologyIsReturned( + self, mock_get_func + ): + mock_num_slices = 1 + mock_num_xe_cores = 20 + mock_num_vector_engines = 160 + mock_num_matrix_engines = 160 + mock_num_threads = 1280 + mock_generation_name = b"xe2" + + def mock_get_properties(device_handle, properties_ptr): + topology_props = cast( + properties_ptr._obj.pNext, + POINTER(self.pyzes.zes_device_gpu_topology_ext_properties_t), + ).contents + self.assertEqual( + topology_props.stype, + self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_GPU_TOPOLOGY_EXT_PROPERTIES, + ) + topology_props.numSlices = mock_num_slices + topology_props.numXeCores = mock_num_xe_cores + topology_props.numVectorEngines = mock_num_vector_engines + topology_props.numMatrixEngines = mock_num_matrix_engines + topology_props.numThreads = mock_num_threads + topology_props.generationName = mock_generation_name + return self.pyzes.ZE_RESULT_SUCCESS + + mock_func = MagicMock(side_effect=mock_get_properties) + mock_get_func.return_value = mock_func + + device_handle = self.pyzes.zes_device_handle_t() + topology_props = self.pyzes.zes_device_gpu_topology_ext_properties_t() + topology_props.stype = ( + self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_GPU_TOPOLOGY_EXT_PROPERTIES + ) + topology_props.pNext = None + device_props = self.pyzes.zes_device_properties_t() + device_props.stype = self.pyzes.ZES_STRUCTURE_TYPE_DEVICE_PROPERTIES + device_props.pNext = cast(pointer(topology_props), c_void_p) + + result = self.pyzes.zesDeviceGetProperties(device_handle, byref(device_props)) + + self.assertEqual(result, self.pyzes.ZE_RESULT_SUCCESS) + self.assertEqual(topology_props.numSlices, mock_num_slices) + self.assertEqual(topology_props.numXeCores, mock_num_xe_cores) + self.assertEqual(topology_props.numVectorEngines, mock_num_vector_engines) + self.assertEqual(topology_props.numMatrixEngines, mock_num_matrix_engines) + self.assertEqual(topology_props.numThreads, mock_num_threads) + self.assertEqual(topology_props.generationName, mock_generation_name) + mock_get_func.assert_called_with("zesDeviceGetProperties") + mock_func.assert_called_once() + def test_GivenValidDeviceHandleWhenCallingZesDevicePciGetPropertiesThenCallSucceedsWithValidProperties( self, mock_get_func ):