mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
feature(sysman): Support for PowerLimitExt APIs in windows
Related-To: LOCI-3407 Signed-off-by: shubham kumar <shubham.kumar@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
305f24ec9d
commit
c824c48f21
@@ -10,6 +10,8 @@
|
||||
#include "level_zero/tools/source/sysman/sysman_const.h"
|
||||
#include "level_zero/tools/source/sysman/windows/kmd_sys_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace L0 {
|
||||
|
||||
ze_result_t WddmPowerImp::getProperties(zes_power_properties_t *pProperties) {
|
||||
@@ -297,18 +299,222 @@ bool WddmPowerImp::isPowerModuleSupported() {
|
||||
|
||||
ze_result_t status = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
uint32_t enabled = 0;
|
||||
memcpy_s(&enabled, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
ze_bool_t enabled = false;
|
||||
memcpy_s(&enabled, sizeof(ze_bool_t), response.dataBuffer, sizeof(ze_bool_t));
|
||||
powerLimitCount = 0;
|
||||
|
||||
return ((status == ZE_RESULT_SUCCESS) && (enabled));
|
||||
if ((status == ZE_RESULT_SUCCESS) && enabled) {
|
||||
powerLimitCount++;
|
||||
}
|
||||
|
||||
request.requestId = KmdSysman::Requests::Power::PowerLimit2Enabled;
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
enabled = false;
|
||||
memcpy_s(&enabled, sizeof(ze_bool_t), response.dataBuffer, sizeof(ze_bool_t));
|
||||
|
||||
if ((status == ZE_RESULT_SUCCESS) && enabled) {
|
||||
powerLimitCount++;
|
||||
}
|
||||
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit4Ac;
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (status == ZE_RESULT_SUCCESS) {
|
||||
powerLimitCount++;
|
||||
}
|
||||
|
||||
if (powerLimitCount > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t WddmPowerImp::getLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
ze_result_t result = ZE_RESULT_SUCCESS;
|
||||
uint8_t count = 0;
|
||||
|
||||
if (*pCount == 0) {
|
||||
*pCount = powerLimitCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
*pCount = std::min(*pCount, powerLimitCount);
|
||||
|
||||
KmdSysman::RequestProperty request;
|
||||
KmdSysman::ResponseProperty response;
|
||||
|
||||
request.commandId = KmdSysman::Command::Get;
|
||||
request.componentId = KmdSysman::Component::PowerComponent;
|
||||
|
||||
if (pSustained) {
|
||||
// sustained
|
||||
request.requestId = KmdSysman::Requests::Power::PowerLimit1Enabled;
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
ze_bool_t enabled = false;
|
||||
memcpy_s(&enabled, sizeof(ze_bool_t), response.dataBuffer, sizeof(ze_bool_t));
|
||||
|
||||
if (enabled) {
|
||||
memset(&pSustained[count], 0, sizeof(zes_power_limit_ext_desc_t));
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit1;
|
||||
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t limit = 0;
|
||||
memcpy_s(&limit, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit1Tau;
|
||||
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t interval = 0;
|
||||
memcpy_s(&interval, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
pSustained[count].enabled = enabled;
|
||||
pSustained[count].limit = limit;
|
||||
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++;
|
||||
}
|
||||
|
||||
// Burst
|
||||
request.requestId = KmdSysman::Requests::Power::PowerLimit2Enabled;
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
enabled = false;
|
||||
memcpy_s(&enabled, sizeof(ze_bool_t), response.dataBuffer, sizeof(ze_bool_t));
|
||||
|
||||
if (count < *pCount && enabled) {
|
||||
memset(&pSustained[count], 0, sizeof(zes_power_limit_ext_desc_t));
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit2;
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t limit = 0;
|
||||
memcpy_s(&limit, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
|
||||
pSustained[count].enabled = enabled;
|
||||
pSustained[count].limit = limit;
|
||||
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_BURST;
|
||||
pSustained[count].limitUnit = ZES_LIMIT_UNIT_POWER;
|
||||
pSustained[count].interval = 0;
|
||||
count++;
|
||||
}
|
||||
// Peak
|
||||
if (count < *pCount) {
|
||||
|
||||
memset(&pSustained[count], 0, sizeof(zes_power_limit_ext_desc_t));
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit4Ac;
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t powerAC = 0;
|
||||
memcpy_s(&powerAC, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit4Dc;
|
||||
|
||||
result = pKmdSysManager->requestSingle(request, response);
|
||||
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
uint32_t powerDC = 0;
|
||||
memcpy_s(&powerDC, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
|
||||
|
||||
pSustained[count].enabled = true;
|
||||
pSustained[count].limit = powerAC;
|
||||
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_PEAK;
|
||||
pSustained[count].limitUnit = ZES_LIMIT_UNIT_POWER;
|
||||
pSustained[count].interval = 0;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t WddmPowerImp::setLimitsExt(uint32_t *pCount, zes_power_limit_ext_desc_t *pSustained) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
ze_result_t status = ZE_RESULT_SUCCESS;
|
||||
KmdSysman::RequestProperty request;
|
||||
KmdSysman::ResponseProperty response;
|
||||
|
||||
request.commandId = KmdSysman::Command::Set;
|
||||
request.componentId = KmdSysman::Component::PowerComponent;
|
||||
request.dataSize = sizeof(uint32_t);
|
||||
|
||||
for (uint32_t i = 0; i < *pCount; i++) {
|
||||
if (pSustained[i].level == ZES_POWER_LEVEL_SUSTAINED) {
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit1;
|
||||
memcpy_s(request.dataBuffer, sizeof(uint32_t), &pSustained[i].limit, sizeof(uint32_t));
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit1Tau;
|
||||
memcpy_s(request.dataBuffer, sizeof(uint32_t), &pSustained[i].interval, sizeof(uint32_t));
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
} else if (pSustained[i].level == ZES_POWER_LEVEL_BURST) {
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit2;
|
||||
memcpy_s(request.dataBuffer, sizeof(uint32_t), &pSustained[i].limit, sizeof(uint32_t));
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
} else if (pSustained[i].level == ZES_POWER_LEVEL_PEAK) {
|
||||
if (pSustained[i].source != ZES_POWER_SOURCE_BATTERY) {
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit4Ac;
|
||||
memcpy_s(request.dataBuffer, sizeof(uint32_t), &pSustained[i].limit, sizeof(uint32_t));
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
request.requestId = KmdSysman::Requests::Power::CurrentPowerLimit4Dc;
|
||||
memcpy_s(request.dataBuffer, sizeof(uint32_t), &pSustained[i].limit, sizeof(uint32_t));
|
||||
status = pKmdSysManager->requestSingle(request, response);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
WddmPowerImp::WddmPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
|
||||
|
||||
@@ -32,6 +32,7 @@ class WddmPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
|
||||
|
||||
protected:
|
||||
KmdSysManager *pKmdSysManager = nullptr;
|
||||
uint32_t powerLimitCount = 0;
|
||||
};
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
namespace L0 {
|
||||
namespace ult {
|
||||
constexpr uint32_t mockLimitCount = 3u;
|
||||
|
||||
class PowerKmdSysManager : public Mock<MockKmdSysManager> {};
|
||||
|
||||
|
||||
@@ -289,16 +289,84 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerLimitsAllo
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtWhenHwmonInterfaceExistThenUnsupportedFeatureIsReturned) {
|
||||
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandlesWhenCallingSetAndGetPowerLimitExtThenLimitsSetEarlierAreRetrieved) {
|
||||
// Setting allow set calls or not
|
||||
init(true);
|
||||
|
||||
auto handles = get_power_handles(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_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;
|
||||
} else if (allLimits[i].level == ZES_POWER_LEVEL_BURST) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenCallingGetPowerLimitsExtThenProperValuesAreReturned) {
|
||||
// Setting allow set calls or not
|
||||
init(false);
|
||||
auto handles = get_power_handles(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user