mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-25 05:24:02 +08:00
Update Sysman frequency API as per latest spec
Change-Id: I5bfdb5e5681e9cfa054f48cf8cc4fd8e76740958 Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
887f52d9de
commit
70babc4b69
@@ -238,6 +238,14 @@ zetSysmanPowerSetEnergyThreshold(
|
||||
return L0::Power::fromHandle(hPower)->powerSetEnergyThreshold(threshold);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesDeviceEnumFrequencyDomains(
|
||||
zes_device_handle_t hDevice,
|
||||
uint32_t *pCount,
|
||||
zes_freq_handle_t *phFrequency) {
|
||||
return L0::SysmanDevice::fromHandle(hDevice)->frequencyGet(pCount, phFrequency);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGet(
|
||||
zet_sysman_handle_t hSysman,
|
||||
@@ -246,6 +254,13 @@ zetSysmanFrequencyGet(
|
||||
return L0::Sysman::fromHandle(hSysman)->frequencyGet(pCount, phFrequency);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencyGetProperties(
|
||||
zes_freq_handle_t hFrequency,
|
||||
zes_freq_properties_t *pProperties) {
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetProperties(pProperties);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGetProperties(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
@@ -253,6 +268,14 @@ zetSysmanFrequencyGetProperties(
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetProperties(pProperties);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencyGetAvailableClocks(
|
||||
zes_freq_handle_t hFrequency,
|
||||
uint32_t *pCount,
|
||||
double *phFrequency) {
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetAvailableClocks(pCount, phFrequency);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGetAvailableClocks(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
@@ -261,6 +284,13 @@ zetSysmanFrequencyGetAvailableClocks(
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetAvailableClocks(pCount, phFrequency);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencyGetRange(
|
||||
zes_freq_handle_t hFrequency,
|
||||
zes_freq_range_t *pLimits) {
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetRange(pLimits);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGetRange(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
@@ -268,6 +298,13 @@ zetSysmanFrequencyGetRange(
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetRange(pLimits);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencySetRange(
|
||||
zes_freq_handle_t hFrequency,
|
||||
const zes_freq_range_t *pLimits) {
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencySetRange(pLimits);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencySetRange(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
@@ -275,6 +312,13 @@ zetSysmanFrequencySetRange(
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencySetRange(pLimits);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencyGetState(
|
||||
zes_freq_handle_t hFrequency,
|
||||
zes_freq_state_t *pState) {
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetState(pState);
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGetState(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
@@ -282,6 +326,13 @@ zetSysmanFrequencyGetState(
|
||||
return L0::Frequency::fromHandle(hFrequency)->frequencyGetState(pState);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zesFrequencyGetThrottleTime(
|
||||
zes_freq_handle_t hFrequency,
|
||||
zes_freq_throttle_time_t *pThrottleTime) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
__zedllexport ze_result_t __zecall
|
||||
zetSysmanFrequencyGetThrottleTime(
|
||||
zet_sysman_freq_handle_t hFrequency,
|
||||
|
||||
@@ -38,4 +38,19 @@ ze_result_t FrequencyHandleContext::frequencyGet(uint32_t *pCount, zet_sysman_fr
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FrequencyHandleContext::frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency) {
|
||||
if (nullptr == phFrequency) {
|
||||
*pCount = static_cast<uint32_t>(handle_list.size());
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (Frequency *freq : handle_list) {
|
||||
if (i >= *pCount)
|
||||
break;
|
||||
phFrequency[i++] = freq->toZesFreqHandle();
|
||||
}
|
||||
*pCount = i;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -8,15 +8,23 @@
|
||||
#pragma once
|
||||
#include <level_zero/zet_api.h>
|
||||
|
||||
#include "third_party/level_zero/zes_api_ext.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct _zet_sysman_freq_handle_t {};
|
||||
struct _zet_sysman_freq_handle_t {
|
||||
virtual ~_zet_sysman_freq_handle_t() = default;
|
||||
};
|
||||
|
||||
struct _zes_freq_handle_t {
|
||||
virtual ~_zes_freq_handle_t() = default;
|
||||
};
|
||||
|
||||
namespace L0 {
|
||||
|
||||
struct OsSysman;
|
||||
|
||||
class Frequency : _zet_sysman_freq_handle_t {
|
||||
class Frequency : _zet_sysman_freq_handle_t, _zes_freq_handle_t {
|
||||
public:
|
||||
virtual ~Frequency() {}
|
||||
virtual ze_result_t frequencyGetProperties(zet_freq_properties_t *pProperties) = 0;
|
||||
@@ -25,10 +33,20 @@ class Frequency : _zet_sysman_freq_handle_t {
|
||||
virtual ze_result_t frequencySetRange(const zet_freq_range_t *pLimits) = 0;
|
||||
virtual ze_result_t frequencyGetState(zet_freq_state_t *pState) = 0;
|
||||
|
||||
virtual ze_result_t frequencyGetProperties(zes_freq_properties_t *pProperties) = 0;
|
||||
virtual ze_result_t frequencyGetRange(zes_freq_range_t *pLimits) = 0;
|
||||
virtual ze_result_t frequencySetRange(const zes_freq_range_t *pLimits) = 0;
|
||||
virtual ze_result_t frequencyGetState(zes_freq_state_t *pState) = 0;
|
||||
virtual ze_result_t frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) = 0;
|
||||
|
||||
static Frequency *fromHandle(zet_sysman_freq_handle_t handle) {
|
||||
return static_cast<Frequency *>(handle);
|
||||
}
|
||||
static Frequency *fromHandle(zes_freq_handle_t handle) {
|
||||
return static_cast<Frequency *>(handle);
|
||||
}
|
||||
inline zet_sysman_freq_handle_t toHandle() { return this; }
|
||||
inline zes_freq_handle_t toZesFreqHandle() { return this; }
|
||||
};
|
||||
|
||||
struct FrequencyHandleContext {
|
||||
@@ -38,6 +56,7 @@ struct FrequencyHandleContext {
|
||||
ze_result_t init();
|
||||
|
||||
ze_result_t frequencyGet(uint32_t *pCount, zet_sysman_freq_handle_t *phFrequency);
|
||||
ze_result_t frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency);
|
||||
|
||||
OsSysman *pOsSysman;
|
||||
std::vector<Frequency *> handle_list = {};
|
||||
|
||||
@@ -16,6 +16,88 @@ namespace L0 {
|
||||
const double FrequencyImp::step = 50.0 / 3; // Step of 16.6666667 Mhz (GEN9 Hardcode)
|
||||
const bool FrequencyImp::canControl = true; // canControl is true on i915 (GEN9 Hardcode)
|
||||
|
||||
ze_result_t FrequencyImp::frequencyGetProperties(zes_freq_properties_t *pProperties) {
|
||||
*pProperties = zesFrequencyProperties;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t FrequencyImp::frequencyGetRange(zes_freq_range_t *pLimits) {
|
||||
ze_result_t result = pOsFrequency->getMax(pLimits->max);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
return pOsFrequency->getMin(pLimits->min);
|
||||
}
|
||||
|
||||
ze_result_t FrequencyImp::frequencySetRange(const zes_freq_range_t *pLimits) {
|
||||
double newMin = round(pLimits->min);
|
||||
double newMax = round(pLimits->max);
|
||||
bool newMinValid = false, newMaxValid = false;
|
||||
for (unsigned int i = 0; i < numClocks; i++) {
|
||||
if (newMin == pClocks[i]) {
|
||||
newMinValid = true;
|
||||
}
|
||||
if (newMax == pClocks[i]) {
|
||||
newMaxValid = true;
|
||||
}
|
||||
}
|
||||
if (newMin > newMax || !newMinValid || !newMaxValid) {
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
double currentMax;
|
||||
pOsFrequency->getMax(currentMax);
|
||||
if (newMin > currentMax) {
|
||||
// set the max first
|
||||
ze_result_t result = pOsFrequency->setMax(newMax);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return pOsFrequency->setMin(newMin);
|
||||
}
|
||||
|
||||
// set the min first
|
||||
ze_result_t result = pOsFrequency->setMin(newMin);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
return pOsFrequency->setMax(newMax);
|
||||
}
|
||||
|
||||
ze_result_t FrequencyImp::frequencyGetState(zes_freq_state_t *pState) {
|
||||
ze_result_t result;
|
||||
|
||||
result = pOsFrequency->getRequest(pState->request);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = pOsFrequency->getTdp(pState->tdp);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = pOsFrequency->getEfficient(pState->efficient);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = pOsFrequency->getActual(pState->actual);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
pState->stype = ZES_STRUCTURE_TYPE_FREQ_STATE;
|
||||
pState->pNext = nullptr;
|
||||
pState->currentVoltage = -1.0;
|
||||
pState->throttleReasons = 0u;
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t FrequencyImp::frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t FrequencyImp::frequencyGetProperties(zet_freq_properties_t *pProperties) {
|
||||
*pProperties = frequencyProperties;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
@@ -133,6 +215,22 @@ void FrequencyImp::init() {
|
||||
pClocks[i] = round(frequencyProperties.min + (frequencyProperties.step * i));
|
||||
}
|
||||
frequencyProperties.isThrottleEventSupported = false;
|
||||
|
||||
zesFrequencyProperties.stype = ZES_STRUCTURE_TYPE_FREQ_PROPERTIES;
|
||||
zesFrequencyProperties.pNext = nullptr;
|
||||
zesFrequencyProperties.type = ZES_FREQ_DOMAIN_GPU;
|
||||
zesFrequencyProperties.onSubdevice = false;
|
||||
zesFrequencyProperties.subdeviceId = 0;
|
||||
zesFrequencyProperties.canControl = canControl;
|
||||
ze_result_t result3 = pOsFrequency->getMinVal(zesFrequencyProperties.min);
|
||||
ze_result_t result4 = pOsFrequency->getMaxVal(zesFrequencyProperties.max);
|
||||
// If can't figure out the valid range, then can't control it.
|
||||
if (ZE_RESULT_SUCCESS != result3 || ZE_RESULT_SUCCESS != result4) {
|
||||
zesFrequencyProperties.canControl = false;
|
||||
zesFrequencyProperties.min = 0.0;
|
||||
zesFrequencyProperties.max = 0.0;
|
||||
}
|
||||
zesFrequencyProperties.isThrottleEventSupported = false;
|
||||
}
|
||||
|
||||
FrequencyImp::FrequencyImp(OsSysman *pOsSysman) {
|
||||
|
||||
@@ -23,6 +23,12 @@ class FrequencyImp : public Frequency, NEO::NonCopyableOrMovableClass {
|
||||
ze_result_t frequencySetRange(const zet_freq_range_t *pLimits) override;
|
||||
ze_result_t frequencyGetState(zet_freq_state_t *pState) override;
|
||||
|
||||
ze_result_t frequencyGetProperties(zes_freq_properties_t *pProperties) override;
|
||||
ze_result_t frequencyGetRange(zes_freq_range_t *pLimits) override;
|
||||
ze_result_t frequencySetRange(const zes_freq_range_t *pLimits) override;
|
||||
ze_result_t frequencyGetState(zes_freq_state_t *pState) override;
|
||||
ze_result_t frequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) override;
|
||||
|
||||
FrequencyImp() = default;
|
||||
FrequencyImp(OsSysman *pOsSysman);
|
||||
~FrequencyImp() override;
|
||||
@@ -34,6 +40,7 @@ class FrequencyImp : public Frequency, NEO::NonCopyableOrMovableClass {
|
||||
static const bool canControl;
|
||||
|
||||
zet_freq_properties_t frequencyProperties = {};
|
||||
zes_freq_properties_t zesFrequencyProperties = {};
|
||||
double *pClocks = nullptr;
|
||||
uint32_t numClocks = 0;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h"
|
||||
|
||||
#include "sysman/linux/os_sysman_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
|
||||
const std::string LinuxFrequencyImp::minFreqFile("gt_min_freq_mhz");
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "sysman/frequency/frequency_imp.h"
|
||||
#include "sysman/frequency/os_frequency.h"
|
||||
#include "sysman/linux/fs_access.h"
|
||||
#include "sysman/linux/os_sysman_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ struct SysmanDevice : _ze_device_handle_t {
|
||||
static SysmanDevice *fromHandle(zes_device_handle_t handle) { return Device::fromHandle(handle)->getSysmanHandle(); }
|
||||
|
||||
virtual ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) = 0;
|
||||
virtual ze_result_t frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency) = 0;
|
||||
virtual ~SysmanDevice() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,11 +23,13 @@ SysmanDeviceImp::SysmanDeviceImp(ze_device_handle_t hDevice) {
|
||||
pOsSysman = OsSysman::create(this);
|
||||
UNRECOVERABLE_IF(nullptr == pOsSysman);
|
||||
pPowerHandleContext = new PowerHandleContext(pOsSysman);
|
||||
pFrequencyHandleContext = new FrequencyHandleContext(pOsSysman);
|
||||
}
|
||||
|
||||
SysmanDeviceImp::~SysmanDeviceImp() {
|
||||
freeResource(pOsSysman);
|
||||
freeResource(pPowerHandleContext);
|
||||
freeResource(pFrequencyHandleContext);
|
||||
}
|
||||
|
||||
void SysmanDeviceImp::init() {
|
||||
@@ -35,6 +37,9 @@ void SysmanDeviceImp::init() {
|
||||
if (pPowerHandleContext) {
|
||||
pPowerHandleContext->init();
|
||||
}
|
||||
if (pFrequencyHandleContext) {
|
||||
pFrequencyHandleContext->init();
|
||||
}
|
||||
}
|
||||
|
||||
SysmanImp::SysmanImp(ze_device_handle_t hDevice) {
|
||||
@@ -199,6 +204,10 @@ ze_result_t SysmanImp::frequencyGet(uint32_t *pCount, zet_sysman_freq_handle_t *
|
||||
return pFrequencyHandleContext->frequencyGet(pCount, phFrequency);
|
||||
}
|
||||
|
||||
ze_result_t SysmanDeviceImp::frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency) {
|
||||
return pFrequencyHandleContext->frequencyGet(pCount, phFrequency);
|
||||
}
|
||||
|
||||
ze_result_t SysmanImp::engineGet(uint32_t *pCount, zet_sysman_engine_handle_t *phEngine) {
|
||||
return pEngineHandleContext->engineGet(pCount, phEngine);
|
||||
}
|
||||
|
||||
@@ -93,8 +93,10 @@ struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass {
|
||||
|
||||
OsSysman *pOsSysman = nullptr;
|
||||
PowerHandleContext *pPowerHandleContext = nullptr;
|
||||
FrequencyHandleContext *pFrequencyHandleContext = nullptr;
|
||||
|
||||
ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) override;
|
||||
ze_result_t frequencyGet(uint32_t *pCount, zes_freq_handle_t *phFrequency) override;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
|
||||
@@ -6,20 +6,8 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "level_zero/core/test/unit_tests/mock.h"
|
||||
#include "level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h"
|
||||
|
||||
#include "sysman/frequency/frequency_imp.h"
|
||||
#include "sysman/frequency/os_frequency.h"
|
||||
#include "sysman/linux/fs_access.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
|
||||
#endif
|
||||
|
||||
using ::testing::_;
|
||||
|
||||
namespace L0 {
|
||||
namespace ult {
|
||||
|
||||
@@ -45,8 +33,40 @@ struct Mock<FrequencySysfsAccess> : public FrequencySysfsAccess {
|
||||
double mockMaxVal = 0;
|
||||
double mockMinVal = 0;
|
||||
|
||||
MOCK_METHOD2(read, ze_result_t(const std::string file, double &val));
|
||||
MOCK_METHOD2(write, ze_result_t(const std::string file, const double val));
|
||||
MOCK_METHOD(ze_result_t, read, (const std::string file, double &val), (override));
|
||||
MOCK_METHOD(ze_result_t, write, (const std::string file, const double val), (override));
|
||||
|
||||
ze_result_t getValReturnError(const std::string file, double &val) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
ze_result_t getValActualReturnError(const std::string file, double &val) {
|
||||
if (file.compare(actualFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t getValEfficientReturnError(const std::string file, double &val) {
|
||||
if (file.compare(efficientFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t getValTdpReturnError(const std::string file, double &val) {
|
||||
if (file.compare(tdpFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t getValRequestReturnError(const std::string file, double &val) {
|
||||
if (file.compare(requestFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t getVal(const std::string file, double &val) {
|
||||
if (file.compare(minFreqFile) == 0) {
|
||||
@@ -75,6 +95,21 @@ struct Mock<FrequencySysfsAccess> : public FrequencySysfsAccess {
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t setValMinReturnError(const std::string file, const double val) {
|
||||
if (file.compare(minFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t setValMaxReturnError(const std::string file, const double val) {
|
||||
if (file.compare(maxFreqFile) == 0) {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t setVal(const std::string file, const double val) {
|
||||
if (file.compare(minFreqFile) == 0) {
|
||||
mockMin = val;
|
||||
@@ -113,8 +148,4 @@ class PublicLinuxFrequencyImp : public L0::LinuxFrequencyImp {
|
||||
};
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
} // namespace L0
|
||||
@@ -5,9 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
|
||||
#include "level_zero/tools/source/sysman/frequency/linux/os_frequency_imp.h"
|
||||
#include "level_zero/tools/source/sysman/sysman_imp.h"
|
||||
#include "level_zero/tools/test/unit_tests/sources/sysman/mock_sysman_fixture.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -15,13 +13,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::Matcher;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
|
||||
namespace L0 {
|
||||
namespace ult {
|
||||
@@ -36,6 +28,301 @@ constexpr double efficient = 300.0;
|
||||
constexpr double maxVal = 1100.0;
|
||||
constexpr double minVal = 300.0;
|
||||
constexpr uint32_t numClocks = static_cast<uint32_t>((maxFreq - minFreq) / step) + 1;
|
||||
constexpr uint32_t handleComponentCount = 1u;
|
||||
class SysmanDeviceFrequencyFixture : public SysmanDeviceFixture {
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Mock<FrequencySysfsAccess>> pSysfsAccess;
|
||||
SysfsAccess *pSysfsAccessOld = nullptr;
|
||||
|
||||
void SetUp() override {
|
||||
SysmanDeviceFixture::SetUp();
|
||||
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
|
||||
pSysfsAccess = std::make_unique<NiceMock<Mock<FrequencySysfsAccess>>>();
|
||||
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
|
||||
|
||||
pSysfsAccess->setVal(minFreqFile, minFreq);
|
||||
pSysfsAccess->setVal(maxFreqFile, maxFreq);
|
||||
pSysfsAccess->setVal(requestFreqFile, request);
|
||||
pSysfsAccess->setVal(tdpFreqFile, tdp);
|
||||
pSysfsAccess->setVal(actualFreqFile, actual);
|
||||
pSysfsAccess->setVal(efficientFreqFile, efficient);
|
||||
pSysfsAccess->setVal(maxValFreqFile, maxVal);
|
||||
pSysfsAccess->setVal(minValFreqFile, minVal);
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getVal));
|
||||
ON_CALL(*pSysfsAccess.get(), write(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::setVal));
|
||||
|
||||
// delete handles created in initial SysmanDeviceHandleContext::init() call
|
||||
for (auto handle : pSysmanDeviceImp->pFrequencyHandleContext->handle_list) {
|
||||
delete handle;
|
||||
}
|
||||
pSysmanDeviceImp->pFrequencyHandleContext->handle_list.clear();
|
||||
pSysmanDeviceImp->pFrequencyHandleContext->init();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
SysmanDeviceFixture::TearDown();
|
||||
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
|
||||
}
|
||||
|
||||
double clockValue(const double calculatedClock) {
|
||||
// i915 specific. frequency step is a fraction
|
||||
// However, the i915 represents all clock
|
||||
// rates as integer values. So clocks are
|
||||
// rounded to the nearest integer.
|
||||
uint32_t actualClock = static_cast<uint32_t>(calculatedClock + 0.5);
|
||||
return static_cast<double>(actualClock);
|
||||
}
|
||||
|
||||
std::vector<zes_freq_handle_t> get_freq_handles(uint32_t count) {
|
||||
std::vector<zes_freq_handle_t> handles(count, nullptr);
|
||||
EXPECT_EQ(zesDeviceEnumFrequencyDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
|
||||
return handles;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenComponentCountZeroWhenEnumeratingFrequencyHandlesThenNonZeroCountIsReturnedAndCallSucceds) {
|
||||
uint32_t count;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumFrequencyDomains(device->toHandle(), &count, nullptr));
|
||||
EXPECT_EQ(count, handleComponentCount);
|
||||
|
||||
uint32_t testCount = count + 1;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumFrequencyDomains(device->toHandle(), &testCount, nullptr));
|
||||
EXPECT_EQ(count, testCount);
|
||||
|
||||
auto handles = get_freq_handles(count);
|
||||
for (auto handle : handles) {
|
||||
EXPECT_NE(handle, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenActualComponentCountTwoWhenTryingToGetOneComponentOnlyThenOneComponentIsReturnedAndCountUpdated) {
|
||||
auto pFrequencyHandleContextTest = std::make_unique<FrequencyHandleContext>(pOsSysman);
|
||||
pFrequencyHandleContextTest->handle_list.push_back(new FrequencyImp(pOsSysman));
|
||||
pFrequencyHandleContextTest->handle_list.push_back(new FrequencyImp(pOsSysman));
|
||||
|
||||
uint32_t count = 1;
|
||||
std::vector<zes_freq_handle_t> phFrequency(count, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, pFrequencyHandleContextTest->frequencyGet(&count, phFrequency.data()));
|
||||
EXPECT_EQ(count, 1u);
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetPropertiesThenSuccessIsReturned) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
EXPECT_NE(handle, nullptr);
|
||||
zes_freq_properties_t properties;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetProperties(handle, &properties));
|
||||
EXPECT_EQ(ZES_STRUCTURE_TYPE_FREQ_PROPERTIES, properties.stype);
|
||||
EXPECT_EQ(nullptr, properties.pNext);
|
||||
EXPECT_EQ(ZES_FREQ_DOMAIN_GPU, properties.type);
|
||||
EXPECT_FALSE(properties.onSubdevice);
|
||||
EXPECT_DOUBLE_EQ(maxFreq, properties.max);
|
||||
EXPECT_DOUBLE_EQ(minFreq, properties.min);
|
||||
EXPECT_TRUE(properties.canControl);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndZeroCountWhenCallingzesFrequencyGetAvailableClocksThenCallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
EXPECT_NE(handle, nullptr);
|
||||
uint32_t count = 0;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetAvailableClocks(handle, &count, nullptr));
|
||||
EXPECT_EQ(numClocks, count);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleAndCorrectCountWhenCallingzesFrequencyGetAvailableClocksThenCallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
uint32_t count = 0;
|
||||
|
||||
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(minFreq + (step * i)), clocks[i]);
|
||||
}
|
||||
delete[] clocks;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidateFrequencyGetRangeWhengetMaxFailsThenFrequencyGetRangeCallShouldFail) {
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getValReturnError));
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limit = {};
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencyGetRange(&limit));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetRangeThenVerifyzesFrequencyGetRangeTestCallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
zes_freq_range_t limits;
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetRange(handle, &limits));
|
||||
EXPECT_DOUBLE_EQ(minFreq, limits.min);
|
||||
EXPECT_DOUBLE_EQ(maxFreq, limits.max);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyLimitsWhenCallingFrequencySetRangeForFailures1ThenAPIExitsGracefully) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits = {};
|
||||
|
||||
// Verify that Max must be within range.
|
||||
limits.min = minFreq;
|
||||
limits.max = 600.0;
|
||||
ON_CALL(*pSysfsAccess.get(), write(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::setValMinReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyLimitsWhenCallingFrequencySetRangeForFailures2ThenAPIExitsGracefully) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits = {};
|
||||
|
||||
// Verify that Max must be within range.
|
||||
limits.min = 900.0;
|
||||
limits.max = maxFreq;
|
||||
ON_CALL(*pSysfsAccess.get(), write(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::setValMaxReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencySetRangeThenVerifyzesFrequencySetRangeTest1CallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
const double startingMin = 900.0;
|
||||
const double newMax = 600.0;
|
||||
zes_freq_range_t limits;
|
||||
|
||||
pSysfsAccess->setVal(minFreqFile, 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);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencySetRangeThenVerifyzesFrequencySetRangeTest2CallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
const double startingMax = 600.0;
|
||||
const double newMin = 900.0;
|
||||
zes_freq_range_t limits;
|
||||
|
||||
pSysfsAccess->setVal(maxFreqFile, 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);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest1ReturnsError) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits;
|
||||
|
||||
// Verify that Max must be within range.
|
||||
limits.min = minFreq;
|
||||
limits.max = clockValue(maxFreq + step);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest2ReturnsError) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits;
|
||||
|
||||
// Verify that Min must be within range.
|
||||
limits.min = clockValue(minFreq - step);
|
||||
limits.max = maxFreq;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest3ReturnsError) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits;
|
||||
|
||||
// Verify that values must be multiples of step.
|
||||
limits.min = clockValue(minFreq + (step * 0.5));
|
||||
limits.max = maxFreq;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenInvalidFrequencyLimitsWhenCallingFrequencySetRangeThenVerifyFrequencySetRangeTest4ReturnsError) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_range_t limits;
|
||||
|
||||
// Verify that Max must be greater than min range.
|
||||
limits.min = clockValue(maxFreq + step);
|
||||
limits.max = minFreq;
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, pFrequencyImp->frequencySetRange(&limits));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidFrequencyHandleWhenCallingzesFrequencyGetStateThenVerifyzesFrequencyGetStateTestCallSucceeds) {
|
||||
auto handles = get_freq_handles(handleComponentCount);
|
||||
for (auto handle : handles) {
|
||||
const double testRequestValue = 450.0;
|
||||
const double testTdpValue = 1200.0;
|
||||
const double testEfficientValue = 400.0;
|
||||
const double testActualValue = 550.0;
|
||||
zes_freq_state_t state;
|
||||
|
||||
pSysfsAccess->setVal(requestFreqFile, testRequestValue);
|
||||
pSysfsAccess->setVal(tdpFreqFile, testTdpValue);
|
||||
pSysfsAccess->setVal(actualFreqFile, testActualValue);
|
||||
pSysfsAccess->setVal(efficientFreqFile, testEfficientValue);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, zesFrequencyGetState(handle, &state));
|
||||
EXPECT_DOUBLE_EQ(testRequestValue, state.request);
|
||||
EXPECT_DOUBLE_EQ(testTdpValue, state.tdp);
|
||||
EXPECT_DOUBLE_EQ(testEfficientValue, state.efficient);
|
||||
EXPECT_DOUBLE_EQ(testActualValue, state.actual);
|
||||
EXPECT_EQ(0u, state.throttleReasons);
|
||||
EXPECT_EQ(nullptr, state.pNext);
|
||||
EXPECT_EQ(ZES_STRUCTURE_TYPE_FREQ_STATE, state.stype);
|
||||
EXPECT_LE(state.currentVoltage, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenValidStatePointerWhenValidatingfrequencyGetStateForFailuresThenAPIExitsGracefully) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_state_t state = {};
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getValRequestReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencyGetState(&state));
|
||||
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getValTdpReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencyGetState(&state));
|
||||
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getValEfficientReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencyGetState(&state));
|
||||
|
||||
ON_CALL(*pSysfsAccess.get(), read(_, _))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<FrequencySysfsAccess>::getValActualReturnError));
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pFrequencyImp->frequencyGetState(&state));
|
||||
}
|
||||
|
||||
TEST_F(SysmanDeviceFrequencyFixture, GivenThrottleTimeStructPointerWhenCallingfrequencyGetThrottleTimeThenUnsupportedIsReturned) {
|
||||
auto pFrequencyImp = std::make_unique<FrequencyImp>(pOsSysman);
|
||||
zes_freq_throttle_time_t throttleTime = {};
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pFrequencyImp->frequencyGetThrottleTime(&throttleTime));
|
||||
}
|
||||
|
||||
class SysmanFrequencyFixture : public DeviceFixture, public ::testing::Test {
|
||||
|
||||
@@ -273,4 +560,4 @@ TEST_F(SysmanFrequencyFixture, GivenValidFrequencyHandleWhenCallingzetSysmanFreq
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
} // namespace L0
|
||||
Reference in New Issue
Block a user