feature(sysman): Add support for Memory properties & state for iGPU's in Windows

Related-To: NEO-14197

Signed-off-by: Vishnu Khanth <vishnu.khanth.b@intel.com>
This commit is contained in:
Vishnu Khanth
2025-04-28 08:14:53 +00:00
committed by Compute-Runtime-Automation
parent 75e313ce28
commit 8668744f71
3 changed files with 135 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -7,11 +7,14 @@
#include "level_zero/tools/source/sysman/memory/windows/os_memory_imp.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "level_zero/tools/source/sysman/sysman.h"
#include "level_zero/tools/source/sysman/windows/kmd_sys_manager.h"
#include <Windows.h>
template <typename I>
std::string intToHex(I w, size_t hexLength = sizeof(I) << 1) {
static const char *digits = "0123456789ABCDEF";
@@ -47,6 +50,8 @@ bool WddmMemoryImp::isMemoryModuleSupported() {
KmdSysman::RequestProperty request;
KmdSysman::ResponseProperty response;
bool isIntegratedDevice = pDevice->getHwInfo().capabilityTable.isIntegratedDevice;
request.commandId = KmdSysman::Command::Get;
request.componentId = KmdSysman::Component::MemoryComponent;
request.requestId = KmdSysman::Requests::Memory::NumMemoryDomains;
@@ -57,6 +62,10 @@ bool WddmMemoryImp::isMemoryModuleSupported() {
memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
if (!value && isIntegratedDevice) {
return true;
}
return (value > 0);
}
ze_result_t WddmMemoryImp::getProperties(zes_mem_properties_t *pProperties) {
@@ -68,6 +77,21 @@ ze_result_t WddmMemoryImp::getProperties(zes_mem_properties_t *pProperties) {
pProperties->onSubdevice = isSubdevice;
pProperties->subdeviceId = subdeviceId;
pProperties->type = ZES_MEM_TYPE_FORCE_UINT32;
pProperties->physicalSize = 0;
pProperties->numChannels = -1;
pProperties->busWidth = -1;
pProperties->location = ZES_MEM_LOC_FORCE_UINT32;
bool isIntegratedDevice = pDevice->getHwInfo().capabilityTable.isIntegratedDevice;
if (isIntegratedDevice) {
pProperties->location = ZES_MEM_LOC_SYSTEM;
ULONGLONG installedMemoryKb = 0;
if (GetPhysicallyInstalledSystemMemory(&installedMemoryKb)) {
pProperties->physicalSize = installedMemoryKb * 1024;
}
return ZE_RESULT_SUCCESS;
}
request.commandId = KmdSysman::Command::Get;
request.componentId = KmdSysman::Component::MemoryComponent;
@@ -93,7 +117,6 @@ ze_result_t WddmMemoryImp::getProperties(zes_mem_properties_t *pProperties) {
return status;
}
pProperties->type = ZES_MEM_TYPE_FORCE_UINT32;
if (vResponses[0].returnCode == KmdSysman::Success) {
memcpy_s(&retValu32, sizeof(uint32_t), vResponses[0].dataBuffer, sizeof(uint32_t));
switch (retValu32) {
@@ -139,33 +162,26 @@ ze_result_t WddmMemoryImp::getProperties(zes_mem_properties_t *pProperties) {
}
}
pProperties->physicalSize = 0;
if (vResponses[1].returnCode == KmdSysman::Success) {
memcpy_s(&retValu64, sizeof(uint64_t), vResponses[1].dataBuffer, sizeof(uint64_t));
pProperties->physicalSize = retValu64;
}
pProperties->numChannels = -1;
if (vResponses[2].returnCode == KmdSysman::Success) {
memcpy_s(&retValu32, sizeof(uint32_t), vResponses[2].dataBuffer, sizeof(uint32_t));
pProperties->numChannels = retValu32;
}
pProperties->location = ZES_MEM_LOC_FORCE_UINT32;
if (vResponses[3].returnCode == KmdSysman::Success) {
memcpy_s(&retValu32, sizeof(uint32_t), vResponses[3].dataBuffer, sizeof(uint32_t));
pProperties->location = static_cast<zes_mem_loc_t>(retValu32);
}
pProperties->busWidth = -1;
if (vResponses[4].returnCode == KmdSysman::Success) {
memcpy_s(&retValu32, sizeof(uint32_t), vResponses[4].dataBuffer, sizeof(uint32_t));
pProperties->busWidth = retValu32;
}
pProperties->subdeviceId = 0;
pProperties->onSubdevice = false;
return ZE_RESULT_SUCCESS;
}
@@ -229,14 +245,21 @@ ze_result_t WddmMemoryImp::getState(zes_mem_state_t *pState) {
request.componentId = KmdSysman::Component::MemoryComponent;
request.requestId = KmdSysman::Requests::Memory::CurrentTotalAllocableMem;
bool isIntegratedDevice = pDevice->getHwInfo().capabilityTable.isIntegratedDevice;
status = pKmdSysManager->requestSingle(request, response);
if (status != ZE_RESULT_SUCCESS) {
if (status != ZE_RESULT_SUCCESS && !isIntegratedDevice) {
return status;
}
memcpy_s(&retValu64, sizeof(uint64_t), response.dataBuffer, sizeof(uint64_t));
pState->size = retValu64;
if (isIntegratedDevice && pKmdSysManager->GetWddmAccess()) {
pState->size = pKmdSysManager->GetWddmAccess()->getSystemSharedMemory();
} else {
pState->size = retValu64;
}
if (!pdhInitialized) {
if (pdhOpenQuery && pdhOpenQuery(NULL, NULL, &gpuQuery) == ERROR_SUCCESS) {
@@ -245,14 +268,19 @@ ze_result_t WddmMemoryImp::getState(zes_mem_state_t *pState) {
}
if (!pdhCounterAdded && pdhAddEnglishCounterW && pKmdSysManager->GetWddmAccess()) {
std::wstring counterStr = constructCounterStr(L"GPU Adapter Memory", L"Dedicated Usage", pKmdSysManager->GetWddmAccess()->getAdapterLuid(), 0);
pdhCounterAdded = (pdhAddEnglishCounterW(gpuQuery, counterStr.c_str(), NULL, &dedicatedUsage) == ERROR_SUCCESS);
if (isIntegratedDevice) {
std::wstring counterStr = constructCounterStr(L"GPU Adapter Memory", L"Shared Usage", pKmdSysManager->GetWddmAccess()->getAdapterLuid(), 0);
pdhCounterAdded = (pdhAddEnglishCounterW(gpuQuery, counterStr.c_str(), NULL, &usage) == ERROR_SUCCESS);
} else {
std::wstring counterStr = constructCounterStr(L"GPU Adapter Memory", L"Dedicated Usage", pKmdSysManager->GetWddmAccess()->getAdapterLuid(), 0);
pdhCounterAdded = (pdhAddEnglishCounterW(gpuQuery, counterStr.c_str(), NULL, &usage) == ERROR_SUCCESS);
}
}
if (pdhCounterAdded && pdhCollectQueryData && pdhGetFormattedCounterValue) {
PDH_FMT_COUNTERVALUE counterVal;
pdhCollectQueryData(gpuQuery);
pdhGetFormattedCounterValue(dedicatedUsage, PDH_FMT_LARGE, NULL, &counterVal);
pdhGetFormattedCounterValue(usage, PDH_FMT_LARGE, NULL, &counterVal);
retValu64 = counterVal.largeValue;
pState->free = pState->size - retValu64;
}

View File

@@ -61,7 +61,7 @@ class WddmMemoryImp : public OsMemory, NEO::NonCopyableAndNonMovableClass {
bool pdhInitialized = false;
bool pdhCounterAdded = false;
PDH_HQUERY gpuQuery = nullptr;
PDH_HCOUNTER dedicatedUsage = nullptr;
PDH_HCOUNTER usage = nullptr;
HINSTANCE hGetProcPDH = nullptr;
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -72,6 +72,20 @@ class SysmanDeviceMemoryFixture : public SysmanDeviceFixture {
pSysmanDeviceImp->pMemoryHandleContext->init(deviceHandles);
}
void clearMemHandleListAndReinit() {
pSysmanDeviceImp->pMemoryHandleContext->handleList.clear();
uint32_t subDeviceCount = 0;
std::vector<ze_device_handle_t> deviceHandles{};
device->getSubDevices(&subDeviceCount, nullptr);
if (subDeviceCount == 0) {
deviceHandles.resize(1, device->toHandle());
} else {
deviceHandles.resize(subDeviceCount, nullptr);
device->getSubDevices(&subDeviceCount, deviceHandles.data());
}
pSysmanDeviceImp->pMemoryHandleContext->init(deviceHandles);
}
std::vector<zes_mem_handle_t> getMemoryHandles(uint32_t count) {
std::vector<zes_mem_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
@@ -145,6 +159,38 @@ TEST_F(SysmanDeviceMemoryFixture, DISABLED_GivenValidMemoryHandleWhenCallingGett
}
}
TEST_F(SysmanDeviceMemoryFixture, GivenValidMemoryHandleWhenCallingGettingPropertiesThenCallSucceeds) {
pKmdSysManager->mockMemoryDomains = 1;
clearMemHandleListAndReinit();
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, 1u);
std::vector<zes_mem_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
for (auto handle : handles) {
EXPECT_NE(handle, nullptr);
zes_mem_properties_t properties{};
EXPECT_EQ(zesMemoryGetProperties(handle, &properties), ZE_RESULT_SUCCESS);
EXPECT_FALSE(properties.onSubdevice);
EXPECT_EQ(properties.subdeviceId, 0u);
if (defaultHwInfo->capabilityTable.isIntegratedDevice) {
EXPECT_EQ(properties.location, ZES_MEM_LOC_SYSTEM);
EXPECT_GT(properties.physicalSize, 0u);
EXPECT_EQ(properties.numChannels, -1);
EXPECT_EQ(properties.busWidth, -1);
} else {
EXPECT_EQ(properties.type, ZES_MEM_TYPE_GDDR6);
EXPECT_EQ(properties.location, ZES_MEM_LOC_DEVICE);
EXPECT_EQ(properties.physicalSize, pKmdSysManager->mockMemoryPhysicalSize);
EXPECT_EQ(static_cast<uint32_t>(properties.numChannels), pKmdSysManager->mockMemoryChannels);
EXPECT_EQ(static_cast<uint32_t>(properties.busWidth), pKmdSysManager->mockMemoryBus);
}
}
}
TEST_F(SysmanDeviceMemoryFixture, DISABLED_GivenValidMemoryHandleWhenGettingStateThenCallSucceeds) {
setLocalSupportedAndReinit(true);
auto handles = getMemoryHandles(memoryHandleComponentCount);
@@ -193,5 +239,50 @@ TEST_F(SysmanDeviceMemoryFixture, DISABLED_GivenValidMemoryHandleWhenGettingBand
}
}
TEST_F(SysmanDeviceMemoryFixture, GivenMockedComponentCountZeroWhenEnumeratingMemoryModulesThenExpectNonZeroCountAndValidHandlesForIntegratedPlatforms) {
pKmdSysManager->mockMemoryDomains = 0;
clearMemHandleListAndReinit();
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
if (defaultHwInfo->capabilityTable.isIntegratedDevice) {
EXPECT_EQ(count, 1u);
std::vector<zes_mem_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
for (auto handle : handles) {
EXPECT_NE(handle, nullptr);
}
} else {
EXPECT_EQ(count, 0u);
}
}
TEST_F(SysmanDeviceMemoryFixture, GivenMockedComponentCountZeroWhenEnumeratingMemoryModulesThenExpectNonZeroCountAndValidPropertiesForIntegratedPlatforms) {
pKmdSysManager->mockMemoryDomains = 0;
clearMemHandleListAndReinit();
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
if (defaultHwInfo->capabilityTable.isIntegratedDevice) {
EXPECT_EQ(count, 1u);
std::vector<zes_mem_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumMemoryModules(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
for (auto handle : handles) {
EXPECT_NE(handle, nullptr);
zes_mem_properties_t properties{};
EXPECT_EQ(zesMemoryGetProperties(handle, &properties), ZE_RESULT_SUCCESS);
EXPECT_EQ(properties.location, ZES_MEM_LOC_SYSTEM);
EXPECT_FALSE(properties.onSubdevice);
EXPECT_EQ(properties.subdeviceId, 0u);
EXPECT_GT(properties.physicalSize, 0u);
}
} else {
EXPECT_EQ(count, 0u);
}
}
} // namespace ult
} // namespace L0