Add support for power limit ext functions

Add support for getPowerLimitsExt and
setPowerLimitsExt functions.

Related-To: LOCI-3125, LOCI-3193

Signed-off-by: Bellekallu Rajkiran <bellekallu.rajkiran@intel.com>
This commit is contained in:
Bellekallu Rajkiran
2022-07-11 13:55:10 +00:00
committed by Compute-Runtime-Automation
parent 4cb9ad5d55
commit d02b45c9b9
5 changed files with 677 additions and 17 deletions

View File

@ -17,9 +17,9 @@ namespace L0 {
const std::string LinuxPowerImp::hwmonDir("device/hwmon");
const std::string LinuxPowerImp::i915("i915");
const std::string LinuxPowerImp::sustainedPowerLimit("power1_max");
const std::string LinuxPowerImp::criticalPowerLimit("power1_crit");
const std::string LinuxPowerImp::sustainedPowerLimitInterval("power1_max_interval");
const std::string LinuxPowerImp::energyCounterNode("energy1_input");
const std::string LinuxPowerImp::defaultPowerLimit("power1_max_default");
const std::string LinuxPowerImp::defaultPowerLimit("power1_rated_max");
void powerGetTimestamp(uint64_t &timestamp) {
std::chrono::time_point<std::chrono::steady_clock> ts = std::chrono::steady_clock::now();
@ -77,7 +77,7 @@ ze_result_t LinuxPowerImp::getLimits(zes_power_sustained_limit_t *pSustained, ze
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
val /= milliFactor; // Convert microWatts to milliwatts
val /= milliFactor; // Convert microwatts to milliwatts
pSustained->power = static_cast<int32_t>(val);
pSustained->enabled = true;
pSustained->interval = -1;
@ -91,7 +91,7 @@ ze_result_t LinuxPowerImp::getLimits(zes_power_sustained_limit_t *pSustained, ze
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
val /= milliFactor; // Convert microWatts to milliwatts
val /= milliFactor; // Convert microwatts to milliwatts
pPeak->powerAC = static_cast<int32_t>(val);
pPeak->powerDC = -1;
}
@ -105,14 +105,14 @@ ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustain
if (!isSubdevice) {
int32_t val = 0;
if (pSustained != nullptr) {
val = static_cast<uint32_t>(pSustained->power) * milliFactor; // Convert milliWatts to microwatts
val = static_cast<uint32_t>(pSustained->power) * milliFactor; // Convert milliwatts to microwatts
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimit, val);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
}
if (pPeak != nullptr) {
val = static_cast<uint32_t>(pPeak->powerAC) * milliFactor; // Convert milliWatts to microwatts
val = static_cast<uint32_t>(pPeak->powerAC) * milliFactor; // Convert milliwatts to microwatts
result = pSysfsAccess->write(i915HwmonDir + "/" + criticalPowerLimit, val);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
@ -124,11 +124,95 @@ ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustain
}
ze_result_t LinuxPowerImp::getLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
ze_result_t result = ZE_RESULT_SUCCESS;
if ((*pCount == 0) || (powerLimitCount < *pCount)) {
*pCount = powerLimitCount;
}
if (pSustained != nullptr) {
uint64_t val = 0;
uint8_t count = 0;
if (count < *pCount) {
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimit, val);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
int32_t interval = 0;
result = pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimitInterval, interval);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
val /= milliFactor; // Convert microwatts to milliwatts
pSustained[count].limit = static_cast<int32_t>(val);
pSustained[count].enabledStateLocked = true;
pSustained[count].intervalValueLocked = false;
pSustained[count].limitValueLocked = false;
pSustained[count].source = ZES_POWER_SOURCE_ANY;
pSustained[count].level = ZES_POWER_LEVEL_SUSTAINED;
pSustained[count].limitUnit = ZES_LIMIT_UNIT_POWER;
pSustained[count].interval = interval;
count++;
}
if (count < *pCount) {
result = pSysfsAccess->read(i915HwmonDir + "/" + criticalPowerLimit, val);
if (result != ZE_RESULT_SUCCESS) {
return getErrorCode(result);
}
pSustained[count].enabledStateLocked = true;
pSustained[count].intervalValueLocked = true;
pSustained[count].limitValueLocked = false;
pSustained[count].source = ZES_POWER_SOURCE_ANY;
pSustained[count].level = ZES_POWER_LEVEL_PEAK;
pSustained[count].interval = 0; // Hardcode to 100 micro seconds i.e 0.1 milli seconds
if ((productFamily == IGFX_PVC) || (productFamily == IGFX_XE_HP_SDV)) {
pSustained[count].limit = static_cast<int32_t>(val);
pSustained[count].limitUnit = ZES_LIMIT_UNIT_CURRENT;
} else {
val /= milliFactor; // Convert microwatts to milliwatts
pSustained[count].limit = static_cast<int32_t>(val);
pSustained[count].limitUnit = ZES_LIMIT_UNIT_POWER;
}
}
}
return result;
}
ze_result_t LinuxPowerImp::setLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
ze_result_t result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
if (!isSubdevice) {
uint64_t val = 0;
for (uint32_t i = 0; i < *pCount; i++) {
if (pSustained[i].level == ZES_POWER_LEVEL_SUSTAINED) {
val = pSustained[i].limit * milliFactor; // Convert milliwatts to microwatts
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimit, val);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimitInterval, pSustained[i].interval);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
} else if (pSustained[i].level == ZES_POWER_LEVEL_PEAK) {
if ((productFamily == IGFX_PVC) || (productFamily == IGFX_XE_HP_SDV)) {
val = pSustained[i].limit;
} else {
val = pSustained[i].limit * milliFactor; // Convert milliwatts to microwatts
}
result = pSysfsAccess->write(i915HwmonDir + "/" + criticalPowerLimit, val);
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
} else {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
}
result = ZE_RESULT_SUCCESS;
}
return result;
}
ze_result_t LinuxPowerImp::getEnergyThreshold(zes_energy_threshold_t *pThreshold) {
@ -174,6 +258,18 @@ bool LinuxPowerImp::isPowerModuleSupported() {
canControl = isSubdevice ? false : true;
}
}
if (!isSubdevice) {
uint64_t val = 0;
if (ZE_RESULT_SUCCESS == pSysfsAccess->read(i915HwmonDir + "/" + sustainedPowerLimit, val)) {
powerLimitCount++;
}
if (ZE_RESULT_SUCCESS == pSysfsAccess->read(i915HwmonDir + "/" + criticalPowerLimit, val)) {
powerLimitCount++;
}
}
if (hwmonDirExists == false) {
return (pPmt != nullptr);
}
@ -184,6 +280,12 @@ LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pPmt = pLinuxSysmanImp->getPlatformMonitoringTechAccess(subdeviceId);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
productFamily = pLinuxSysmanImp->getProductFamily();
if ((productFamily == IGFX_PVC) || (productFamily == IGFX_XE_HP_SDV)) {
criticalPowerLimit = "curr1_crit";
} else {
criticalPowerLimit = "power1_crit";
}
}
OsPower *OsPower::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {

View File

@ -10,6 +10,8 @@
#include "level_zero/tools/source/sysman/power/os_power.h"
#include "igfxfmid.h"
#include <memory>
#include <string>
@ -41,15 +43,18 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
private:
std::string i915HwmonDir;
std::string criticalPowerLimit;
static const std::string hwmonDir;
static const std::string i915;
static const std::string sustainedPowerLimit;
static const std::string criticalPowerLimit;
static const std::string sustainedPowerLimitInterval;
static const std::string energyCounterNode;
static const std::string defaultPowerLimit;
bool canControl = false;
bool isSubdevice = false;
uint32_t subdeviceId = 0;
uint32_t powerLimitCount = 0;
PRODUCT_FAMILY productFamily{};
ze_result_t getErrorCode(ze_result_t result) {
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {

View File

@ -25,6 +25,7 @@ namespace L0 {
namespace ult {
constexpr uint64_t setEnergyCounter = (83456u * 1048576u);
constexpr uint64_t offset = 0x400;
constexpr uint32_t mockLimitCount = 2u;
const std::string deviceName("device");
const std::string baseTelemSysFS("/sys/class/intel_pmt");
const std::string hwmonDir("device/hwmon");
@ -34,9 +35,11 @@ const std::string i915HwmonDirTile0("device/hwmon/hwmon3");
const std::string i915HwmonDirTile1("device/hwmon/hwmon4");
const std::vector<std::string> listOfMockedHwmonDirs = {"hwmon0", "hwmon1", "hwmon2", "hwmon3", "hwmon4"};
const std::string sustainedPowerLimit("power1_max");
const std::string criticalPowerLimit("power1_crit");
const std::string sustainedPowerLimitInterval("power1_max_interval");
const std::string criticalPowerLimit1("curr1_crit");
const std::string criticalPowerLimit2("power1_crit");
const std::string energyCounterNode("energy1_input");
const std::string defaultPowerLimit("power1_max_default");
const std::string defaultPowerLimit("power1_rated_max");
constexpr uint64_t expectedEnergyCounter = 123456785u;
constexpr uint64_t expectedEnergyCounterTile0 = 123456785u;
constexpr uint64_t expectedEnergyCounterTile1 = 128955785u;
@ -53,7 +56,11 @@ template <>
struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
ze_result_t mockReadResult = ZE_RESULT_SUCCESS;
ze_result_t mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS;
ze_result_t mockReadPeakResult = ZE_RESULT_SUCCESS;
ze_result_t mockWriteResult = ZE_RESULT_SUCCESS;
ze_result_t mockWriteUnsignedResult = ZE_RESULT_SUCCESS;
ze_result_t mockReadIntResult = ZE_RESULT_SUCCESS;
ze_result_t mockWritePeakLimitResult = ZE_RESULT_SUCCESS;
ze_result_t mockscanDirEntriesResult = ZE_RESULT_SUCCESS;
ze_result_t getValString(const std::string file, std::string &val) {
@ -78,13 +85,17 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
uint64_t sustainedPowerLimitVal = 0;
uint64_t criticalPowerLimitVal = 0;
int32_t sustainedPowerLimitIntervalVal = 0;
ze_result_t getValUnsignedLongHelper(const std::string file, uint64_t &val);
ze_result_t getValUnsignedLong(const std::string file, uint64_t &val) {
ze_result_t result = ZE_RESULT_SUCCESS;
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
val = sustainedPowerLimitVal;
} else if (file.compare(i915HwmonDir + "/" + criticalPowerLimit) == 0) {
} else if ((file.compare(i915HwmonDir + "/" + criticalPowerLimit1) == 0) || (file.compare(i915HwmonDir + "/" + criticalPowerLimit2) == 0)) {
if (mockReadPeakResult != ZE_RESULT_SUCCESS) {
return mockReadPeakResult;
}
val = criticalPowerLimitVal;
} else if (file.compare(i915HwmonDirTile0 + "/" + energyCounterNode) == 0) {
val = expectedEnergyCounterTile0;
@ -113,7 +124,12 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
ze_result_t result = ZE_RESULT_SUCCESS;
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
sustainedPowerLimitVal = static_cast<uint64_t>(val);
} else if (file.compare(i915HwmonDir + "/" + criticalPowerLimit) == 0) {
} else if ((file.compare(i915HwmonDir + "/" + sustainedPowerLimitInterval) == 0)) {
sustainedPowerLimitIntervalVal = val;
} else if ((file.compare(i915HwmonDir + "/" + criticalPowerLimit1) == 0) || (file.compare(i915HwmonDir + "/" + criticalPowerLimit2) == 0)) {
if (mockWritePeakLimitResult != ZE_RESULT_SUCCESS) {
return mockWritePeakLimitResult;
}
criticalPowerLimitVal = static_cast<uint64_t>(val);
} else {
result = ZE_RESULT_ERROR_NOT_AVAILABLE;
@ -138,6 +154,19 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
return getValUnsignedLong(file, val);
}
ze_result_t read(const std::string file, int32_t &val) override {
if (mockReadIntResult != ZE_RESULT_SUCCESS) {
return mockReadIntResult;
}
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimitInterval) == 0) {
val = sustainedPowerLimitIntervalVal;
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
ze_result_t read(const std::string file, std::string &val) override {
if (mockReadResult != ZE_RESULT_SUCCESS) {
return mockReadResult;
@ -161,6 +190,26 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
return setVal(file, val);
}
ze_result_t write(const std::string file, const uint64_t val) override {
ze_result_t result = ZE_RESULT_SUCCESS;
if (mockWriteUnsignedResult != ZE_RESULT_SUCCESS) {
return mockWriteUnsignedResult;
}
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
sustainedPowerLimitVal = val;
} else if ((file.compare(i915HwmonDir + "/" + criticalPowerLimit1) == 0) || (file.compare(i915HwmonDir + "/" + criticalPowerLimit2) == 0)) {
if (mockWritePeakLimitResult != ZE_RESULT_SUCCESS) {
return mockWritePeakLimitResult;
}
criticalPowerLimitVal = val;
} else {
result = ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return result;
}
ze_result_t scanDirEntries(const std::string file, std::vector<std::string> &listOfEntries) override {
if (mockscanDirEntriesResult != ZE_RESULT_SUCCESS) {
return mockscanDirEntriesResult;

View File

@ -95,6 +95,28 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenScanDiectoriesFailAndPmtI
EXPECT_EQ(zesDeviceGetCardPowerDomain(device->toHandle(), &phPower), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE);
}
TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenReadingToSysNodesFailsWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) {
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
for (auto &pmtMapElement : pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject) {
if (pmtMapElement.first == 0) {
delete pmtMapElement.second;
pmtMapElement.second = nullptr;
}
}
pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle());
auto handles = getPowerHandles(powerHandleComponentCountMultiDevice);
for (auto handle : handles) {
uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr));
EXPECT_EQ(count, 0u);
}
}
TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) {
auto handles = getPowerHandles(powerHandleComponentCountMultiDevice);
@ -152,5 +174,217 @@ TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenSetPowerLimitsWhenGetting
}
}
HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsXEHP) {
auto handles = getPowerHandles(powerHandleComponentCountMultiDevice);
for (auto handle : handles) {
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
zes_power_properties_t properties = {};
zes_power_limit_ext_desc_t limits = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties));
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, &limits));
EXPECT_EQ(limitCount, 0u);
}
limitCount++;
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, 0u);
}
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(limitCount, 0u);
}
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
} else {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
}
}
}
HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsPVC) {
auto handles = getPowerHandles(powerHandleComponentCountMultiDevice);
for (auto handle : handles) {
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
zes_power_properties_t properties = {};
zes_power_limit_ext_desc_t limits = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties));
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, &limits));
EXPECT_EQ(limitCount, 0u);
}
limitCount++;
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, 0u);
}
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(limitCount, 0u);
}
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
} else {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
}
}
}
HWTEST2_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsDG1) {
auto handles = getPowerHandles(powerHandleComponentCountMultiDevice);
for (auto handle : handles) {
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
zes_power_properties_t properties = {};
zes_power_limit_ext_desc_t limits = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetProperties(handle, &properties));
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, &limits));
EXPECT_EQ(limitCount, 0u);
}
limitCount++;
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, 0u);
}
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
} else {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(limitCount, 0u);
}
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
if (!properties.onSubdevice) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
} else {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
}
}
}
} // namespace ult
} // namespace L0

