From c5a97b05200d6e352a270d86ce324e17e4157210 Mon Sep 17 00:00:00 2001 From: Vishnu Khanth Date: Tue, 25 Mar 2025 05:45:16 +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 --- .../memory/windows/sysman_os_memory_imp.cpp | 55 +++++++++---- .../api/memory/windows/sysman_os_memory_imp.h | 2 +- .../sources/memory/windows/mock_memory.h | 7 +- .../memory/windows/test_zes_memory.cpp | 79 ++++++++++++++++++- .../test/black_box_tests/zello_sysman.cpp | 12 +++ 5 files changed, 138 insertions(+), 17 deletions(-) diff --git a/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.cpp b/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.cpp index 86aba0d648..e4e79f6756 100644 --- a/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.cpp +++ b/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -12,6 +12,8 @@ #include "level_zero/sysman/source/shared/windows/product_helper/sysman_product_helper.h" #include "level_zero/sysman/source/shared/windows/sysman_kmd_sys_manager.h" +#include + namespace L0 { namespace Sysman { @@ -54,6 +56,8 @@ bool WddmMemoryImp::isMemoryModuleSupported() { KmdSysman::RequestProperty request; KmdSysman::ResponseProperty response; + bool isIntegratedDevice = pWddmSysmanImp->getHardwareInfo().capabilityTable.isIntegratedDevice; + request.commandId = KmdSysman::Command::Get; request.componentId = KmdSysman::Component::MemoryComponent; request.requestId = KmdSysman::Requests::Memory::NumMemoryDomains; @@ -64,6 +68,10 @@ bool WddmMemoryImp::isMemoryModuleSupported() { memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + if (!value && isIntegratedDevice) { + return true; + } + return (value > 0); } @@ -76,6 +84,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->location = ZES_MEM_LOC_FORCE_UINT32; + pProperties->busWidth = -1; + + bool isIntegratedDevice = pWddmSysmanImp->getHardwareInfo().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; @@ -101,7 +124,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) { @@ -147,33 +169,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; } @@ -194,14 +209,21 @@ ze_result_t WddmMemoryImp::getState(zes_mem_state_t *pState) { request.componentId = KmdSysman::Component::MemoryComponent; request.requestId = KmdSysman::Requests::Memory::CurrentTotalAllocableMem; + bool isIntegratedDevice = pWddmSysmanImp->getHardwareInfo().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) { @@ -210,14 +232,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/sysman/source/api/memory/windows/sysman_os_memory_imp.h b/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.h index 486d7e8f47..623b425039 100644 --- a/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.h +++ b/level_zero/sysman/source/api/memory/windows/sysman_os_memory_imp.h @@ -48,7 +48,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/sysman/test/unit_tests/sources/memory/windows/mock_memory.h b/level_zero/sysman/test/unit_tests/sources/memory/windows/mock_memory.h index 97ef71dff8..267cb39a98 100644 --- a/level_zero/sysman/test/unit_tests/sources/memory/windows/mock_memory.h +++ b/level_zero/sysman/test/unit_tests/sources/memory/windows/mock_memory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -186,6 +186,11 @@ class SysmanDeviceMemoryFixture : public SysmanDeviceFixture { pSysmanDeviceImp->pMemoryHandleContext->init(pOsSysman->getSubDeviceCount()); } + void clearMemHandleListAndReinit() { + pSysmanDeviceImp->pMemoryHandleContext->handleList.clear(); + pSysmanDeviceImp->pMemoryHandleContext->init(pOsSysman->getSubDeviceCount()); + } + std::vector getMemoryHandles(uint32_t count) { std::vector handles(count, nullptr); EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); diff --git a/level_zero/sysman/test/unit_tests/sources/memory/windows/test_zes_memory.cpp b/level_zero/sysman/test/unit_tests/sources/memory/windows/test_zes_memory.cpp index 25c784e065..764c6a5cf7 100644 --- a/level_zero/sysman/test/unit_tests/sources/memory/windows/test_zes_memory.cpp +++ b/level_zero/sysman/test/unit_tests/sources/memory/windows/test_zes_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -75,6 +75,38 @@ TEST_F(SysmanDeviceMemoryFixture, DISABLED_GivenValidMemoryHandleWhenCallingGett } } +TEST_F(SysmanDeviceMemoryFixture, GivenValidMemoryHandleWhenCallingGettingPropertiesThenCallSucceeds) { + pKmdSysManager->mockMemoryDomains = 1; + clearMemHandleListAndReinit(); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 1u); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->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); @@ -122,6 +154,51 @@ TEST_F(SysmanDeviceMemoryFixture, GivenValidOsMemoryObjectWhenGettingMemoryBandW EXPECT_EQ(mockMemoryBandwidthTimestamp, bandwidth.timestamp); } +TEST_F(SysmanDeviceMemoryFixture, GivenMockedComponentCountZeroWhenEnumeratingMemoryModulesThenExpectNonZeroCountAndValidHandlesForIntegratedPlatforms) { + pKmdSysManager->mockMemoryDomains = 0; + clearMemHandleListAndReinit(); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + + if (defaultHwInfo->capabilityTable.isIntegratedDevice) { + EXPECT_EQ(count, 1u); + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->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(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + + if (defaultHwInfo->capabilityTable.isIntegratedDevice) { + EXPECT_EQ(count, 1u); + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->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 Sysman } // namespace L0 diff --git a/level_zero/tools/test/black_box_tests/zello_sysman.cpp b/level_zero/tools/test/black_box_tests/zello_sysman.cpp index 05b208df01..0cef9a3f15 100644 --- a/level_zero/tools/test/black_box_tests/zello_sysman.cpp +++ b/level_zero/tools/test/black_box_tests/zello_sysman.cpp @@ -1078,6 +1078,16 @@ std::string getMemoryHealth(zes_mem_health_t memHealth) { return mgetMemoryHealth.at(memHealth); } +std::string getMemoryLocation(zes_mem_loc_t memLocation) { + if (memLocation == ZES_MEM_LOC_DEVICE) { + return "ZES_MEM_LOC_DEVICE"; + } else if (memLocation == ZES_MEM_LOC_SYSTEM) { + return "ZES_MEM_LOC_SYSTEM"; + } else { + return "NOT SUPPORTED MEMORY LOCATION SET"; + } +} + void testSysmanMemory(ze_device_handle_t &device) { std::cout << std::endl << " ---- Memory tests ---- " << std::endl; @@ -1100,8 +1110,10 @@ void testSysmanMemory(ze_device_handle_t &device) { std::cout << "Memory Type = " << getMemoryType(memoryProperties.type) << std::endl; std::cout << "On Subdevice = " << static_cast(memoryProperties.onSubdevice) << std::endl; std::cout << "Subdevice Id = " << memoryProperties.subdeviceId << std::endl; + std::cout << "Memory Location = " << getMemoryLocation(memoryProperties.location) << std::endl; std::cout << "Memory Size = " << memoryProperties.physicalSize << std::endl; std::cout << "Number of channels = " << memoryProperties.numChannels << std::endl; + std::cout << "Memory busWidth = " << memoryProperties.busWidth << std::endl; } VALIDATECALL(zesMemoryGetState(handle, &memoryState));