From f0907361ff34868368311035d031490cb2369dd9 Mon Sep 17 00:00:00 2001 From: Daniel Enriquez Date: Thu, 17 Sep 2020 03:14:58 -0700 Subject: [PATCH] Adding Frequency Support for Windows in Level 0 Sysman Change-Id: I8dbf67b0a6f88379a3da304e01a8f102e2027dd1 --- level_zero/api/sysman/zes_sysman.cpp | 22 +- .../source/sysman/frequency/frequency.cpp | 9 +- .../tools/source/sysman/frequency/frequency.h | 17 +- .../source/sysman/frequency/frequency_imp.cpp | 49 +- .../source/sysman/frequency/frequency_imp.h | 16 +- .../frequency/linux/os_frequency_imp.cpp | 53 +- .../sysman/frequency/linux/os_frequency_imp.h | 14 +- .../source/sysman/frequency/os_frequency.h | 16 +- .../sysman/frequency/windows/CMakeLists.txt | 4 +- .../frequency/windows/os_frequency_imp.cpp | 646 +++++++++++++++++- .../frequency/windows/os_frequency_imp.h | 80 +++ .../frequency/linux/mock_sysfs_frequency.h | 2 +- .../frequency/linux/test_zes_frequency.cpp | 122 +++- .../sysman/frequency/windows/CMakeLists.txt | 14 + .../sysman/frequency/windows/mock_frequency.h | 344 ++++++++++ .../frequency/windows/test_zes_frequency.cpp | 478 +++++++++++++ 16 files changed, 1819 insertions(+), 67 deletions(-) create mode 100644 level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/CMakeLists.txt create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h create mode 100644 level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp diff --git a/level_zero/api/sysman/zes_sysman.cpp b/level_zero/api/sysman/zes_sysman.cpp index f4dd01fd80..f70a91df3a 100644 --- a/level_zero/api/sysman/zes_sysman.cpp +++ b/level_zero/api/sysman/zes_sysman.cpp @@ -244,14 +244,14 @@ ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcGetFrequencyTarget( zes_freq_handle_t hFrequency, double *pCurrentOcFrequency) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGetFrequencyTarget(pCurrentOcFrequency); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcSetFrequencyTarget( zes_freq_handle_t hFrequency, double currentOcFrequency) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcSetFrequencyTarget(currentOcFrequency); } ZE_APIEXPORT ze_result_t ZE_APICALL @@ -259,7 +259,7 @@ zesFrequencyOcGetVoltageTarget( zes_freq_handle_t hFrequency, double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGetVoltageTarget(pCurrentVoltageTarget, pCurrentVoltageOffset); } ZE_APIEXPORT ze_result_t ZE_APICALL @@ -267,56 +267,56 @@ zesFrequencyOcSetVoltageTarget( zes_freq_handle_t hFrequency, double currentVoltageTarget, double currentVoltageOffset) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcSetVoltageTarget(currentVoltageTarget, currentVoltageOffset); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcSetMode( zes_freq_handle_t hFrequency, zes_oc_mode_t currentOcMode) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcSetMode(currentOcMode); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcGetMode( zes_freq_handle_t hFrequency, zes_oc_mode_t *pCurrentOcMode) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGetMode(pCurrentOcMode); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcGetCapabilities( zes_freq_handle_t hFrequency, zes_oc_capabilities_t *pOcCapabilities) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGetCapabilities(pOcCapabilities); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcGetIccMax( zes_freq_handle_t hFrequency, double *pOcIccMax) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGetIccMax(pOcIccMax); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcSetIccMax( zes_freq_handle_t hFrequency, double ocIccMax) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcSetIccMax(ocIccMax); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcGetTjMax( zes_freq_handle_t hFrequency, double *pOcTjMax) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcGeTjMax(pOcTjMax); } ZE_APIEXPORT ze_result_t ZE_APICALL zesFrequencyOcSetTjMax( zes_freq_handle_t hFrequency, double ocTjMax) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return L0::Frequency::fromHandle(hFrequency)->frequencyOcSetTjMax(ocTjMax); } ZE_APIEXPORT ze_result_t ZE_APICALL diff --git a/level_zero/tools/source/sysman/frequency/frequency.cpp b/level_zero/tools/source/sysman/frequency/frequency.cpp index 340f4c64ef..5632e3a0f3 100644 --- a/level_zero/tools/source/sysman/frequency/frequency.cpp +++ b/level_zero/tools/source/sysman/frequency/frequency.cpp @@ -20,16 +20,17 @@ FrequencyHandleContext::~FrequencyHandleContext() { } } -void FrequencyHandleContext::createHandle(ze_device_handle_t deviceHandle, uint16_t frequencyDomain) { +void FrequencyHandleContext::createHandle(ze_device_handle_t deviceHandle, zes_freq_domain_t frequencyDomain) { Frequency *pFrequency = new FrequencyImp(pOsSysman, deviceHandle, frequencyDomain); handleList.push_back(pFrequency); } ze_result_t FrequencyHandleContext::init(std::vector deviceHandles) { for (auto deviceHandle : deviceHandles) { - auto totalDomains = OsFrequency::getHardwareBlockCount(deviceHandle); - for (uint16_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) { - createHandle(deviceHandle, frequencyDomain); + auto totalDomains = OsFrequency::getNumberOfFreqDoainsSupported(pOsSysman); + UNRECOVERABLE_IF(totalDomains > 2); + for (uint32_t frequencyDomain = 0; frequencyDomain < totalDomains; frequencyDomain++) { + createHandle(deviceHandle, static_cast(frequencyDomain)); } } return ZE_RESULT_SUCCESS; diff --git a/level_zero/tools/source/sysman/frequency/frequency.h b/level_zero/tools/source/sysman/frequency/frequency.h index 6659b3aab4..a0cd45d6c7 100644 --- a/level_zero/tools/source/sysman/frequency/frequency.h +++ b/level_zero/tools/source/sysman/frequency/frequency.h @@ -17,6 +17,8 @@ struct _zes_freq_handle_t { namespace L0 { +constexpr double unsupportedProperty = -1.0; + struct OsSysman; class Frequency : _zes_freq_handle_t { @@ -30,6 +32,19 @@ class Frequency : _zes_freq_handle_t { virtual ze_result_t frequencyGetState(zes_freq_state_t *pState) = 0; virtual ze_result_t frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) = 0; + // Overclocking + virtual ze_result_t frequencyOcGetCapabilities(zes_oc_capabilities_t *pOcCapabilities) = 0; + virtual ze_result_t frequencyOcGetFrequencyTarget(double *pCurrentOcfrequency) = 0; + virtual ze_result_t frequencyOcSetFrequencyTarget(double currentOcfrequency) = 0; + virtual ze_result_t frequencyOcGetVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) = 0; + virtual ze_result_t frequencyOcSetVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) = 0; + virtual ze_result_t frequencyOcGetMode(zes_oc_mode_t *pCurrentOcMode) = 0; + virtual ze_result_t frequencyOcSetMode(zes_oc_mode_t currentOcMode) = 0; + virtual ze_result_t frequencyOcGetIccMax(double *pOcIccMax) = 0; + virtual ze_result_t frequencyOcSetIccMax(double ocIccMax) = 0; + virtual ze_result_t frequencyOcGeTjMax(double *pOcTjMax) = 0; + virtual ze_result_t frequencyOcSetTjMax(double ocTjMax) = 0; + static Frequency *fromHandle(zes_freq_handle_t handle) { return static_cast(handle); } @@ -48,7 +63,7 @@ struct FrequencyHandleContext { std::vector handleList = {}; private: - void createHandle(ze_device_handle_t deviceHandle, uint16_t frequencyDomain); + void createHandle(ze_device_handle_t deviceHandle, zes_freq_domain_t frequencyDomain); }; } // namespace L0 diff --git a/level_zero/tools/source/sysman/frequency/frequency_imp.cpp b/level_zero/tools/source/sysman/frequency/frequency_imp.cpp index e8cf1e28db..51af9eb151 100644 --- a/level_zero/tools/source/sysman/frequency/frequency_imp.cpp +++ b/level_zero/tools/source/sysman/frequency/frequency_imp.cpp @@ -65,8 +65,51 @@ ze_result_t FrequencyImp::frequencyGetThrottleTime(zes_freq_throttle_time_t *pTh return pOsFrequency->osFrequencyGetThrottleTime(pThrottleTime); } +ze_result_t FrequencyImp::frequencyOcGetCapabilities(zes_oc_capabilities_t *pOcCapabilities) { + return pOsFrequency->getOcCapabilities(pOcCapabilities); +} + +ze_result_t FrequencyImp::frequencyOcGetFrequencyTarget(double *pCurrentOcFrequency) { + return pOsFrequency->getOcFrequencyTarget(pCurrentOcFrequency); +} + +ze_result_t FrequencyImp::frequencyOcSetFrequencyTarget(double currentOcFrequency) { + return pOsFrequency->setOcFrequencyTarget(currentOcFrequency); +} + +ze_result_t FrequencyImp::frequencyOcGetVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) { + return pOsFrequency->getOcVoltageTarget(pCurrentVoltageTarget, pCurrentVoltageOffset); +} + +ze_result_t FrequencyImp::frequencyOcSetVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) { + return pOsFrequency->setOcVoltageTarget(currentVoltageTarget, currentVoltageOffset); +} + +ze_result_t FrequencyImp::frequencyOcGetMode(zes_oc_mode_t *pCurrentOcMode) { + return pOsFrequency->getOcMode(pCurrentOcMode); +} + +ze_result_t FrequencyImp::frequencyOcSetMode(zes_oc_mode_t currentOcMode) { + return pOsFrequency->setOcMode(currentOcMode); +} + +ze_result_t FrequencyImp::frequencyOcGetIccMax(double *pOcIccMax) { + return pOsFrequency->getOcIccMax(pOcIccMax); +} + +ze_result_t FrequencyImp::frequencyOcSetIccMax(double ocIccMax) { + return pOsFrequency->setOcIccMax(ocIccMax); +} + +ze_result_t FrequencyImp::frequencyOcGeTjMax(double *pOcTjMax) { + return pOsFrequency->getOcTjMax(pOcTjMax); +} + +ze_result_t FrequencyImp::frequencyOcSetTjMax(double ocTjMax) { + return pOsFrequency->setOcTjMax(ocTjMax); +} + void FrequencyImp::init() { - zesFrequencyProperties.type = static_cast(frequencyDomain); pOsFrequency->osFrequencyGetProperties(zesFrequencyProperties); double freqRange = zesFrequencyProperties.max - zesFrequencyProperties.min; numClocks = static_cast(round(freqRange / step)) + 1; @@ -76,10 +119,10 @@ void FrequencyImp::init() { } } -FrequencyImp::FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, uint16_t frequencyDomain) : deviceHandle(handle), frequencyDomain(frequencyDomain) { +FrequencyImp::FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, zes_freq_domain_t frequencyDomainNumber) : deviceHandle(handle) { ze_device_properties_t deviceProperties = {}; Device::fromHandle(deviceHandle)->getProperties(&deviceProperties); - pOsFrequency = OsFrequency::create(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId); + pOsFrequency = OsFrequency::create(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId, frequencyDomainNumber); UNRECOVERABLE_IF(nullptr == pOsFrequency); init(); diff --git a/level_zero/tools/source/sysman/frequency/frequency_imp.h b/level_zero/tools/source/sysman/frequency/frequency_imp.h index 6e5da0becf..165cfd7f0d 100644 --- a/level_zero/tools/source/sysman/frequency/frequency_imp.h +++ b/level_zero/tools/source/sysman/frequency/frequency_imp.h @@ -24,8 +24,21 @@ class FrequencyImp : public Frequency, NEO::NonCopyableOrMovableClass { ze_result_t frequencyGetState(zes_freq_state_t *pState) override; ze_result_t frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override; + // Overclocking + ze_result_t frequencyOcGetCapabilities(zes_oc_capabilities_t *pOcCapabilities) override; + ze_result_t frequencyOcGetFrequencyTarget(double *pCurrentOcFrequency) override; + ze_result_t frequencyOcSetFrequencyTarget(double currentOcFrequency) override; + ze_result_t frequencyOcGetVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) override; + ze_result_t frequencyOcSetVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) override; + ze_result_t frequencyOcGetMode(zes_oc_mode_t *pCurrentOcMode) override; + ze_result_t frequencyOcSetMode(zes_oc_mode_t currentOcMode) override; + ze_result_t frequencyOcGetIccMax(double *pOcIccMax) override; + ze_result_t frequencyOcSetIccMax(double ocIccMax) override; + ze_result_t frequencyOcGeTjMax(double *pOcTjMax) override; + ze_result_t frequencyOcSetTjMax(double ocTjMax) override; + FrequencyImp() = default; - FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, uint16_t frequencyDomain); + FrequencyImp(OsSysman *pOsSysman, ze_device_handle_t handle, zes_freq_domain_t frequencyDomainNumber); ~FrequencyImp() override; OsFrequency *pOsFrequency = nullptr; void init(); @@ -37,7 +50,6 @@ class FrequencyImp : public Frequency, NEO::NonCopyableOrMovableClass { double *pClocks = nullptr; uint32_t numClocks = 0; ze_device_handle_t deviceHandle = nullptr; - uint16_t frequencyDomain = 0; }; } // namespace L0 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 bc8733634b..5ea5595f37 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 @@ -16,6 +16,7 @@ const bool LinuxFrequencyImp::canControl = true; // canControl is true on i915 ( ze_result_t LinuxFrequencyImp::osFrequencyGetProperties(zes_freq_properties_t &properties) { properties.pNext = nullptr; properties.canControl = canControl; + properties.type = frequencyDomainNumber; ze_result_t result1 = getMinVal(properties.min); ze_result_t result2 = getMaxVal(properties.max); // If can't figure out the valid range, then can't control it. @@ -96,6 +97,50 @@ ze_result_t LinuxFrequencyImp::osFrequencyGetThrottleTime(zes_freq_throttle_time return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ze_result_t LinuxFrequencyImp::getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::getOcFrequencyTarget(double *pCurrentOcFrequency) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::setOcFrequencyTarget(double currentOcFrequency) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::getOcMode(zes_oc_mode_t *pCurrentOcMode) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::setOcMode(zes_oc_mode_t currentOcMode) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::getOcIccMax(double *pOcIccMax) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::setOcIccMax(double ocIccMax) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::getOcTjMax(double *pOcTjMax) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +ze_result_t LinuxFrequencyImp::setOcTjMax(double ocTjMax) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + ze_result_t LinuxFrequencyImp::getMin(double &min) { double intval; @@ -241,18 +286,18 @@ void LinuxFrequencyImp::init() { minValFreqFile = "gt_RPn_freq_mhz"; } -LinuxFrequencyImp::LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : isSubdevice(onSubdevice), subdeviceId(subdeviceId) { +LinuxFrequencyImp::LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) : isSubdevice(onSubdevice), subdeviceId(subdeviceId), frequencyDomainNumber(frequencyDomainNumber) { LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess(); init(); } -OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) { - LinuxFrequencyImp *pLinuxFrequencyImp = new LinuxFrequencyImp(pOsSysman, onSubdevice, subdeviceId); +OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) { + LinuxFrequencyImp *pLinuxFrequencyImp = new LinuxFrequencyImp(pOsSysman, onSubdevice, subdeviceId, frequencyDomainNumber); return static_cast(pLinuxFrequencyImp); } -uint16_t OsFrequency::getHardwareBlockCount(ze_device_handle_t handle) { +uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { return 1; // hardcode for now to support only ZES_FREQ_DOMAIN_GPU } diff --git a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h index acfce899c6..260296a957 100644 --- a/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h +++ b/level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h @@ -21,8 +21,19 @@ class LinuxFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass { ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) override; ze_result_t osFrequencyGetState(zes_freq_state_t *pState) override; ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override; + ze_result_t getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) override; + ze_result_t getOcFrequencyTarget(double *pCurrentOcFrequency) override; + ze_result_t setOcFrequencyTarget(double currentOcFrequency) override; + ze_result_t getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) override; + ze_result_t setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) override; + ze_result_t getOcMode(zes_oc_mode_t *pCurrentOcMode) override; + ze_result_t setOcMode(zes_oc_mode_t currentOcMode) override; + ze_result_t getOcIccMax(double *pOcIccMax) override; + ze_result_t setOcIccMax(double ocIccMax) override; + ze_result_t getOcTjMax(double *pOcTjMax) override; + ze_result_t setOcTjMax(double ocTjMax) override; LinuxFrequencyImp() = default; - LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId); + LinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber); ~LinuxFrequencyImp() override = default; protected: @@ -50,6 +61,7 @@ class LinuxFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass { static const bool canControl; bool isSubdevice = false; uint32_t subdeviceId = 0; + zes_freq_domain_t frequencyDomainNumber = ZES_FREQ_DOMAIN_GPU; void init(); }; diff --git a/level_zero/tools/source/sysman/frequency/os_frequency.h b/level_zero/tools/source/sysman/frequency/os_frequency.h index 5b9e34d420..eecc5bbfb7 100644 --- a/level_zero/tools/source/sysman/frequency/os_frequency.h +++ b/level_zero/tools/source/sysman/frequency/os_frequency.h @@ -18,9 +18,19 @@ class OsFrequency { virtual ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) = 0; virtual ze_result_t osFrequencyGetState(zes_freq_state_t *pState) = 0; virtual ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) = 0; - - static OsFrequency *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId); - static uint16_t getHardwareBlockCount(ze_device_handle_t handle); + virtual ze_result_t getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) = 0; + virtual ze_result_t getOcFrequencyTarget(double *pCurrentOcFrequency) = 0; + virtual ze_result_t setOcFrequencyTarget(double currentOcFrequency) = 0; + virtual ze_result_t getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) = 0; + virtual ze_result_t setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) = 0; + virtual ze_result_t getOcMode(zes_oc_mode_t *pCurrentOcMode) = 0; + virtual ze_result_t setOcMode(zes_oc_mode_t currentOcMode) = 0; + virtual ze_result_t getOcIccMax(double *pOcIccMax) = 0; + virtual ze_result_t setOcIccMax(double ocIccMax) = 0; + 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); virtual ~OsFrequency() {} }; diff --git a/level_zero/tools/source/sysman/frequency/windows/CMakeLists.txt b/level_zero/tools/source/sysman/frequency/windows/CMakeLists.txt index dff4fcadc8..d41a36c8b3 100644 --- a/level_zero/tools/source/sysman/frequency/windows/CMakeLists.txt +++ b/level_zero/tools/source/sysman/frequency/windows/CMakeLists.txt @@ -1,11 +1,11 @@ # -# Copyright (C) 2019-2020 Intel Corporation +# Copyright (C) 2020 Intel Corporation # # SPDX-License-Identifier: MIT # set(L0_SRCS_TOOLS_SYSMAN_FREQUENCY_WINDOWS - ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/os_frequency_imp.h ${CMAKE_CURRENT_SOURCE_DIR}/os_frequency_imp.cpp ) 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 5a3b4900fe..516cc799bf 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 @@ -5,46 +5,656 @@ * */ -#include "level_zero/tools/source/sysman/frequency/os_frequency.h" +#include "level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h" namespace L0 { -class WddmFrequencyImp : public OsFrequency { - public: - ze_result_t osFrequencyGetProperties(zes_freq_properties_t &properties) override; - ze_result_t osFrequencyGetRange(zes_freq_range_t *pLimits) override; - ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) override; - ze_result_t osFrequencyGetState(zes_freq_state_t *pState) override; - ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override; -}; - ze_result_t WddmFrequencyImp::osFrequencyGetProperties(zes_freq_properties_t &properties) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + readOverclockingInfo(); + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::FrequencyThrottledEventSupported; + request.paramInfo = static_cast(frequencyDomainNumber); + + properties.isThrottleEventSupported = false; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + properties.isThrottleEventSupported = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::FrequencyRangeMinDefault; + request.paramInfo = static_cast(frequencyDomainNumber); + + properties.min = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + value = 0; + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + properties.min = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::FrequencyRangeMaxDefault; + request.paramInfo = static_cast(frequencyDomainNumber); + + properties.max = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + value = 0; + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + properties.max = static_cast(value); + } + + properties.onSubdevice = false; + properties.subdeviceId = 0; + properties.type = frequencyDomainNumber; + properties.canControl = canControl(); + + return ZE_RESULT_SUCCESS; } ze_result_t WddmFrequencyImp::osFrequencyGetRange(zes_freq_range_t *pLimits) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return getRange(&pLimits->min, &pLimits->max); } ze_result_t WddmFrequencyImp::osFrequencySetRange(const zes_freq_range_t *pLimits) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + return setRange(pLimits->min, pLimits->max); } ze_result_t WddmFrequencyImp::osFrequencyGetState(zes_freq_state_t *pState) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentRequestedFrequency; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + pState->request = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + pState->request = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentTdpFrequency; + + pState->tdp = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + pState->tdp = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentResolvedFrequency; + + pState->actual = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + pState->actual = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentEfficientFrequency; + + pState->efficient = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + pState->efficient = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltage; + + pState->currentVoltage = unsupportedProperty; + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + pState->currentVoltage = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentThrottleReasons; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + KmdThrottleReasons value = {0}; + pState->throttleReasons = {0}; + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + + if (value.powerlimit1) { + pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_AVE_PWR_CAP; + } + if (value.powerlimit2) { + pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_BURST_PWR_CAP; + } + if (value.powerlimit4) { + pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_CURRENT_LIMIT; + } + if (value.thermal) { + pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_THERMAL_LIMIT; + } + } + + return ZE_RESULT_SUCCESS; } ze_result_t WddmFrequencyImp::osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } -OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) { - WddmFrequencyImp *pWddmFrequencyImp = new WddmFrequencyImp(); +bool WddmFrequencyImp::canControl() { + double minF = 0.0, maxF = 0.0; + if (getRange(&minF, &maxF) != ZE_RESULT_SUCCESS) { + return false; + } + + return (setRange(minF, maxF) == ZE_RESULT_SUCCESS); +} + +ze_result_t WddmFrequencyImp::getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) { + *pOcCapabilities = ocCapabilities; + return ZE_RESULT_SUCCESS; +} + +ze_result_t WddmFrequencyImp::getOcFrequencyTarget(double *pCurrentOcFrequency) { + ze_result_t status = ZE_RESULT_SUCCESS; + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *pCurrentOcFrequency = currentFrequencyTarget = static_cast(value); + + return status; +} + +ze_result_t WddmFrequencyImp::setOcFrequencyTarget(double currentOcFrequency) { + if (currentFrequencyTarget != currentOcFrequency) { + currentFrequencyTarget = currentOcFrequency; + return applyOcSettings(); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t WddmFrequencyImp::getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) { + ze_result_t status = ZE_RESULT_SUCCESS; + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *pCurrentVoltageTarget = currentVoltageTarget = static_cast(value); + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset; + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *pCurrentVoltageOffset = currentVoltageOffset = static_cast(value); + + return status; +} + +ze_result_t WddmFrequencyImp::setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) { + if (this->currentVoltageTarget != currentVoltageTarget || this->currentVoltageOffset != currentVoltageOffset) { + this->currentVoltageTarget = currentVoltageTarget; + this->currentVoltageOffset = currentVoltageOffset; + return applyOcSettings(); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t WddmFrequencyImp::getOcMode(zes_oc_mode_t *pCurrentOcMode) { + ze_result_t status = ZE_RESULT_SUCCESS; + + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentFixedMode; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentFixedMode = value ? ZES_OC_MODE_FIXED : ZES_OC_MODE_OFF; + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode; + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentVoltageMode = value ? ZES_OC_MODE_OVERRIDE : ZES_OC_MODE_INTERPOLATIVE; + + if (currentFixedMode == ZES_OC_MODE_FIXED) { + currentOcMode = ZES_OC_MODE_FIXED; + } else { + currentOcMode = currentVoltageMode; + } + + *pCurrentOcMode = currentOcMode; + + return status; +} + +ze_result_t WddmFrequencyImp::setOcMode(zes_oc_mode_t currentOcMode) { + if (currentOcMode == ZES_OC_MODE_OFF) { + this->currentFrequencyTarget = ocCapabilities.maxFactoryDefaultFrequency; + this->currentVoltageTarget = ocCapabilities.maxFactoryDefaultVoltage; + this->currentVoltageOffset = 0; + this->currentFixedMode = ZES_OC_MODE_OFF; + this->currentVoltageMode = ZES_OC_MODE_INTERPOLATIVE; + this->currentOcMode = ZES_OC_MODE_OFF; + return applyOcSettings(); + } + + if (currentOcMode == ZES_OC_MODE_FIXED) { + this->currentOcMode = ZES_OC_MODE_FIXED; + this->currentFixedMode = ZES_OC_MODE_FIXED; + this->currentVoltageMode = ZES_OC_MODE_OVERRIDE; + return applyOcSettings(); + } + + if (currentOcMode == ZES_OC_MODE_INTERPOLATIVE || currentOcMode == ZES_OC_MODE_OVERRIDE) { + this->currentVoltageMode = currentOcMode; + this->currentFixedMode = ZES_OC_MODE_OFF; + this->currentOcMode = currentOcMode; + return applyOcSettings(); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t WddmFrequencyImp::getOcIccMax(double *pOcIccMax) { + ze_result_t status = ZE_RESULT_SUCCESS; + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *pOcIccMax = static_cast(value); + + return status; +} + +ze_result_t WddmFrequencyImp::setOcIccMax(double ocIccMax) { + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Set; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax; + request.paramInfo = static_cast(this->frequencyDomainNumber); + request.dataSize = sizeof(uint32_t); + + value = static_cast(ocIccMax); + memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t)); + + return pKmdSysManager->requestSingle(request, response); +} + +ze_result_t WddmFrequencyImp::getOcTjMax(double *pOcTjMax) { + ze_result_t status = ZE_RESULT_SUCCESS; + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentTjMax; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *pOcTjMax = static_cast(value); + + return status; +} + +ze_result_t WddmFrequencyImp::setOcTjMax(double ocTjMax) { + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Set; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax; + request.paramInfo = static_cast(this->frequencyDomainNumber); + request.dataSize = sizeof(uint32_t); + + value = static_cast(ocTjMax); + memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t)); + + return pKmdSysManager->requestSingle(request, response); +} + +ze_result_t WddmFrequencyImp::setRange(double min, double max) { + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Set; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyRange; + request.paramInfo = static_cast(this->frequencyDomainNumber); + request.dataSize = 2 * sizeof(uint32_t); + + value = static_cast(min); + memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t)); + value = static_cast(max); + memcpy_s((request.dataBuffer + sizeof(uint32_t)), sizeof(uint32_t), &value, sizeof(uint32_t)); + + return pKmdSysManager->requestSingle(request, response); +} + +ze_result_t WddmFrequencyImp::getRange(double *min, double *max) { + ze_result_t status = ZE_RESULT_SUCCESS; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyRange; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + uint32_t value = 0; + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + *min = static_cast(value); + memcpy_s(&value, sizeof(uint32_t), (response.dataBuffer + sizeof(uint32_t)), sizeof(uint32_t)); + *max = static_cast(value); + + return status; +} + +ze_result_t WddmFrequencyImp::applyOcSettings() { + ze_result_t status = ZE_RESULT_SUCCESS; + int32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Set; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::CurrentFixedMode; + request.paramInfo = static_cast(this->frequencyDomainNumber); + request.dataSize = sizeof(int32_t); + + value = (currentFixedMode == ZES_OC_MODE_FIXED) ? 1 : 0; + memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t)); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode; + + value = (currentVoltageMode == ZES_OC_MODE_OVERRIDE) ? 1 : 0; + memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t)); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset; + + value = static_cast(currentVoltageOffset); + memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t)); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget; + + value = static_cast(currentVoltageTarget); + memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t)); + + status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget; + + value = static_cast(currentFrequencyTarget); + memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t)); + + return pKmdSysManager->requestSingle(request, response); +} + +void WddmFrequencyImp::readOverclockingInfo() { + uint32_t value = 0; + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::ExtendedOcSupported; + request.paramInfo = static_cast(this->frequencyDomainNumber); + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isExtendedModeSupported = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::FixedModeSupported; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isFixedModeSupported = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::HighVoltageModeSupported; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isHighVoltModeCapable = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::HighVoltageEnabled; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isHighVoltModeEnabled = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isIccMaxSupported = static_cast(value > 0); + } + + request.requestId = KmdSysman::Requests::Frequency::FrequencyOcSupported; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isOcSupported = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentTjMax; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.isTjMaxSupported = static_cast(value > 0); + } + + request.requestId = KmdSysman::Requests::Frequency::MaxNonOcFrequencyDefault; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.maxFactoryDefaultFrequency = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::MaxNonOcVoltageDefault; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.maxFactoryDefaultVoltage = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::MaxOcFrequencyDefault; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.maxOcFrequency = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::MaxOcVoltageDefault; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + ocCapabilities.maxOcVoltage = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentFixedMode; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentFixedMode = value ? ZES_OC_MODE_FIXED : ZES_OC_MODE_OFF; + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentFrequencyTarget = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentVoltageTarget = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentVoltageOffset = static_cast(value); + } + + request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode; + + if (pKmdSysManager->requestSingle(request, response) == ZE_RESULT_SUCCESS) { + memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + currentVoltageMode = value ? ZES_OC_MODE_OVERRIDE : ZES_OC_MODE_INTERPOLATIVE; + } + + if (currentFrequencyTarget == 0.0 || currentVoltageTarget == 0.0) { + if (currentFrequencyTarget == 0.0) { + currentFrequencyTarget = ocCapabilities.maxFactoryDefaultFrequency; + } + + if (currentVoltageTarget == 0.0) { + currentVoltageTarget = ocCapabilities.maxFactoryDefaultVoltage; + } + } + + if (currentFixedMode == ZES_OC_MODE_FIXED) { + currentOcMode = ZES_OC_MODE_FIXED; + } else { + currentOcMode = currentVoltageMode; + } +} + +WddmFrequencyImp::WddmFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) { + WddmSysmanImp *pWddmSysmanImp = static_cast(pOsSysman); + this->frequencyDomainNumber = frequencyDomainNumber; + pKmdSysManager = &pWddmSysmanImp->getKmdSysManager(); +} + +OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) { + WddmFrequencyImp *pWddmFrequencyImp = new WddmFrequencyImp(pOsSysman, onSubdevice, subdeviceId, frequencyDomainNumber); return static_cast(pWddmFrequencyImp); } -uint16_t OsFrequency::getHardwareBlockCount(ze_device_handle_t handle) { - return 1; +uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) { + WddmSysmanImp *pWddmSysmanImp = static_cast(pOsSysman); + KmdSysManager *pKmdSysManager = &pWddmSysmanImp->getKmdSysManager(); + + KmdSysman::RequestProperty request; + KmdSysman::ResponseProperty response; + + request.commandId = KmdSysman::Command::Get; + request.componentId = KmdSysman::Component::FrequencyComponent; + request.requestId = KmdSysman::Requests::Frequency::NumFrequencyDomains; + + ze_result_t status = pKmdSysManager->requestSingle(request, response); + + if (status != ZE_RESULT_SUCCESS) { + return 0; + } + + uint32_t maxNumEnginesSupported = 0; + memcpy_s(&maxNumEnginesSupported, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t)); + + return static_cast(maxNumEnginesSupported); } } // namespace L0 diff --git a/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h b/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h new file mode 100644 index 0000000000..f4182c0cfd --- /dev/null +++ b/level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "sysman/frequency/os_frequency.h" +#include "sysman/windows/os_sysman_imp.h" + +#define KMD_BIT_RANGE(endbit, startbit) ((endbit) - (startbit) + 1) + +namespace L0 { + +struct KmdThrottleReasons { + union { + uint32_t bitfield; + struct { + uint32_t reserved1 : KMD_BIT_RANGE(16, 0); + uint32_t thermal : KMD_BIT_RANGE(17, 17); + uint32_t reserved2 : KMD_BIT_RANGE(23, 18); + uint32_t powerlimit4 : KMD_BIT_RANGE(24, 24); + uint32_t reserved3 : KMD_BIT_RANGE(25, 25); + uint32_t powerlimit1 : KMD_BIT_RANGE(26, 26); + uint32_t powerlimit2 : KMD_BIT_RANGE(27, 27); + uint32_t reserved4 : KMD_BIT_RANGE(31, 28); + }; + }; +}; + +class KmdSysManager; +class WddmFrequencyImp : public OsFrequency, NEO::NonCopyableOrMovableClass { + public: + ze_result_t osFrequencyGetProperties(zes_freq_properties_t &properties) override; + ze_result_t osFrequencyGetRange(zes_freq_range_t *pLimits) override; + ze_result_t osFrequencySetRange(const zes_freq_range_t *pLimits) override; + ze_result_t osFrequencyGetState(zes_freq_state_t *pState) override; + ze_result_t osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override; + + ze_result_t getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) override; + ze_result_t getOcFrequencyTarget(double *pCurrentOcFrequency) override; + ze_result_t setOcFrequencyTarget(double currentOcFrequency) override; + ze_result_t getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) override; + ze_result_t setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) override; + ze_result_t getOcMode(zes_oc_mode_t *pCurrentOcMode) override; + ze_result_t setOcMode(zes_oc_mode_t currentOcMode) override; + ze_result_t getOcIccMax(double *pOcIccMax) override; + ze_result_t setOcIccMax(double ocIccMax) override; + ze_result_t getOcTjMax(double *pOcTjMax) override; + ze_result_t setOcTjMax(double ocTjMax) override; + + WddmFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t type); + WddmFrequencyImp() = default; + ~WddmFrequencyImp() override = default; + + private: + ze_result_t setRange(double min, double max); + ze_result_t getRange(double *min, double *max); + void readOverclockingInfo(); + bool canControl(); + ze_result_t applyOcSettings(); + double minRangeFreq = -1.0; + double maxRangeFreq = -1.0; + zes_oc_capabilities_t ocCapabilities = {}; + zes_oc_mode_t currentOcMode = ZES_OC_MODE_OFF; + zes_oc_mode_t currentFixedMode = ZES_OC_MODE_OFF; + zes_oc_mode_t currentVoltageMode = ZES_OC_MODE_OFF; + double currentFrequencyTarget = -1.0; + double currentVoltageTarget = -1.0; + double currentVoltageOffset = -1.0; + + protected: + KmdSysManager *pKmdSysManager = nullptr; + zes_freq_domain_t frequencyDomainNumber = ZES_FREQ_DOMAIN_GPU; +}; + +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/mock_sysfs_frequency.h b/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/mock_sysfs_frequency.h index 5478400803..5599a757a9 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/mock_sysfs_frequency.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/mock_sysfs_frequency.h @@ -218,7 +218,7 @@ struct Mock : public FrequencySysfsAccess { class PublicLinuxFrequencyImp : public L0::LinuxFrequencyImp { public: - PublicLinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : LinuxFrequencyImp(pOsSysman, onSubdevice, subdeviceId) {} + PublicLinuxFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t type) : LinuxFrequencyImp(pOsSysman, onSubdevice, subdeviceId, type) {} using LinuxFrequencyImp::getMaxVal; using LinuxFrequencyImp::getMin; using LinuxFrequencyImp::getMinVal; diff --git a/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/test_zes_frequency.cpp b/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/test_zes_frequency.cpp index 6fddbeeddc..3cf5e3ec68 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/test_zes_frequency.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/linux/test_zes_frequency.cpp @@ -120,8 +120,8 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroAndValidPtrWhenEnume TEST_F(SysmanDeviceFrequencyFixture, GivenActualComponentCountTwoWhenTryingToGetOneComponentOnlyThenOneComponentIsReturnedAndCountUpdated) { auto pFrequencyHandleContextTest = std::make_unique(pOsSysman); - pFrequencyHandleContextTest->handleList.push_back(new FrequencyImp(pOsSysman, device->toHandle(), 0)); - pFrequencyHandleContextTest->handleList.push_back(new FrequencyImp(pOsSysman, device->toHandle(), 0)); + pFrequencyHandleContextTest->handleList.push_back(new FrequencyImp(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU)); + pFrequencyHandleContextTest->handleList.push_back(new FrequencyImp(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU)); uint32_t count = 1; std::vector phFrequency(count, nullptr); @@ -173,7 +173,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndCorrectCountWhe } TEST_F(SysmanDeviceFrequencyFixture, GivenValidateFrequencyGetRangeWhengetMaxFailsThenFrequencyGetRangeCallShouldFail) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limit = {}; ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getValReturnErrorNotAvailable)); @@ -195,7 +195,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyLimitsWhenCallingFrequencySetRangeForFailures1ThenAPIExitsGracefully) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits = {}; // Verify that Max must be within range. @@ -211,7 +211,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyLimitsWhenCallingFrequen } TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyLimitsWhenCallingFrequencySetRangeForFailures2ThenAPIExitsGracefully) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits = {}; // Verify that Max must be within range. @@ -265,7 +265,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest1ReturnsError) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits; // Verify that Max must be within range. @@ -275,7 +275,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequ } TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest2ReturnsError) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits; // Verify that Min must be within range. @@ -285,7 +285,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequ } TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest3ReturnsError) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits; // Verify that values must be multiples of step. @@ -295,7 +295,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequ } TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest4ReturnsError) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_range_t limits; // Verify that Max must be greater than min range. @@ -329,7 +329,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } TEST_F(SysmanDeviceFrequencyFixture, GivenValidStatePointerWhenValidatingfrequencyGetStateForFailuresThenAPIExitsGracefully) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_state_t state = {}; ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getValRequestReturnErrorNotAvailable)); @@ -365,13 +365,13 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidStatePointerWhenValidatingfrequen } TEST_F(SysmanDeviceFrequencyFixture, GivenThrottleTimeStructPointerWhenCallingfrequencyGetThrottleTimeThenUnsupportedIsReturned) { - auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), 0); + auto pFrequencyImp = std::make_unique(pOsSysman, device->toHandle(), ZES_FREQ_DOMAIN_GPU); zes_freq_throttle_time_t throttleTime = {}; EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pFrequencyImp->frequencyGetThrottleTime(&throttleTime)); } TEST_F(SysmanDeviceFrequencyFixture, GivengetMinFunctionReturnsErrorWhenValidatinggetMinFailuresThenAPIReturnsErrorAccordingly) { - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0, ZES_FREQ_DOMAIN_GPU); double min = 0; ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getValReturnErrorNotAvailable)); @@ -383,7 +383,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivengetMinFunctionReturnsErrorWhenValidati } TEST_F(SysmanDeviceFrequencyFixture, GivengetMinValFunctionReturnsErrorWhenValidatinggetMinValFailuresThenAPIReturnsErrorAccordingly) { - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0, ZES_FREQ_DOMAIN_GPU); double val = 0; ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getMinValReturnErrorNotAvailable)); @@ -395,7 +395,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivengetMinValFunctionReturnsErrorWhenValid } TEST_F(SysmanDeviceFrequencyFixture, GivengetMaxValFunctionReturnsErrorWhenValidatinggetMaxValFailuresThenAPIReturnsErrorAccordingly) { - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0, ZES_FREQ_DOMAIN_GPU); double val = 0; ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getMaxValReturnErrorNotAvailable)); @@ -408,7 +408,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivengetMaxValFunctionReturnsErrorWhenValid TEST_F(SysmanDeviceFrequencyFixture, GivengetMaxValFunctionReturnsErrorWhenValidatingosFrequencyGetPropertiesThenAPIBehavesAsExpected) { zes_freq_properties_t properties = {}; - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0, ZES_FREQ_DOMAIN_GPU); ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getMaxValReturnErrorNotAvailable)); EXPECT_EQ(ZE_RESULT_SUCCESS, linuxFrequencyImp.osFrequencyGetProperties(properties)); @@ -417,7 +417,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivengetMaxValFunctionReturnsErrorWhenValid TEST_F(SysmanDeviceFrequencyFixture, GivengetMinValFunctionReturnsErrorWhenValidatingosFrequencyGetPropertiesThenAPIBehavesAsExpected) { zes_freq_properties_t properties = {}; - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 0, 0, ZES_FREQ_DOMAIN_GPU); ON_CALL(*pSysfsAccess.get(), read(_, _)) .WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock::getMinValReturnErrorNotAvailable)); EXPECT_EQ(ZE_RESULT_SUCCESS, linuxFrequencyImp.osFrequencyGetProperties(properties)); @@ -426,7 +426,7 @@ TEST_F(SysmanDeviceFrequencyFixture, GivengetMinValFunctionReturnsErrorWhenValid TEST_F(SysmanDeviceFrequencyFixture, GivenOnSubdeviceSetWhenValidatingAnyFrequencyAPIThenSuccessIsReturned) { zes_freq_properties_t properties = {}; - PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 1, 0); + PublicLinuxFrequencyImp linuxFrequencyImp(pOsSysman, 1, 0, ZES_FREQ_DOMAIN_GPU); EXPECT_EQ(ZE_RESULT_SUCCESS, linuxFrequencyImp.osFrequencyGetProperties(properties)); EXPECT_EQ(1, properties.canControl); } @@ -449,5 +449,93 @@ TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFreq } } +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetFrequencyTargetThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double freqTarget = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetFrequencyTarget(handle, &freqTarget)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcSetFrequencyTargetThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double freqTarget = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcSetFrequencyTarget(handle, freqTarget)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetVoltageTargetThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double voltTarget = 0.0, voltOffset = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetVoltageTarget(handle, &voltTarget, &voltOffset)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcSetVoltageTargetThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double voltTarget = 0.0, voltOffset = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcSetVoltageTarget(handle, voltTarget, voltOffset)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcSetModeThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + zes_oc_mode_t mode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcSetMode(handle, mode)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetModeThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + zes_oc_mode_t mode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetMode(handle, &mode)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetCapabilitiesThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + zes_oc_capabilities_t caps = {}; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetCapabilities(handle, &caps)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetIccMaxThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double iccMax = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetIccMax(handle, &iccMax)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcSetIccMaxThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double iccMax = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcSetIccMax(handle, iccMax)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetTjMaxThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double tjMax = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcGetTjMax(handle, &tjMax)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcSetTjMaxThenVerifyTestCallFail) { + auto handles = get_freq_handles(handleComponentCount); + for (auto handle : handles) { + double tjMax = 0.0; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesFrequencyOcSetTjMax(handle, tjMax)); + } +} + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/CMakeLists.txt b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/CMakeLists.txt new file mode 100644 index 0000000000..1d44b04e10 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(WIN32) + target_sources(${TARGET_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_frequency.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_frequency.h + ) +endif() 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 new file mode 100644 index 0000000000..283b921756 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/core/test/unit_tests/mock.h" +#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_kmd_sys_manager.h" + +#include "sysman/frequency/windows/os_frequency_imp.h" + +namespace L0 { +namespace ult { + +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 mockMinFrequencyRange = 400; + uint32_t mockMaxFrequencyRange = 1200; + uint32_t mockRpn[2] = {400, 0}; + uint32_t mockRp0[2] = {1200, 0}; + uint32_t mockRequestedFrequency = 600; + uint32_t mockTdpFrequency = 0; + uint32_t mockResolvedFrequency[2] = {600, 4200}; + 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 mockIsIccMaxSupported = 1; + uint32_t mockIsOcSupported[2] = {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}; + + void getFrequencyProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override { + uint8_t *pBuffer = reinterpret_cast(pResponse); + pBuffer += sizeof(KmdSysman::GfxSysmanReqHeaderOut); + + KmdSysman::GeneralDomainsType domain = static_cast(pRequest->inCommandParam); + + if (domain < KmdSysman::GeneralDomainsType::GeneralDomainDGPU || domain >= KmdSysman::GeneralDomainsType::GeneralDomainMaxTypes) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + return; + } + + switch (pRequest->inRequestId) { + case KmdSysman::Requests::Frequency::NumFrequencyDomains: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockNumberOfDomains; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::ExtendedOcSupported: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockIsExtendedModeSupported[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::FixedModeSupported: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockFixedMode[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::HighVoltageModeSupported: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockHighVoltageSupported[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::HighVoltageEnabled: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockHighVoltageEnabled[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::FrequencyOcSupported: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockIsOcSupported[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentIccMax: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockIccMax; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentTjMax: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockTjMax; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::MaxNonOcFrequencyDefault: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockMaxFactoryDefaultFrequency[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::MaxNonOcVoltageDefault: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockMaxFactoryDefaultVoltage[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::MaxOcFrequencyDefault: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockMaxOcFrequency[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::MaxOcVoltageDefault: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockMaxOcVoltage[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentFixedMode: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockFixedMode[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentFrequencyTarget: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockFrequencyTarget[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageTarget: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockVoltageTarget[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageOffset: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockVoltageOffset[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageMode: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockVoltageMode[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::FrequencyThrottledEventSupported: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentFrequencyRange: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + 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); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::CurrentRequestedFrequency: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRequestedFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::CurrentTdpFrequency: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockTdpFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::CurrentResolvedFrequency: { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockResolvedFrequency[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } break; + case KmdSysman::Requests::Frequency::CurrentEfficientFrequency: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockEfficientFrequency; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::FrequencyRangeMaxDefault: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRp0[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::FrequencyRangeMinDefault: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockRpn[domain]; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::CurrentVoltage: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockCurrentVoltage; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + case KmdSysman::Requests::Frequency::CurrentThrottleReasons: { + if (domain == KmdSysman::GeneralDomainsType::GeneralDomainDGPU) { + uint32_t *pValue = reinterpret_cast(pBuffer); + *pValue = mockThrottleReasons; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + pResponse->outDataSize = sizeof(uint32_t); + } else if (domain == KmdSysman::GeneralDomainsType::GeneralDomainHBM) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } + } break; + default: { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } break; + } + } + + void setFrequencyProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override { + uint8_t *pBuffer = reinterpret_cast(pRequest); + pBuffer += sizeof(KmdSysman::GfxSysmanReqHeaderIn); + + KmdSysman::GeneralDomainsType domain = static_cast(pRequest->inCommandParam); + + if (domain < KmdSysman::GeneralDomainsType::GeneralDomainDGPU || domain >= KmdSysman::GeneralDomainsType::GeneralDomainMaxTypes) { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + return; + } + 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; + } break; + case KmdSysman::Requests::Frequency::CurrentFixedMode: { + uint32_t *pValue = reinterpret_cast(pBuffer); + mockFixedMode[domain] = *pValue; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageMode: { + uint32_t *pValue = reinterpret_cast(pBuffer); + mockVoltageMode[domain] = *pValue; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageOffset: { + uint32_t *pValue = reinterpret_cast(pBuffer); + mockVoltageOffset[domain] = *pValue; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } break; + case KmdSysman::Requests::Frequency::CurrentVoltageTarget: { + uint32_t *pValue = reinterpret_cast(pBuffer); + mockVoltageTarget[domain] = *pValue; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } break; + case KmdSysman::Requests::Frequency::CurrentFrequencyTarget: { + uint32_t *pValue = reinterpret_cast(pBuffer); + mockFrequencyTarget[domain] = *pValue; + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess; + } break; + default: { + pResponse->outDataSize = 0; + pResponse->outReturnCode = KmdSysman::KmdSysmanFail; + } break; + } + } + + Mock() = default; + ~Mock() = default; +}; + +} // namespace ult +} // namespace L0 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 new file mode 100644 index 0000000000..9bb8037c10 --- /dev/null +++ b/level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/test_zes_frequency.cpp @@ -0,0 +1,478 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h" +#include "level_zero/tools/test/unit_tests/sources/sysman/frequency/windows/mock_frequency.h" +#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_sysman_fixture.h" + +namespace L0 { +namespace ult { + +constexpr uint32_t frequencyHandleComponentCount = 2u; +constexpr double minFreq = 400.0; +constexpr double maxFreq = 1200.0; +constexpr double step = 50.0 / 3; +constexpr uint32_t numClocks = static_cast((maxFreq - minFreq) / step) + 1; +class SysmanDeviceFrequencyFixture : public SysmanDeviceFixture { + protected: + Mock *pKmdSysManager = nullptr; + KmdSysManager *pOriginalKmdSysManager = nullptr; + void SetUp(bool allowSetCalls) { // NOLINT(readability-identifier-naming) + SysmanDeviceFixture::SetUp(); + + pKmdSysManager = new Mock; + + pKmdSysManager->allowSetCalls = allowSetCalls; + + EXPECT_CALL(*pKmdSysManager, escape(_, _, _, _, _)) + .WillRepeatedly(::testing::Invoke(pKmdSysManager, &Mock::mock_escape)); + + pOriginalKmdSysManager = pWddmSysmanImp->pKmdSysManager; + pWddmSysmanImp->pKmdSysManager = pKmdSysManager; + + // delete handles created in initial SysmanDeviceHandleContext::init() call + for (auto handle : pSysmanDeviceImp->pFrequencyHandleContext->handleList) { + delete handle; + } + pSysmanDeviceImp->pFrequencyHandleContext->handleList.clear(); + uint32_t subDeviceCount = 0; + std::vector deviceHandles; + // We received a device handle. Check for subdevices in this device + Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, nullptr); + if (subDeviceCount == 0) { + deviceHandles.resize(1, device->toHandle()); + } else { + deviceHandles.resize(subDeviceCount, nullptr); + Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, deviceHandles.data()); + } + pSysmanDeviceImp->pFrequencyHandleContext->init(deviceHandles); + } + + void TearDown() override { + SysmanDeviceFixture::TearDown(); + pWddmSysmanImp->pKmdSysManager = pOriginalKmdSysManager; + if (pKmdSysManager != nullptr) { + delete pKmdSysManager; + pKmdSysManager = nullptr; + } + } + + double clockValue(const double calculatedClock) { + // i915 specific. frequency step is a fraction + // However, the Kmd represents all clock + // rates as integer values. So clocks are + // rounded to the nearest integer. + uint32_t actualClock = static_cast(calculatedClock + 0.5); + return static_cast(actualClock); + } + + std::vector get_frequency_handles(uint32_t count) { + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } +}; + +TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { + SetUp(true); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, frequencyHandleComponentCount); +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidComponentCountWhenEnumeratingFrequencyDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) { + SetUp(true); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, frequencyHandleComponentCount); + + count = count + 1; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, frequencyHandleComponentCount); +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyDomainsThenValidPowerHandlesIsReturned) { + SetUp(true); + + uint32_t count = 0; + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, frequencyHandleComponentCount); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + for (auto handle : handles) { + EXPECT_NE(handle, nullptr); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetPropertiesThenSuccessIsReturned) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + for (auto handle : handles) { + EXPECT_NE(handle, nullptr); + zes_freq_properties_t properties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetProperties(handle, &properties)); + EXPECT_EQ(pKmdSysManager->mockDomainType[domainIndex], properties.type); + EXPECT_FALSE(properties.onSubdevice); + EXPECT_EQ(pKmdSysManager->mockGPUCanControl[domainIndex], properties.canControl); + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { + EXPECT_DOUBLE_EQ(-1, properties.max); + EXPECT_DOUBLE_EQ(-1, properties.min); + } + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesAllowSetCallsToFalseFrequencyGetPropertiesThenSuccessIsReturned) { + SetUp(false); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + for (auto handle : handles) { + EXPECT_NE(handle, nullptr); + zes_freq_properties_t properties; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetProperties(handle, &properties)); + EXPECT_EQ(pKmdSysManager->mockDomainType[domainIndex], properties.type); + EXPECT_FALSE(properties.onSubdevice); + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRp0[domainIndex], properties.max); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockRpn[domainIndex], properties.min); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { + EXPECT_DOUBLE_EQ(-1.0, properties.max); + EXPECT_DOUBLE_EQ(-1.0, properties.min); + } + EXPECT_EQ(pKmdSysManager->mockGPUCannotControl[domainIndex], properties.canControl); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndZeroCountWhenCallingzesFrequencyGetAvailableClocksThenCallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + EXPECT_NE(handle, nullptr); + uint32_t count = 0; + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); + EXPECT_EQ(numClocks, count); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); + EXPECT_EQ(1, count); + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndCorrectCountWhenCallingzesFrequencyGetAvailableClocksThenCallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + uint32_t count = 0; + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr)); + EXPECT_EQ(numClocks, count); + + double *clocks = new double[count]; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, clocks)); + EXPECT_EQ(numClocks, count); + for (uint32_t i = 0; i < count; i++) { + EXPECT_DOUBLE_EQ(clockValue(pKmdSysManager->mockRpn[domainIndex] + (step * i)), clocks[i]); + } + delete[] clocks; + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetRangeThenVerifyzesFrequencyGetRangeTestCallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + zes_freq_range_t limits; + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits)); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMinFrequencyRange, limits.min); + EXPECT_DOUBLE_EQ(pKmdSysManager->mockMaxFrequencyRange, limits.max); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesFrequencyGetRange(handle, &limits)); + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencySetRangeThenVerifyzesFrequencySetRangeTest1CallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + const double startingMin = 900.0; + const double newMax = 600.0; + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + 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; + 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); + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencySetRangeThenVerifyzesFrequencySetRangeTest2CallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + const double startingMax = 600.0; + const double newMin = 900.0; + + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + 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; + 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); + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetStateThenVerifyCallSucceeds) { + SetUp(true); + + auto handles = get_frequency_handles(frequencyHandleComponentCount); + uint32_t domainIndex = 0; + + for (auto handle : handles) { + zes_freq_state_t state = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetState(handle, &state)); + + if (domainIndex == ZES_FREQ_DOMAIN_GPU) { + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockResolvedFrequency[domainIndex]), state.actual); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockCurrentVoltage), 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); + } else if (domainIndex == ZES_FREQ_DOMAIN_MEMORY) { + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockResolvedFrequency[domainIndex]), state.actual); + EXPECT_DOUBLE_EQ(-1.0, state.currentVoltage); + EXPECT_DOUBLE_EQ(-1.0, state.efficient); + EXPECT_DOUBLE_EQ(-1.0, state.request); + EXPECT_DOUBLE_EQ(-1.0, state.tdp); + EXPECT_EQ(pKmdSysManager->mockThrottleReasons, state.throttleReasons); + } + + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetThrottleTimeThenVerifyCallFails) { + SetUp(true); + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + zes_freq_throttle_time_t throttletime = {}; + EXPECT_NE(ZE_RESULT_SUCCESS, zesFrequencyGetThrottleTime(handle, &throttletime)); + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetCapabilitiesThenVerifyCallSucceeds) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + zes_oc_capabilities_t ocCaps = {}; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetCapabilities(handle, &ocCaps)); + EXPECT_EQ(pKmdSysManager->mockIsExtendedModeSupported[domainIndex], ocCaps.isExtendedModeSupported); + EXPECT_EQ(pKmdSysManager->mockIsFixedModeSupported[domainIndex], ocCaps.isFixedModeSupported); + EXPECT_EQ(pKmdSysManager->mockHighVoltageSupported[domainIndex], ocCaps.isHighVoltModeCapable); + EXPECT_EQ(pKmdSysManager->mockHighVoltageEnabled[domainIndex], ocCaps.isHighVoltModeEnabled); + EXPECT_EQ(pKmdSysManager->mockIsIccMaxSupported, ocCaps.isIccMaxSupported); + EXPECT_EQ(pKmdSysManager->mockIsOcSupported[domainIndex], ocCaps.isOcSupported); + EXPECT_EQ(pKmdSysManager->mockIsTjMaxSupported, ocCaps.isTjMaxSupported); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockMaxFactoryDefaultFrequency[domainIndex]), ocCaps.maxFactoryDefaultFrequency); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockMaxFactoryDefaultVoltage[domainIndex]), ocCaps.maxFactoryDefaultVoltage); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockMaxOcFrequency[domainIndex]), ocCaps.maxOcFrequency); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockMaxOcVoltage[domainIndex]), ocCaps.maxOcVoltage); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockVoltageOffset[domainIndex]), ocCaps.maxOcVoltageOffset); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockVoltageOffset[domainIndex]), ocCaps.minOcVoltageOffset); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetFrequencyTargetThenVerifyCallSucceeds) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double freqTarget = 0.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetFrequencyTarget(handle, &freqTarget)); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockFrequencyTarget[domainIndex]), freqTarget); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetVoltageTargetThenVerifyCallSucceeds) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double voltageTarget = 0.0, voltageOffset = 0.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetVoltageTarget(handle, &voltageTarget, &voltageOffset)); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockVoltageTarget[domainIndex]), voltageTarget); + EXPECT_DOUBLE_EQ(static_cast(pKmdSysManager->mockVoltageOffset[domainIndex]), voltageOffset); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyOcGetModeThenVerifyCallSucceeds) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + zes_oc_mode_t mode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetMode(handle, &mode)); + EXPECT_DOUBLE_EQ(ZES_OC_MODE_INTERPOLATIVE, mode); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToFalseWhenCallingzesFrequencyOcSetFrequencyTargetThenVerifyCallFails) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double freqTarget = 1400.0; + EXPECT_NE(ZE_RESULT_SUCCESS, zesFrequencyOcSetFrequencyTarget(handle, freqTarget)); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToFalseWhenCallingzesFrequencyOcSetVoltageTargetThenVerifyCallFails) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double voltageTarget = 1040.0, voltageOffset = 20.0; + EXPECT_NE(ZE_RESULT_SUCCESS, zesFrequencyOcSetVoltageTarget(handle, voltageTarget, voltageOffset)); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToFalseWhenCallingzesFrequencyOcSetModeThenVerifyCallFails) { + SetUp(false); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + zes_oc_mode_t mode = ZES_OC_MODE_OVERRIDE; + EXPECT_NE(ZE_RESULT_SUCCESS, zesFrequencyOcSetMode(handle, mode)); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToTrueWhenCallingzesFrequencyOcSetFrequencyTargetThenVerifyCallSucceed) { + SetUp(true); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double freqTarget = 1400.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetFrequencyTarget(handle, freqTarget)); + double newFreqTarget = 0.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetFrequencyTarget(handle, &newFreqTarget)); + EXPECT_DOUBLE_EQ(freqTarget, newFreqTarget); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToTrueWhenCallingzesFrequencyOcSetVoltageTargetThenVerifyCallSucceed) { + SetUp(true); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + double voltageTarget = 1040.0, voltageOffset = 20.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetVoltageTarget(handle, voltageTarget, voltageOffset)); + double newVoltageTarget = 1040.0, newVoltageOffset = 20.0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetVoltageTarget(handle, &newVoltageTarget, &newVoltageOffset)); + EXPECT_DOUBLE_EQ(voltageTarget, newVoltageTarget); + EXPECT_DOUBLE_EQ(voltageOffset, newVoltageOffset); + domainIndex++; + } +} + +TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAllowSetCallsToTrueWhenCallingzesFrequencyOcSetModeThenVerifyCallSucceed) { + SetUp(true); + uint32_t domainIndex = 0; + auto handles = get_frequency_handles(frequencyHandleComponentCount); + for (auto handle : handles) { + zes_oc_mode_t mode = ZES_OC_MODE_OVERRIDE; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetMode(handle, mode)); + zes_oc_mode_t newmode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetMode(handle, &newmode)); + EXPECT_EQ(mode, newmode); + + mode = ZES_OC_MODE_INTERPOLATIVE; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetMode(handle, mode)); + newmode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetMode(handle, &newmode)); + EXPECT_EQ(mode, newmode); + + mode = ZES_OC_MODE_FIXED; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetMode(handle, mode)); + newmode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetMode(handle, &newmode)); + EXPECT_EQ(mode, newmode); + + mode = ZES_OC_MODE_OFF; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcSetMode(handle, mode)); + newmode = ZES_OC_MODE_OVERRIDE; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyOcGetMode(handle, &newmode)); + EXPECT_EQ(ZES_OC_MODE_INTERPOLATIVE, newmode); + domainIndex++; + } +} + +} // namespace ult +} // namespace L0