View File

@ -226,13 +226,147 @@ TEST_F(SysmanDevicePowerFixture, GivenSetPowerLimitsWhenGettingPowerLimitsWhenHw
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtWhenHwmonInterfaceExistThenUnsupportedFeatureIsReturned) {
HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsPVC) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
uint32_t limitCount = 0;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &limitCount, nullptr));
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
limitCount++;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
}
}
HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsDG1) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
limitCount++;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
}
}
HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved, IsXEHP) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
uint32_t limitCount = 0;
const int32_t testLimit = 3000000;
const int32_t testInterval = 10;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
limitCount++;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, nullptr));
EXPECT_EQ(limitCount, mockLimitCount);
std::vector<zes_power_limit_ext_desc_t> allLimits(limitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_FALSE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
allLimits[i].interval = testInterval;
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_FALSE(allLimits[i].limitValueLocked);
EXPECT_TRUE(allLimits[i].enabledStateLocked);
EXPECT_TRUE(allLimits[i].intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits[i].source);
EXPECT_EQ(ZES_LIMIT_UNIT_CURRENT, allLimits[i].limitUnit);
allLimits[i].limit = testLimit;
}
}
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimitsExt(handle, &limitCount, allLimits.data()));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &limitCount, allLimits.data()));
for (uint32_t i = 0; i < limitCount; i++) {
if (allLimits[i].level == ZES_POWER_LEVEL_SUSTAINED) {
EXPECT_EQ(testInterval, allLimits[i].interval);
} else if (allLimits[i].level == ZES_POWER_LEVEL_PEAK) {
EXPECT_EQ(0, allLimits[i].interval);
}
EXPECT_EQ(testLimit, allLimits[i].limit);
}
}
}
@ -251,6 +385,142 @@ TEST_F(SysmanDevicePowerFixture, GivenReadingSustainedPowerLimitNodeReturnErrorW
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToSustainedLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
pSysfsAccess->mockWriteResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data()));
pSysfsAccess->mockWriteUnsignedResult = ZE_RESULT_SUCCESS;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data()));
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndReadingToSustainedLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_SUCCESS;
count = mockLimitCount;
pSysfsAccess->mockReadIntResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
}
}
TEST_F(SysmanDevicePowerFixture, GivenReadingToSysNodesFailsWhenCallingGetPowerLimitsExtThenPowerLimitCountIsZero) {
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysfsAccess->mockReadValUnsignedLongResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle());
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr));
EXPECT_EQ(count, 0u);
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
pSysfsAccess->mockWritePeakLimitResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data()));
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndReadingToPeakLimitSysNodesFailsWhenCallingGetPowerLimitsExtThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
pSysfsAccess->mockReadPeakResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingBurstPowerLimitThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_limit_ext_desc_t allLimits{};
uint32_t count = 1;
allLimits.level = ZES_POWER_LEVEL_BURST;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, &allLimits));
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenProperValuesAreReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_limit_ext_desc_t allLimits{};
uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, nullptr));
EXPECT_EQ(count, mockLimitCount);
count = 1;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, &allLimits));
EXPECT_EQ(count, 1u);
EXPECT_EQ(false, allLimits.limitValueLocked);
EXPECT_EQ(true, allLimits.enabledStateLocked);
EXPECT_EQ(false, allLimits.intervalValueLocked);
EXPECT_EQ(ZES_POWER_SOURCE_ANY, allLimits.source);
EXPECT_EQ(ZES_LIMIT_UNIT_POWER, allLimits.limitUnit);
EXPECT_EQ(ZES_POWER_LEVEL_SUSTAINED, allLimits.level);
}
}
HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned, IsPVC) {
auto handles = getPowerHandles(powerHandleComponentCount);
pSysfsAccess->mockWritePeakLimitResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data()));
}
}
HWTEST2_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndWritingToPeakLimitSysNodesFailsWhenCallingSetPowerLimitsExtThenProperErrorCodesReturned, IsDG1) {
auto handles = getPowerHandles(powerHandleComponentCount);
pSysfsAccess->mockWritePeakLimitResult = ZE_RESULT_ERROR_NOT_AVAILABLE;
for (auto handle : handles) {
uint32_t count = mockLimitCount;
std::vector<zes_power_limit_ext_desc_t> allLimits(mockLimitCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimitsExt(handle, &count, allLimits.data()));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimitsExt(handle, &count, allLimits.data()));
}
}
TEST_F(SysmanDevicePowerFixture, GivenReadingPeakPowerLimitNodeReturnErrorWhenSetOrGetPowerLimitsWhenHwmonInterfaceExistForPeakPowerLimitEnabledThenProperErrorCodesReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);