From ac01d0224771d8d6e3eff9d6a6c8f410f7c52b5a Mon Sep 17 00:00:00 2001 From: Mayank Raghuwanshi Date: Fri, 12 May 2023 10:04:51 +0000 Subject: [PATCH] feature: Add support for frequency media domain for windows Related-To: LOCI-4287 Signed-off-by: Mayank Raghuwanshi --- .../linux/sysman_os_frequency_imp.cpp | 5 +- .../linux/sysman_os_frequency_imp_prelim.cpp | 5 +- .../source/frequency/sysman_frequency.cpp | 6 +- .../source/frequency/sysman_os_frequency.h | 2 +- .../windows/sysman_os_frequency_imp.cpp | 19 +-- .../sysman/source/windows/sysman_kmd_sys.h | 2 + .../frequency/windows/mock_frequency.h | 119 +++++++++++++----- .../frequency/windows/test_zes_frequency.cpp | 43 ++++++- .../source/sysman/frequency/frequency.cpp | 7 +- .../frequency/linux/os_frequency_imp.cpp | 5 +- .../linux/os_frequency_imp_prelim.cpp | 5 +- .../source/sysman/frequency/os_frequency.h | 4 +- .../frequency/windows/os_frequency_imp.cpp | 20 +-- .../tools/source/sysman/windows/kmd_sys.h | 2 + .../sysman/frequency/windows/mock_frequency.h | 102 +++++++++++---- .../frequency/windows/test_zes_frequency.cpp | 57 ++++++++- 16 files changed, 314 insertions(+), 89 deletions(-) diff --git a/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp.cpp b/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp.cpp index a081425eb5..a1b8eb886d 100644 --- a/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp.cpp +++ b/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp.cpp @@ -424,8 +424,9 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pLinuxFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { - return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { + std::vector freqDomains = {ZES_FREQ_DOMAIN_GPU}; + return freqDomains; } } // namespace Sysman diff --git a/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp_prelim.cpp b/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp_prelim.cpp index 7622c3d0da..fd1da0d28f 100644 --- a/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp_prelim.cpp +++ b/level_zero/sysman/source/frequency/linux/sysman_os_frequency_imp_prelim.cpp @@ -429,8 +429,9 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pLinuxFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { - return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { + std::vector freqDomains = {ZES_FREQ_DOMAIN_GPU}; + return freqDomains; } } // namespace Sysman diff --git a/level_zero/sysman/source/frequency/sysman_frequency.cpp b/level_zero/sysman/source/frequency/sysman_frequency.cpp index ec673d2030..7d3b7a4e92 100644 --- a/level_zero/sysman/source/frequency/sysman_frequency.cpp +++ b/level_zero/sysman/source/frequency/sysman_frequency.cpp @@ -30,16 +30,16 @@ void FrequencyHandleContext::createHandle(ze_bool_t onSubdevice, uint32_t subdev ze_result_t FrequencyHandleContext::init(uint32_t subDeviceCount) { auto totalDomains = OsFrequency::getNumberOfFreqDomainsSupported(pOsSysman); - UNRECOVERABLE_IF(totalDomains > 2); + UNRECOVERABLE_IF(totalDomains.size() > 3); if (subDeviceCount == 0) { - for (uint32_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) { + for (const auto &frequencyDomain : totalDomains) { createHandle(false, 0, static_cast(frequencyDomain)); } } else { for (uint32_t subDeviceId = 0; subDeviceId < subDeviceCount; subDeviceId++) { - for (uint32_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) { + for (const auto &frequencyDomain : totalDomains) { createHandle(true, subDeviceId, static_cast(frequencyDomain)); } } diff --git a/level_zero/sysman/source/frequency/sysman_os_frequency.h b/level_zero/sysman/source/frequency/sysman_os_frequency.h index 41c79d100e..f94d6d77ce 100644 --- a/level_zero/sysman/source/frequency/sysman_os_frequency.h +++ b/level_zero/sysman/source/frequency/sysman_os_frequency.h @@ -32,7 +32,7 @@ class OsFrequency { virtual ze_result_t getOcTjMax(double *pOcTjMax) = 0; virtual ze_result_t setOcTjMax(double ocTjMax) = 0; static OsFrequency *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t type); - static uint16_t getNumberOfFreqDomainsSupported(OsSysman *pOsSysman); + static std::vector getNumberOfFreqDomainsSupported(OsSysman *pOsSysman); virtual ~OsFrequency() {} }; diff --git a/level_zero/sysman/source/frequency/windows/sysman_os_frequency_imp.cpp b/level_zero/sysman/source/frequency/windows/sysman_os_frequency_imp.cpp index 2bac0289b4..89ec8a6a6a 100644 --- a/level_zero/sysman/source/frequency/windows/sysman_os_frequency_imp.cpp +++ b/level_zero/sysman/source/frequency/windows/sysman_os_frequency_imp.cpp @@ -624,7 +624,7 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pWddmFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { WddmSysmanImp *pWddmSysmanImp = static_cast(pOsSysman); KmdSysManager *pKmdSysManager = &pWddmSysmanImp->getKmdSysManager(); @@ -633,18 +633,23 @@ uint16_t OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { request.commandId = KmdSysman::Command::Get; request.componentId = KmdSysman::Component::FrequencyComponent; - request.requestId = KmdSysman::Requests::Frequency::NumFrequencyDomains; + request.requestId = KmdSysman::Requests::Frequency::SupportedFreqDomains; ze_result_t status = pKmdSysManager->requestSingle(request, response); + std::vector freqDomains; if (status != ZE_RESULT_SUCCESS) { - return 0; + return freqDomains; } - uint32_t maxNumEnginesSupported = 0; - memcpy_s(&maxNumEnginesSupported, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); - - return static_cast(maxNumEnginesSupported); + uint32_t supportedFreqDomains = 0; + memcpy_s(&supportedFreqDomains, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + for (uint16_t i = ZES_FREQ_DOMAIN_GPU; i <= ZES_FREQ_DOMAIN_MEDIA; i++) { + if (supportedFreqDomains & 1 << i) { + freqDomains.push_back(static_cast(i)); + } + } + return freqDomains; } } // namespace Sysman diff --git a/level_zero/sysman/source/windows/sysman_kmd_sys.h b/level_zero/sysman/source/windows/sysman_kmd_sys.h index 8c1c9878f8..0e6ac3f042 100644 --- a/level_zero/sysman/source/windows/sysman_kmd_sys.h +++ b/level_zero/sysman/source/windows/sysman_kmd_sys.h @@ -216,6 +216,7 @@ enum Frequency { CurrentThrottleReasons, CurrentThrottleTime, CurrentFrequencyRange, + SupportedFreqDomains = 38, MaxFrequencyRequests, }; @@ -340,6 +341,7 @@ enum FlipType { enum GeneralDomainsType { GeneralDomainDGPU = 0, GeneralDomainHBM, + GeneralDomainMedia, GeneralDomainMaxTypes, }; diff --git a/level_zero/sysman/test/unit_tests/sources/frequency/windows/mock_frequency.h b/level_zero/sysman/test/unit_tests/sources/frequency/windows/mock_frequency.h index 78abecbd10..99c717693b 100644 --- a/level_zero/sysman/test/unit_tests/sources/frequency/windows/mock_frequency.h +++ b/level_zero/sysman/test/unit_tests/sources/frequency/windows/mock_frequency.h @@ -14,41 +14,42 @@ namespace L0 { namespace ult { struct MockFrequencyKmdSysManager : public MockKmdSysManager { - uint32_t mockNumberOfDomains = 2; - uint32_t mockDomainType[2] = {ZES_FREQ_DOMAIN_GPU, ZES_FREQ_DOMAIN_MEMORY}; - bool mockGPUCanControl[2] = {true, false}; - bool mockGPUCannotControl[2] = {false, false}; + uint32_t mockNumberOfDomains = 3; + uint32_t mockSupportedDomains = 7; + uint32_t mockDomainType[3] = {ZES_FREQ_DOMAIN_GPU, ZES_FREQ_DOMAIN_MEMORY, ZES_FREQ_DOMAIN_MEDIA}; + bool mockGPUCanControl[3] = {true, false, false}; + bool mockGPUCannotControl[3] = {false, false, false}; uint32_t mockMinFrequencyRange = 400; uint32_t mockMaxFrequencyRange = 1200; - uint32_t mockRpn[2] = {400, 0}; - uint32_t mockRp0[2] = {1200, 0}; + uint32_t mockRpn[3] = {400, 0, 400}; + uint32_t mockRp0[3] = {1200, 0, 1200}; uint32_t mockRequestedFrequency = 600; uint32_t mockTdpFrequency = 0; - uint32_t mockResolvedFrequency[2] = {600, 4200}; + uint32_t mockResolvedFrequency[3] = {600, 4200, 600}; uint32_t mockEfficientFrequency = 400; uint32_t mockCurrentVoltage = 1100; uint32_t mockThrottleReasons = 0; uint32_t mockIccMax = 1025; uint32_t mockTjMax = 105; - uint32_t mockIsExtendedModeSupported[2] = {0, 0}; - uint32_t mockIsFixedModeSupported[2] = {0, 0}; - uint32_t mockIsHighVoltModeCapable[2] = {0, 0}; - uint32_t mockIsHighVoltModeEnabled[2] = {0, 0}; + uint32_t mockIsExtendedModeSupported[3] = {0, 0, 0}; + uint32_t mockIsFixedModeSupported[3] = {0, 0, 0}; + uint32_t mockIsHighVoltModeCapable[3] = {0, 0, 0}; + uint32_t mockIsHighVoltModeEnabled[3] = {0, 0, 0}; uint32_t mockIsIccMaxSupported = 1; - uint32_t mockIsOcSupported[2] = {0, 0}; + uint32_t mockIsOcSupported[3] = {0, 0, 0}; uint32_t mockIsTjMaxSupported = 1; - uint32_t mockMaxFactoryDefaultFrequency[2] = {600, 4200}; - uint32_t mockMaxFactoryDefaultVoltage[2] = {1200, 1300}; - uint32_t mockMaxOcFrequency[2] = {1800, 4500}; - uint32_t mockMaxOcVoltage[2] = {1300, 1400}; - uint32_t mockFixedMode[2] = {0, 0}; - uint32_t mockVoltageMode[2] = {0, 0}; - uint32_t mockHighVoltageSupported[2] = {0, 0}; - uint32_t mockHighVoltageEnabled[2] = {0, 0}; - uint32_t mockFrequencyTarget[2] = {0, 0}; - uint32_t mockVoltageTarget[2] = {0, 0}; - uint32_t mockVoltageOffset[2] = {0, 0}; + uint32_t mockMaxFactoryDefaultFrequency[3] = {600, 4200, 600}; + uint32_t mockMaxFactoryDefaultVoltage[3] = {1200, 1300, 1200}; + uint32_t mockMaxOcFrequency[3] = {1800, 4500, 1800}; + uint32_t mockMaxOcVoltage[3] = {1300, 1400, 1300}; + uint32_t mockFixedMode[3] = {0, 0, 0}; + uint32_t mockVoltageMode[3] = {0, 0, 0}; + uint32_t mockHighVoltageSupported[3] = {0, 0, 0}; + uint32_t mockHighVoltageEnabled[3] = {0, 0, 0}; + uint32_t mockFrequencyTarget[3] = {0, 0, 0}; + uint32_t mockVoltageTarget[3] = {0, 0, 0}; + uint32_t mockVoltageOffset[3] = {0, 0, 0}; void getFrequencyProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override { uint8_t *pBuffer = reinterpret_cast(pResponse); @@ -69,6 +70,12 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; pResponse->outDataSize = sizeof(uint32_t); } break; + case KmdSysman::Requests::Frequency::SupportedFreqDomains: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockSupportedDomains; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; case KmdSysman::Requests::Frequency::ExtendedOcSupported: { uint32_t *pValue = reinterpret_cast(pBuffer); *pValue = mockIsExtendedModeSupported[domain]; @@ -188,6 +195,13 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pMinFreq = reinterpret_cast(pBuffer); + uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); + *pMinFreq = mockMinFrequencyRange; + *pMaxFreq = mockMaxFrequencyRange; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = 2 * sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentRequestedFrequency: { @@ -199,6 +213,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRequestedFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentTdpFrequency: { @@ -210,6 +229,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockTdpFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentResolvedFrequency: { @@ -227,6 +251,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockEfficientFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::FrequencyRangeMaxDefault: { @@ -238,6 +267,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRp0[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::FrequencyRangeMinDefault: { @@ -249,6 +283,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRpn[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentVoltage: { @@ -260,6 +299,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockCurrentVoltage; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentThrottleReasons: { @@ -271,6 +315,11 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockThrottleReasons; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; default: { @@ -293,12 +342,24 @@ struct MockFrequencyKmdSysManager : public MockKmdSysManager { } switch (pRequest->inRequestId) { case KmdSysman::Requests::Frequency::CurrentFrequencyRange: { - uint32_t *pMinFreq = reinterpret_cast(pBuffer); - uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); - mockMinFrequencyRange = *pMinFreq; - mockMaxFrequencyRange = *pMaxFreq; - pResponse->outDataSize = 0; - pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pMinFreq = reinterpret_cast(pBuffer); + uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); + mockMinFrequencyRange = *pMinFreq; + mockMaxFrequencyRange = *pMaxFreq; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::ReturnCodes::DomainServiceNotSupported; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pMinFreq = reinterpret_cast(pBuffer); + uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); + mockMinFrequencyRange = *pMinFreq; + mockMaxFrequencyRange = *pMaxFreq; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } } break; case KmdSysman::Requests::Frequency::CurrentFixedMode: { uint32_t *pValue = reinterpret_cast(pBuffer); diff --git a/level_zero/sysman/test/unit_tests/sources/frequency/windows/test_zes_frequency.cpp b/level_zero/sysman/test/unit_tests/sources/frequency/windows/test_zes_frequency.cpp index 1f3af4e2d4..c3e5a3dae3 100644 --- a/level_zero/sysman/test/unit_tests/sources/frequency/windows/test_zes_frequency.cpp +++ b/level_zero/sysman/test/unit_tests/sources/frequency/windows/test_zes_frequency.cpp @@ -13,7 +13,7 @@ namespace L0 { namespace ult { -constexpr uint32_t frequencyHandleComponentCount = 2u; +constexpr uint32_t frequencyHandleComponentCount = 3u; constexpr double minFreq = 400.0; constexpr double maxFreq = 1200.0; constexpr double step = 50.0 / 3; @@ -59,6 +59,13 @@ class SysmanDeviceFrequencyFixture : public SysmanDeviceFixture { } }; +TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsIfNoHandlesArePresentThenZeroCountIsReturned) { + uint32_t count = 0; + pKmdSysManager->mockSupportedDomains = 0; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumFrequencyDomains(pSysmanDevice->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); @@ -110,6 +117,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_DOUBLE_EQ(-1, properties.max); EXPECT_DOUBLE_EQ(-1, properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); } domainIndex++; } @@ -131,6 +141,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesAllo } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_DOUBLE_EQ(-1.0, properties.max); EXPECT_DOUBLE_EQ(-1.0, properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); } EXPECT_EQ(pKmdSysManager->mockGPUCannotControl[domainIndex], properties.canControl); domainIndex++; @@ -176,6 +189,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndZeroCountWhenCa } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); EXPECT_EQ(1, count); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); + EXPECT_EQ(numClocks, count); } domainIndex++; @@ -217,6 +233,10 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq EXPECT_DOUBLE_EQ(pKmdSysManager->mockMaxFrequencyRange, limits.max); } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesFrequencyGetRange(handle, &limits)); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMinFrequencyRange, limits.min); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMaxFrequencyRange, limits.max); } domainIndex++; @@ -270,8 +290,20 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); EXPECT_DOUBLE_EQ(newMin, limits.min); EXPECT_DOUBLE_EQ(maxFreq, limits.max); - } + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + zes_freq_range_t limits; + pKmdSysManager->mockMinFrequencyRange = static_cast(startingMax); + + // If the new Max value is less than the old Min + // value, the new Min must be set before the new Max + limits.min = minFreq; + limits.max = maxFreq; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencySetRange(handle, &limits)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(minFreq, limits.min); + EXPECT_DOUBLE_EQ(maxFreq, limits.max); + } domainIndex++; } } @@ -298,6 +330,13 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq EXPECT_DOUBLE_EQ(-1.0, state.request); EXPECT_DOUBLE_EQ(-1.0, state.tdp); EXPECT_EQ(pKmdSysManager->mockThrottleReasons, state.throttleReasons); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockResolvedFrequency[domainIndex]), state.actual); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockCurrentVoltage) / milliVoltsFactor, state.currentVoltage); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockEfficientFrequency), state.efficient); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockRequestedFrequency), state.request); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockTdpFrequency), state.tdp); + EXPECT_EQ(pKmdSysManager->mockThrottleReasons, state.throttleReasons); } domainIndex++; diff --git a/level_zero/tools/source/sysman/frequency/frequency.cpp b/level_zero/tools/source/sysman/frequency/frequency.cpp index b61021e851..0f9dbd1978 100644 --- a/level_zero/tools/source/sysman/frequency/frequency.cpp +++ b/level_zero/tools/source/sysman/frequency/frequency.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -28,9 +28,8 @@ void FrequencyHandleContext::createHandle(ze_device_handle_t deviceHandle, zes_f ze_result_t FrequencyHandleContext::init(std::vector &deviceHandles) { for (const auto &deviceHandle : deviceHandles) { - auto totalDomains = OsFrequency::getNumberOfFreqDoainsSupported(pOsSysman); - UNRECOVERABLE_IF(totalDomains > 2); - for (uint32_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) { + auto totalDomains = OsFrequency::getNumberOfFreqDomainsSupported(pOsSysman); + for (const auto &frequencyDomain : totalDomains) { createHandle(deviceHandle, static_cast(frequencyDomain)); } } diff --git a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.cpp b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.cpp index a29c2ca0ea..78b1629a06 100644 --- a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.cpp +++ b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.cpp @@ -423,8 +423,9 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pLinuxFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { - return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { + std::vector freqDomains = {ZES_FREQ_DOMAIN_GPU}; + return freqDomains; } } // namespace L0 diff --git a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp_prelim.cpp b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp_prelim.cpp index d8b01faf3e..47e3347861 100644 --- a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp_prelim.cpp +++ b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp_prelim.cpp @@ -432,8 +432,9 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pLinuxFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { - return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { + std::vector freqDomains = {ZES_FREQ_DOMAIN_GPU}; + return freqDomains; } } // namespace L0 diff --git a/level_zero/tools/source/sysman/frequency/os_frequency.h b/level_zero/tools/source/sysman/frequency/os_frequency.h index b635d5e2f9..5f7f1999c2 100644 --- a/level_zero/tools/source/sysman/frequency/os_frequency.h +++ b/level_zero/tools/source/sysman/frequency/os_frequency.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -31,7 +31,7 @@ class OsFrequency { virtual ze_result_t getOcTjMax(double *pOcTjMax) = 0; virtual ze_result_t setOcTjMax(double ocTjMax) = 0; static OsFrequency *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t type); - static uint16_t getNumberOfFreqDoainsSupported(OsSysman *pOsSysman); + static std::vector getNumberOfFreqDomainsSupported(OsSysman *pOsSysman); virtual ~OsFrequency() {} }; diff --git a/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.cpp b/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.cpp index 6a09213e78..ab58b87afe 100644 --- a/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.cpp +++ b/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.cpp @@ -623,7 +623,7 @@ OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uin return static_cast(pWddmFrequencyImp); } -uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { +std::vector OsFrequency::getNumberOfFreqDomainsSupported(OsSysman *pOsSysman) { WddmSysmanImp *pWddmSysmanImp = static_cast(pOsSysman); KmdSysManager *pKmdSysManager = &pWddmSysmanImp->getKmdSysManager(); @@ -632,18 +632,22 @@ uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { request.commandId = KmdSysman::Command::Get; request.componentId = KmdSysman::Component::FrequencyComponent; - request.requestId = KmdSysman::Requests::Frequency::NumFrequencyDomains; + request.requestId = KmdSysman::Requests::Frequency::SupportedFreqDomains; ze_result_t status = pKmdSysManager->requestSingle(request, response); - + std::vector freqDomains; if (status != ZE_RESULT_SUCCESS) { - return 0; + return freqDomains; } - uint32_t maxNumEnginesSupported = 0; - memcpy_s(&maxNumEnginesSupported, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); - - return static_cast(maxNumEnginesSupported); + uint32_t supportedFreqDomains = 0; + memcpy_s(&supportedFreqDomains, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + for (uint16_t i = ZES_FREQ_DOMAIN_GPU; i <= ZES_FREQ_DOMAIN_MEDIA; i++) { + if (supportedFreqDomains & 1 << i) { + freqDomains.push_back(static_cast(i)); + } + } + return freqDomains; } } // namespace L0 diff --git a/level_zero/tools/source/sysman/windows/kmd_sys.h b/level_zero/tools/source/sysman/windows/kmd_sys.h index 6182b9eab3..eeef85fcd8 100644 --- a/level_zero/tools/source/sysman/windows/kmd_sys.h +++ b/level_zero/tools/source/sysman/windows/kmd_sys.h @@ -216,6 +216,7 @@ enum Frequency { CurrentThrottleReasons, CurrentThrottleTime, CurrentFrequencyRange, + SupportedFreqDomains = 38, MaxFrequencyRequests, }; @@ -340,6 +341,7 @@ enum FlipType { enum GeneralDomainsType { GeneralDomainDGPU = 0, GeneralDomainHBM, + GeneralDomainMedia, GeneralDomainMaxTypes, }; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h index 3fcaad5e10..224bc9b6b8 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h @@ -18,41 +18,42 @@ class FrequencyKmdSysManager : public Mock {}; template <> struct Mock : public FrequencyKmdSysManager { - uint32_t mockNumberOfDomains = 2; - uint32_t mockDomainType[2] = {ZES_FREQ_DOMAIN_GPU, ZES_FREQ_DOMAIN_MEMORY}; - bool mockGPUCanControl[2] = {true, false}; - bool mockGPUCannotControl[2] = {false, false}; + uint32_t mockNumberOfDomains = 3; + uint32_t mockSupportedDomains = 7; + uint32_t mockDomainType[3] = {ZES_FREQ_DOMAIN_GPU, ZES_FREQ_DOMAIN_MEMORY, ZES_FREQ_DOMAIN_MEDIA}; + bool mockGPUCanControl[3] = {true, false, false}; + bool mockGPUCannotControl[3] = {false, false, false}; uint32_t mockMinFrequencyRange = 400; uint32_t mockMaxFrequencyRange = 1200; - uint32_t mockRpn[2] = {400, 0}; - uint32_t mockRp0[2] = {1200, 0}; + uint32_t mockRpn[3] = {400, 0, 400}; + uint32_t mockRp0[3] = {1200, 0, 1200}; uint32_t mockRequestedFrequency = 600; uint32_t mockTdpFrequency = 0; - uint32_t mockResolvedFrequency[2] = {600, 4200}; + uint32_t mockResolvedFrequency[3] = {600, 4200, 600}; uint32_t mockEfficientFrequency = 400; uint32_t mockCurrentVoltage = 1100; uint32_t mockThrottleReasons = 0; uint32_t mockIccMax = 1025; uint32_t mockTjMax = 105; - uint32_t mockIsExtendedModeSupported[2] = {0, 0}; - uint32_t mockIsFixedModeSupported[2] = {0, 0}; - uint32_t mockIsHighVoltModeCapable[2] = {0, 0}; - uint32_t mockIsHighVoltModeEnabled[2] = {0, 0}; + uint32_t mockIsExtendedModeSupported[3] = {0, 0, 0}; + uint32_t mockIsFixedModeSupported[3] = {0, 0, 0}; + uint32_t mockIsHighVoltModeCapable[3] = {0, 0, 0}; + uint32_t mockIsHighVoltModeEnabled[3] = {0, 0, 0}; uint32_t mockIsIccMaxSupported = 1; - uint32_t mockIsOcSupported[2] = {0, 0}; + uint32_t mockIsOcSupported[3] = {0, 0, 0}; uint32_t mockIsTjMaxSupported = 1; - uint32_t mockMaxFactoryDefaultFrequency[2] = {600, 4200}; - uint32_t mockMaxFactoryDefaultVoltage[2] = {1200, 1300}; - uint32_t mockMaxOcFrequency[2] = {1800, 4500}; - uint32_t mockMaxOcVoltage[2] = {1300, 1400}; - uint32_t mockFixedMode[2] = {0, 0}; - uint32_t mockVoltageMode[2] = {0, 0}; - uint32_t mockHighVoltageSupported[2] = {0, 0}; - uint32_t mockHighVoltageEnabled[2] = {0, 0}; - uint32_t mockFrequencyTarget[2] = {0, 0}; - uint32_t mockVoltageTarget[2] = {0, 0}; - uint32_t mockVoltageOffset[2] = {0, 0}; + uint32_t mockMaxFactoryDefaultFrequency[3] = {600, 4200, 600}; + uint32_t mockMaxFactoryDefaultVoltage[3] = {1200, 1300, 1200}; + uint32_t mockMaxOcFrequency[3] = {1800, 4500, 1800}; + uint32_t mockMaxOcVoltage[3] = {1300, 1400, 1300}; + uint32_t mockFixedMode[3] = {0, 0, 0}; + uint32_t mockVoltageMode[3] = {0, 0, 0}; + uint32_t mockHighVoltageSupported[3] = {0, 0, 0}; + uint32_t mockHighVoltageEnabled[3] = {0, 0, 0}; + uint32_t mockFrequencyTarget[3] = {0, 0, 0}; + uint32_t mockVoltageTarget[3] = {0, 0, 0}; + uint32_t mockVoltageOffset[3] = {0, 0, 0}; void getFrequencyProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override { uint8_t *pBuffer = reinterpret_cast(pResponse); @@ -73,6 +74,12 @@ struct Mock : public FrequencyKmdSysManager { pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; pResponse->outDataSize = sizeof(uint32_t); } break; + case KmdSysman::Requests::Frequency::SupportedFreqDomains: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockSupportedDomains; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; case KmdSysman::Requests::Frequency::ExtendedOcSupported: { uint32_t *pValue = reinterpret_cast(pBuffer); *pValue = mockIsExtendedModeSupported[domain]; @@ -192,6 +199,13 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::ReturnCodes::DomainServiceNotSupported; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pMinFreq = reinterpret_cast(pBuffer); + uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); + *pMinFreq = mockMinFrequencyRange; + *pMaxFreq = mockMaxFrequencyRange; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = 2 * sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentRequestedFrequency: { @@ -203,6 +217,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRequestedFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentTdpFrequency: { @@ -214,6 +233,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockTdpFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentResolvedFrequency: { @@ -231,6 +255,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockEfficientFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::FrequencyRangeMaxDefault: { @@ -242,6 +271,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRp0[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::FrequencyRangeMinDefault: { @@ -253,6 +287,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRpn[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentVoltage: { @@ -264,6 +303,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockCurrentVoltage; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; case KmdSysman::Requests::Frequency::CurrentThrottleReasons: { @@ -275,6 +319,11 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockThrottleReasons; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); } } break; default: { @@ -307,6 +356,13 @@ struct Mock : public FrequencyKmdSysManager { } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { pResponse->outDataSize = 0; pResponse->outReturnCode = KmdSysman::ReturnCodes::DomainServiceNotSupported; + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainMedia) { + uint32_t *pMinFreq = reinterpret_cast(pBuffer); + uint32_t *pMaxFreq = reinterpret_cast(pBuffer + sizeof(uint32_t)); + mockMinFrequencyRange = *pMinFreq; + mockMaxFrequencyRange = *pMaxFreq; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; } } break; case KmdSysman::Requests::Frequency::CurrentFixedMode: { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp index 479ab50cbb..7c0bbc7cc0 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp @@ -15,7 +15,7 @@ extern bool sysmanUltsEnable; namespace L0 { namespace ult { -constexpr uint32_t frequencyHandleComponentCount = 2u; +constexpr uint32_t frequencyHandleComponentCount = 3u; constexpr double minFreq = 400.0; constexpr double maxFreq = 1200.0; constexpr double step = 50.0 / 3; @@ -76,12 +76,19 @@ class SysmanDeviceFrequencyFixture : public SysmanDeviceFixture { } }; -TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { +TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsThenValidCountIsReturned) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); EXPECT_EQ(count, frequencyHandleComponentCount); } +TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsIfNoHandlesArePresentThenZeroCountIsReturned) { + uint32_t count = 0; + pKmdSysManager->mockSupportedDomains = 0; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, 0u); +} + TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidComponentCountWhenEnumeratingFrequencyDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { uint32_t count = 0; EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); @@ -128,6 +135,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_DOUBLE_EQ(-1, properties.max); EXPECT_DOUBLE_EQ(-1, properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); } domainIndex++; } @@ -149,6 +159,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesAllo } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_DOUBLE_EQ(-1.0, properties.max); EXPECT_DOUBLE_EQ(-1.0, properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); } EXPECT_EQ(pKmdSysManager->mockGPUCannotControl[domainIndex], properties.canControl); domainIndex++; @@ -194,6 +207,9 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndZeroCountWhenCa } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); EXPECT_EQ(1, count); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); + EXPECT_EQ(numClocks, count); } domainIndex++; @@ -235,6 +251,10 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq EXPECT_DOUBLE_EQ(pKmdSysManager->mockMaxFrequencyRange, limits.max); } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyGetRange(handle, &limits)); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMinFrequencyRange, limits.min); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMaxFrequencyRange, limits.max); } domainIndex++; @@ -268,6 +288,19 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq pKmdSysManager->mockMinFrequencyRange = static_cast(startingMin); + // If the new Max value is less than the old Min + // value, the new Min must be set before the new Max + limits.min = minFreq; + limits.max = newMax; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencySetRange(handle, &limits)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(minFreq, limits.min); + EXPECT_DOUBLE_EQ(newMax, limits.max); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + zes_freq_range_t limits; + + pKmdSysManager->mockMinFrequencyRange = static_cast(startingMin); + // If the new Max value is less than the old Min // value, the new Min must be set before the new Max limits.min = minFreq; @@ -295,6 +328,19 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq pKmdSysManager->mockMaxFrequencyRange = static_cast(startingMax); + // If the new Min value is greater than the old Max + // value, the new Max must be set before the new Min + limits.min = newMin; + limits.max = maxFreq; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencySetRange(handle, &limits)); + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(newMin, limits.min); + EXPECT_DOUBLE_EQ(maxFreq, limits.max); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + zes_freq_range_t limits; + + pKmdSysManager->mockMaxFrequencyRange = static_cast(startingMax); + // If the new Min value is greater than the old Max // value, the new Max must be set before the new Min limits.min = newMin; @@ -331,6 +377,13 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq EXPECT_DOUBLE_EQ(-1.0, state.request); EXPECT_DOUBLE_EQ(-1.0, state.tdp); EXPECT_EQ(pKmdSysManager->mockThrottleReasons, state.throttleReasons); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEDIA) { + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockResolvedFrequency[domainIndex]), state.actual); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockCurrentVoltage) / milliVoltsFactor, state.currentVoltage); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockEfficientFrequency), state.efficient); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockRequestedFrequency), state.request); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockTdpFrequency), state.tdp); + EXPECT_EQ(pKmdSysManager->mockThrottleReasons, state.throttleReasons); } domainIndex++;