From 41ef309ccfc1e888432077c65bb02c3f95620007 Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Thu, 8 May 2025 14:26:22 +0000 Subject: [PATCH] performance: cache devices to expose via zeDeviceGet API call vector with all device handles is initialized only once, during driver init Signed-off-by: Mateusz Jablonski --- .../core/source/driver/driver_handle_imp.cpp | 63 +++++++++---------- .../core/source/driver/driver_handle_imp.h | 1 + .../unit_tests/sources/driver/test_driver.cpp | 1 + .../unit_tests/sources/event/test_event.cpp | 1 + 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index fb378397b3..08b6b558db 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -323,15 +323,12 @@ ze_result_t DriverHandleImp::initialize(std::vector } } - uint32_t numDevicesToExpose = 0u; - this->getDevice(&numDevicesToExpose, nullptr); - this->devicesToExpose.resize(numDevicesToExpose); - this->getDevice(&numDevicesToExpose, this->devicesToExpose.data()); + setupDevicesToExpose(); uint32_t deviceIdentifier = 0u; for (auto &deviceToExpose : this->devicesToExpose) { Device::fromHandle(deviceToExpose)->setIdentifier(deviceIdentifier++); } - createContext(&DefaultDescriptors::contextDesc, numDevicesToExpose, this->devicesToExpose.data(), &defaultContext); + createContext(&DefaultDescriptors::contextDesc, static_cast(this->devicesToExpose.size()), this->devicesToExpose.data(), &defaultContext); return ZE_RESULT_SUCCESS; } @@ -396,7 +393,7 @@ void DriverHandleImp::initDeviceUsmAllocPool(NEO::Device &device) { } } -ze_result_t DriverHandleImp::getDevice(uint32_t *pCount, ze_device_handle_t *phDevices) { +void DriverHandleImp::setupDevicesToExpose() { // If the user has requested FLAT or COMBINED device hierarchy model, then report all the sub devices as devices. bool exposeSubDevices = (this->devices.size() && this->devices[0]->getNEODevice()->getExecutionEnvironment()->getDeviceHierarchyMode() != NEO::DeviceHierarchyMode::composite); @@ -416,6 +413,30 @@ ze_result_t DriverHandleImp::getDevice(uint32_t *pCount, ze_device_handle_t *phD } else { numDevices = this->numDevices; } + this->devicesToExpose.clear(); + this->devicesToExpose.reserve(numDevices); + + for (auto device : devices) { + + auto deviceImpl = static_cast(device); + if (deviceImpl->numSubDevices > 0 && exposeSubDevices) { + + if (device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->isExposeSingleDeviceMode()) { + this->devicesToExpose.push_back(device); + continue; + } + + for (auto subdevice : deviceImpl->subDevices) { + this->devicesToExpose.push_back(subdevice); + } + } else { + this->devicesToExpose.push_back(device); + } + } +} + +ze_result_t DriverHandleImp::getDevice(uint32_t *pCount, ze_device_handle_t *phDevices) { + uint32_t numDevices = static_cast(this->devicesToExpose.size()); if (*pCount == 0) { *pCount = numDevices; return ZE_RESULT_SUCCESS; @@ -425,35 +446,11 @@ ze_result_t DriverHandleImp::getDevice(uint32_t *pCount, ze_device_handle_t *phD return ZE_RESULT_ERROR_INVALID_NULL_HANDLE; } - uint32_t i = 0; - for (auto device : devices) { + auto numDevicesToReturn = std::min(numDevices, *pCount); - auto deviceImpl = static_cast(device); - if (deviceImpl->numSubDevices > 0 && exposeSubDevices) { + memcpy_s(phDevices, numDevicesToReturn * sizeof(ze_device_handle_t), this->devicesToExpose.data(), numDevicesToReturn * sizeof(ze_device_handle_t)); - if (device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->isExposeSingleDeviceMode()) { - phDevices[i++] = device; - if (i == *pCount) { - return ZE_RESULT_SUCCESS; - } - continue; - } - - for (auto subdevice : deviceImpl->subDevices) { - phDevices[i++] = subdevice; - if (i == *pCount) { - return ZE_RESULT_SUCCESS; - } - } - } else { - phDevices[i++] = device; - if (i == *pCount) { - return ZE_RESULT_SUCCESS; - } - } - } - - *pCount = numDevices; + *pCount = numDevicesToReturn; return ZE_RESULT_SUCCESS; } diff --git a/level_zero/core/source/driver/driver_handle_imp.h b/level_zero/core/source/driver/driver_handle_imp.h index 8007659e87..2a56a32ed7 100644 --- a/level_zero/core/source/driver/driver_handle_imp.h +++ b/level_zero/core/source/driver/driver_handle_imp.h @@ -182,6 +182,7 @@ struct DriverHandleImp : public DriverHandle { ze_context_handle_t getDefaultContext() const override { return defaultContext; } + void setupDevicesToExpose(); protected: NEO::GraphicsAllocation *getPeerAllocation(Device *device, diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index 858d49e355..3c6a550068 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -1005,6 +1005,7 @@ TEST_F(DriverHandleTest, givenInitializedDriverWithTwoDevicesWhenGetDeviceIsCall auto newNeoDevice = L0::Device::create(driverHandleImp, std::move(testNeoDevice), false, &result); driverHandleImp->devices.push_back(newNeoDevice); driverHandleImp->numDevices++; + driverHandleImp->setupDevicesToExpose(); uint32_t count = 0U; result = driverHandle->getDevice(&count, nullptr); diff --git a/level_zero/core/test/unit_tests/sources/event/test_event.cpp b/level_zero/core/test/unit_tests/sources/event/test_event.cpp index fc8838b97b..4ab848e7b4 100644 --- a/level_zero/core/test/unit_tests/sources/event/test_event.cpp +++ b/level_zero/core/test/unit_tests/sources/event/test_event.cpp @@ -3126,6 +3126,7 @@ TEST_F(EventPoolCreateMultiDeviceFlatHierarchy, givenFlatHierarchyWhenCallZeGetD } static_cast(driverHandle->devices[1])->numSubDevices = 0; + driverHandle->setupDevicesToExpose(); uint32_t deviceCount2 = 0; result = zeDeviceGet(driverHandle.get(), &deviceCount2, nullptr); EXPECT_EQ(ZE_RESULT_SUCCESS, result);