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-03-25 05:45:16 +00:00 committed by Compute-Runtime-Automation
parent c1df81c9be
commit c5a97b0520
5 changed files with 138 additions and 17 deletions

View File

@ -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 <Windows.h>
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<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;
}
@ -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;
}

View File

@ -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;
};

View File

@ -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<zes_mem_handle_t> getMemoryHandles(uint32_t count) {
std::vector<zes_mem_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumMemoryModules(pSysmanDevice->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);

View File

@ -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<zes_mem_handle_t> 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<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);
@ -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<zes_mem_handle_t> 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<zes_mem_handle_t> 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

View File

@ -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<uint32_t>(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));