From 8668744f719f72a8c3a16937a6da26b25a902321 Mon Sep 17 00:00:00 2001 From: Vishnu Khanth Date: Mon, 28 Apr 2025 08:14:53 +0000 Subject: [PATCH] feature(sysman): Add support for Memory properties & state for iGPU's in Windows Related-To: NEO-14197 Signed-off-by: Vishnu Khanth --- .../sysman/memory/windows/os_memory_imp.cpp | 56 ++++++++--- .../sysman/memory/windows/os_memory_imp.h | 2 +- .../sysman/memory/windows/test_zes_memory.cpp | 93 ++++++++++++++++++- 3 files changed, 135 insertions(+), 16 deletions(-) diff --git a/level_zero/tools/source/sysman/memory/windows/os_memory_imp.cpp b/level_zero/tools/source/sysman/memory/windows/os_memory_imp.cpp index 7312e4f379..889d510cb9 100644 --- a/level_zero/tools/source/sysman/memory/windows/os_memory_imp.cpp +++ b/level_zero/tools/source/sysman/memory/windows/os_memory_imp.cpp @@ -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 + template 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(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; } diff --git a/level_zero/tools/source/sysman/memory/windows/os_memory_imp.h b/level_zero/tools/source/sysman/memory/windows/os_memory_imp.h index f152e1d97f..87bff7074f 100644 --- a/level_zero/tools/source/sysman/memory/windows/os_memory_imp.h +++ b/level_zero/tools/source/sysman/memory/windows/os_memory_imp.h @@ -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; }; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/memory/windows/test_zes_memory.cpp b/level_zero/tools/test/unit_tests/sources/sysman/memory/windows/test_zes_memory.cpp index 8c20b4debf..abb6b997ef 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/memory/windows/test_zes_memory.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/memory/windows/test_zes_memory.cpp @@ -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 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 getMemoryHandles(uint32_t count) { std::vector 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 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(properties.numChannels), pKmdSysManager->mockMemoryChannels); + EXPECT_EQ(static_cast(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 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 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