Pass device handles to sysman power module

Signed-off-by: Mayank Raghuwanshi <mayank.raghuwanshi@intel.com>
This commit is contained in:
Mayank Raghuwanshi 2021-09-21 05:51:12 +00:00 committed by Compute-Runtime-Automation
parent b5e0d32fe1
commit e1ad48ccb5
18 changed files with 434 additions and 188 deletions

View File

@ -8,6 +8,7 @@ set(L0_SRCS_TOOLS_SYSMAN_POWER_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/os_power_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/os_power_imp.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/os_power_helper.cpp
)
if(UNIX)

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/sysman/power/linux/os_power_imp.h"
namespace L0 {
bool LinuxPowerImp::isEnergyHwmonDir(std::string name) {
if (isSubdevice == false && (name == i915)) {
return true;
}
return false;
}
} // namespace L0

View File

@ -32,8 +32,8 @@ void powerGetTimestamp(uint64_t &timestamp) {
}
ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
pProperties->onSubdevice = false;
pProperties->subdeviceId = 0;
pProperties->onSubdevice = isSubdevice;
pProperties->subdeviceId = subdeviceId;
pProperties->canControl = canControl;
pProperties->isEnergyThresholdSupported = false;
pProperties->defaultLimit = -1;
@ -58,16 +58,25 @@ ze_result_t LinuxPowerImp::getProperties(zes_power_properties_t *pProperties) {
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxPowerImp::getPmtEnergyCounter(zes_power_energy_counter_t *pEnergy) {
const std::string key("PACKAGE_ENERGY");
uint64_t energy = 0;
ze_result_t result = pPmt->readValue(key, energy);
// PMT will return energy counter in Q20 format(fixed point representation) where first 20 bits(from LSB) represent decimal part and remaining integral part which is converted into joule by division with 1048576(2^20) and then converted into microjoules
pEnergy->energy = (energy / 1048576) * convertJouleToMicroJoule;
return result;
}
ze_result_t LinuxPowerImp::getEnergyCounter(zes_power_energy_counter_t *pEnergy) {
ze_result_t result = pSysfsAccess->read(i915HwmonDir + "/" + energyCounterNode, pEnergy->energy);
if (result != ZE_RESULT_SUCCESS) {
const std::string key("PACKAGE_ENERGY");
uint64_t energy = 0;
result = pPmt->readValue(key, energy);
// PMT will return energy counter in Q20 format(fixed point representation) where first 20 bits(from LSB) represent decimal part and remaining integral part which is converted into joule by division with 1048576(2^20) and then converted into microjoules
pEnergy->energy = (energy / 1048576) * convertJouleToMicroJoule;
}
powerGetTimestamp(pEnergy->timestamp);
ze_result_t result = pSysfsAccess->read(energyHwmonDir + "/" + energyCounterNode, pEnergy->energy);
if (result != ZE_RESULT_SUCCESS) {
if (pPmt != nullptr) {
return getPmtEnergyCounter(pEnergy);
}
}
if (result != ZE_RESULT_SUCCESS) {
return getErrorCode(result);
}
return result;
}
@ -131,6 +140,13 @@ ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustain
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
if (isSustainedPowerLimitEnabled != static_cast<uint64_t>(pSustained->enabled)) {
result = pSysfsAccess->write(i915HwmonDir + "/" + sustainedPowerLimitEnabled, static_cast<int>(pSustained->enabled));
if (ZE_RESULT_SUCCESS != result) {
return getErrorCode(result);
}
isSustainedPowerLimitEnabled = static_cast<uint64_t>(pSustained->enabled);
}
if (isSustainedPowerLimitEnabled) {
val = static_cast<uint32_t>(pSustained->power) * milliFactor; // Convert milliWatts to microwatts
@ -144,6 +160,7 @@ ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustain
return getErrorCode(result);
}
}
result = ZE_RESULT_SUCCESS;
}
if (pBurst != nullptr) {
result = pSysfsAccess->write(i915HwmonDir + "/" + burstPowerLimitEnabled, static_cast<int>(pBurst->enabled));
@ -159,7 +176,6 @@ ze_result_t LinuxPowerImp::setLimits(const zes_power_sustained_limit_t *pSustain
}
}
}
return result;
}
@ -187,7 +203,9 @@ bool LinuxPowerImp::isPowerModuleSupported() {
i915HwmonDir = hwmonDir + "/" + tempHwmonDirEntry;
hwmonDirExists = true;
canControl = true;
break;
}
if (isEnergyHwmonDir(name) == true) {
energyHwmonDir = hwmonDir + "/" + tempHwmonDirEntry;
}
}
if (hwmonDirExists == false) {
@ -196,16 +214,14 @@ bool LinuxPowerImp::isPowerModuleSupported() {
return true;
}
LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman) {
LinuxPowerImp::LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : isSubdevice(onSubdevice), subdeviceId(subdeviceId) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
// Lets hardcode subDeviceId to 0, as we are expecting this code to execute on device without subdevice
uint32_t subDeviceId = 0;
pPmt = pLinuxSysmanImp->getPlatformMonitoringTechAccess(subDeviceId);
pPmt = pLinuxSysmanImp->getPlatformMonitoringTechAccess(subdeviceId);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
}
OsPower *OsPower::create(OsSysman *pOsSysman) {
LinuxPowerImp *pLinuxPowerImp = new LinuxPowerImp(pOsSysman);
OsPower *OsPower::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
LinuxPowerImp *pLinuxPowerImp = new LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId);
return static_cast<OsPower *>(pLinuxPowerImp);
}

View File

@ -27,7 +27,9 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
ze_result_t setEnergyThreshold(double threshold) override;
bool isPowerModuleSupported() override;
LinuxPowerImp(OsSysman *pOsSysman);
bool isEnergyHwmonDir(std::string name);
ze_result_t getPmtEnergyCounter(zes_power_energy_counter_t *pEnergy);
LinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
LinuxPowerImp() = default;
~LinuxPowerImp() override = default;
@ -37,6 +39,7 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
private:
std::string i915HwmonDir;
std::string energyHwmonDir;
static const std::string hwmonDir;
static const std::string i915;
static const std::string sustainedPowerLimitEnabled;
@ -49,6 +52,8 @@ class LinuxPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
static const std::string minPowerLimit;
static const std::string maxPowerLimit;
bool canControl = false;
bool isSubdevice = false;
uint32_t subdeviceId = 0;
ze_result_t getErrorCode(ze_result_t result) {
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -22,7 +22,7 @@ class OsPower {
virtual ze_result_t setEnergyThreshold(double threshold) = 0;
virtual bool isPowerModuleSupported() = 0;
static OsPower *create(OsSysman *pOsSysman);
static OsPower *create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
virtual ~OsPower() = default;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -19,14 +19,20 @@ PowerHandleContext::~PowerHandleContext() {
}
}
void PowerHandleContext::init() {
Power *pPower = new PowerImp(pOsSysman);
void PowerHandleContext::createHandle(ze_device_handle_t deviceHandle) {
Power *pPower = new PowerImp(pOsSysman, deviceHandle);
if (pPower->initSuccess == true) {
handleList.push_back(pPower);
} else {
delete pPower;
}
}
ze_result_t PowerHandleContext::init(std::vector<ze_device_handle_t> &deviceHandles) {
for (const auto &deviceHandle : deviceHandles) {
createHandle(deviceHandle);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t PowerHandleContext::powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower) {
uint32_t handleListSize = static_cast<uint32_t>(handleList.size());

View File

@ -1,11 +1,12 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/core/source/device/device.h"
#include <level_zero/zes_api.h>
#include <vector>
@ -41,12 +42,14 @@ struct PowerHandleContext {
PowerHandleContext(OsSysman *pOsSysman) : pOsSysman(pOsSysman){};
~PowerHandleContext();
void init();
ze_result_t init(std::vector<ze_device_handle_t> &deviceHandles);
ze_result_t powerGet(uint32_t *pCount, zes_pwr_handle_t *phPower);
OsSysman *pOsSysman = nullptr;
std::vector<Power *> handleList = {};
private:
void createHandle(ze_device_handle_t deviceHandle);
};
} // namespace L0

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -35,10 +35,11 @@ ze_result_t PowerImp::powerSetEnergyThreshold(double threshold) {
return pOsPower->setEnergyThreshold(threshold);
}
PowerImp::PowerImp(OsSysman *pOsSysman) {
pOsPower = OsPower::create(pOsSysman);
PowerImp::PowerImp(OsSysman *pOsSysman, ze_device_handle_t handle) : deviceHandle(handle) {
ze_device_properties_t deviceProperties = {};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
pOsPower = OsPower::create(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId);
UNRECOVERABLE_IF(nullptr == pOsPower);
init();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -23,10 +23,13 @@ class PowerImp : public Power, NEO::NonCopyableOrMovableClass {
ze_result_t powerSetEnergyThreshold(double threshold) override;
PowerImp() = default;
PowerImp(OsSysman *pOsSysman);
PowerImp(OsSysman *pOsSysman, ze_device_handle_t device);
~PowerImp() override;
OsPower *pOsPower = nullptr;
void init();
private:
ze_device_handle_t deviceHandle = {};
};
} // namespace L0

View File

@ -330,13 +330,13 @@ bool WddmPowerImp::isPowerModuleSupported() {
return ((status == ZE_RESULT_SUCCESS) && (enabled));
}
WddmPowerImp::WddmPowerImp(OsSysman *pOsSysman) {
WddmPowerImp::WddmPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
WddmSysmanImp *pWddmSysmanImp = static_cast<WddmSysmanImp *>(pOsSysman);
pKmdSysManager = &pWddmSysmanImp->getKmdSysManager();
}
OsPower *OsPower::create(OsSysman *pOsSysman) {
WddmPowerImp *pWddmPowerImp = new WddmPowerImp(pOsSysman);
OsPower *OsPower::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) {
WddmPowerImp *pWddmPowerImp = new WddmPowerImp(pOsSysman, onSubdevice, subdeviceId);
return static_cast<OsPower *>(pWddmPowerImp);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -23,7 +23,7 @@ class WddmPowerImp : public OsPower, NEO::NonCopyableOrMovableClass {
ze_result_t setEnergyThreshold(double threshold) override;
bool isPowerModuleSupported() override;
WddmPowerImp(OsSysman *pOsSysman);
WddmPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId);
WddmPowerImp() = default;
~WddmPowerImp() override = default;

View File

@ -76,7 +76,7 @@ ze_result_t SysmanDeviceImp::init() {
return result;
}
if (pPowerHandleContext) {
pPowerHandleContext->init();
pPowerHandleContext->init(deviceHandles);
}
if (pFrequencyHandleContext) {
pFrequencyHandleContext->init(deviceHandles);

View File

@ -8,6 +8,8 @@ set(L0_TESTS_TOOLS_SYSMAN_POWER_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_power.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_sysfs_power.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_sysfs_power_helper.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/test_zes_power_helper.cpp
)
if(UNIX)

View File

@ -10,11 +10,16 @@
#include "level_zero/core/test/unit_tests/mock.h"
#include "level_zero/tools/source/sysman/power/linux/os_power_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h"
#include "sysman/linux/pmt/pmt.h"
#include "sysman/power/power_imp.h"
#include "sysman/sysman_imp.h"
using ::testing::DoDefault;
using ::testing::Matcher;
using ::testing::Return;
namespace L0 {
namespace ult {
constexpr uint64_t setEnergyCounter = (83456u * 1048576u);
@ -23,9 +28,9 @@ constexpr uint64_t mappedLength = 2048;
const std::string deviceName("device");
const std::string baseTelemSysFS("/sys/class/intel_pmt");
const std::string hwmonDir("device/hwmon");
const std::string i915HwmonDir("device/hwmon/hwmon4");
const std::string i915HwmonDir("device/hwmon/hwmon2");
const std::string nonI915HwmonDir("device/hwmon/hwmon1");
const std::vector<std::string> listOfMockedHwmonDirs = {"hwmon1", "hwmon2", "hwmon3", "hwmon4"};
const std::vector<std::string> listOfMockedHwmonDirs = {"hwmon0", "hwmon1", "hwmon2", "hwmon3", "hwmon4"};
const std::string sustainedPowerLimitEnabled("power1_max_enable");
const std::string sustainedPowerLimit("power1_max");
const std::string sustainedPowerLimitInterval("power1_max_interval");
@ -39,11 +44,18 @@ constexpr uint64_t expectedEnergyCounter = 123456785u;
constexpr uint32_t mockDefaultPowerLimitVal = 300000000;
constexpr uint32_t mockMaxPowerLimitVal = 490000000;
constexpr uint32_t mockMinPowerLimitVal = 10;
const std::map<std::string, uint64_t> deviceKeyOffsetMapPower = {
{"PACKAGE_ENERGY", 0x400},
{"COMPUTE_TEMPERATURES", 0x68},
{"SOC_TEMPERATURES", 0x60},
{"CORE_TEMPERATURES", 0x6c}};
class PowerSysfsAccess : public SysfsAccess {};
template <>
struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
ze_result_t getValStringHelper(const std::string file, std::string &val);
ze_result_t getValString(const std::string file, std::string &val) {
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
if (file.compare(i915HwmonDir + "/" + "name") == 0) {
@ -65,17 +77,14 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
uint64_t burstPowerLimitVal = 0;
uint64_t energyCounterNodeVal = expectedEnergyCounter;
ze_result_t getValUnsignedLongReturnErrorForEnergyCounter(const std::string file, uint64_t &val) {
if (file.compare(i915HwmonDir + "/" + energyCounterNode) == 0) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getValUnsignedLongReturnErrorForBurstPowerLimit(const std::string file, uint64_t &val) {
if (file.compare(i915HwmonDir + "/" + burstPowerLimitEnabled) == 0) {
val = burstPowerLimitEnabledVal;
}
if (file.compare(i915HwmonDir + "/" + burstPowerLimit) == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
@ -122,10 +131,6 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
return ZE_RESULT_SUCCESS;
}
ze_result_t getValUnsignedLongReturnErrorUnknown(const std::string file, uint64_t &val) {
return ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t setValUnsignedLongReturnErrorForBurstPowerLimit(const std::string file, const int val) {
if (file.compare(i915HwmonDir + "/" + burstPowerLimit) == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
@ -140,6 +145,20 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
return ZE_RESULT_SUCCESS;
}
ze_result_t setValUnsignedLongReturnErrorForSustainedPowerLimitEnabled(const std::string file, const int val) {
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimitEnabled) == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t setValUnsignedLongReturnInsufficientForSustainedPowerLimitEnabled(const std::string file, const int val) {
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimitEnabled) == 0) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t setValReturnErrorForSustainedPower(const std::string file, const int val) {
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
@ -154,6 +173,7 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
return ZE_RESULT_SUCCESS;
}
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 + "/" + sustainedPowerLimitEnabled) == 0) {
@ -201,7 +221,9 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
ze_result_t setVal(const std::string file, const int val) {
ze_result_t result = ZE_RESULT_SUCCESS;
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
if (file.compare(i915HwmonDir + "/" + sustainedPowerLimitEnabled) == 0) {
sustainedPowerLimitEnabledVal = static_cast<uint64_t>(val);
} else if (file.compare(i915HwmonDir + "/" + sustainedPowerLimit) == 0) {
sustainedPowerLimitVal = static_cast<uint64_t>(val);
} else if (file.compare(i915HwmonDir + "/" + sustainedPowerLimitInterval) == 0) {
sustainedPowerLimitIntervalVal = static_cast<uint64_t>(val);
@ -222,9 +244,6 @@ struct Mock<PowerSysfsAccess> : public PowerSysfsAccess {
}
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
ze_result_t getscanDirEntriesStatusReturnError(const std::string file, std::vector<std::string> &listOfEntries) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
Mock<PowerSysfsAccess>() = default;
@ -316,8 +335,141 @@ struct Mock<PowerFsAccess> : public PowerFsAccess {
class PublicLinuxPowerImp : public L0::LinuxPowerImp {
public:
PublicLinuxPowerImp(OsSysman *pOsSysman) : LinuxPowerImp(pOsSysman) {}
PublicLinuxPowerImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId) : LinuxPowerImp(pOsSysman, onSubdevice, subdeviceId) {}
using LinuxPowerImp::pPmt;
};
class SysmanDevicePowerFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<PublicLinuxPowerImp> pPublicLinuxPowerImp;
std::unique_ptr<Mock<PowerPmt>> pPmt;
std::unique_ptr<Mock<PowerFsAccess>> pFsAccess;
std::unique_ptr<Mock<PowerSysfsAccess>> pSysfsAccess;
SysfsAccess *pSysfsAccessOld = nullptr;
FsAccess *pFsAccessOriginal = nullptr;
OsPower *pOsPowerOriginal = nullptr;
std::vector<ze_device_handle_t> deviceHandles;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pFsAccess = std::make_unique<NiceMock<Mock<PowerFsAccess>>>();
pFsAccessOriginal = pLinuxSysmanImp->pFsAccess;
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pSysfsAccess = std::make_unique<NiceMock<Mock<PowerSysfsAccess>>>();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
ON_CALL(*pFsAccess.get(), listDirectory(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::listDirectorySuccess));
ON_CALL(*pFsAccess.get(), getRealPath(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::getRealPathSuccess));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<std::string &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValString));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedLong));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedInt));
ON_CALL(*pSysfsAccess.get(), write(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setVal));
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntries));
uint32_t subDeviceCount = 0;
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());
}
for (auto &deviceHandle : deviceHandles) {
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
auto pPmt = new NiceMock<Mock<PowerPmt>>(pFsAccess.get(), deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE,
deviceProperties.subdeviceId);
pPmt->mockedInit(pFsAccess.get());
pPmt->keyOffsetMap = deviceKeyOffsetMapPower;
pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject.emplace(deviceProperties.subdeviceId, pPmt);
}
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
}
void TearDown() override {
SysmanDeviceFixture::TearDown();
pLinuxSysmanImp->pFsAccess = pFsAccessOriginal;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
}
std::vector<zes_pwr_handle_t> getPowerHandles(uint32_t count) {
std::vector<zes_pwr_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
class SysmanDevicePowerMultiDeviceFixture : public SysmanMultiDeviceFixture {
protected:
std::unique_ptr<PublicLinuxPowerImp> pPublicLinuxPowerImp;
std::unique_ptr<Mock<PowerPmt>> pPmt;
std::unique_ptr<Mock<PowerFsAccess>> pFsAccess;
std::unique_ptr<Mock<PowerSysfsAccess>> pSysfsAccess;
SysfsAccess *pSysfsAccessOld = nullptr;
FsAccess *pFsAccessOriginal = nullptr;
OsPower *pOsPowerOriginal = nullptr;
std::vector<ze_device_handle_t> deviceHandles;
void SetUp() override {
SysmanMultiDeviceFixture::SetUp();
pFsAccess = std::make_unique<NiceMock<Mock<PowerFsAccess>>>();
pFsAccessOriginal = pLinuxSysmanImp->pFsAccess;
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pSysfsAccess = std::make_unique<NiceMock<Mock<PowerSysfsAccess>>>();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
ON_CALL(*pFsAccess.get(), listDirectory(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::listDirectorySuccess));
ON_CALL(*pFsAccess.get(), getRealPath(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::getRealPathSuccess));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<std::string &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValString));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedLong));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedInt));
ON_CALL(*pSysfsAccess.get(), write(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setVal));
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntries));
uint32_t subDeviceCount = 0;
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());
}
for (auto &deviceHandle : deviceHandles) {
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
auto pPmt = new NiceMock<Mock<PowerPmt>>(pFsAccess.get(), deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE,
deviceProperties.subdeviceId);
pPmt->mockedInit(pFsAccess.get());
pPmt->keyOffsetMap = deviceKeyOffsetMapPower;
pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject.emplace(deviceProperties.subdeviceId, pPmt);
}
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
}
void TearDown() override {
SysmanMultiDeviceFixture::TearDown();
pLinuxSysmanImp->pFsAccess = pFsAccessOriginal;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
}
std::vector<zes_pwr_handle_t> getPowerHandles(uint32_t count) {
std::vector<zes_pwr_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
} // namespace ult
} // namespace L0

View File

@ -0,0 +1,6 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/

View File

@ -6,94 +6,13 @@
*/
#include "level_zero/tools/source/sysman/power/linux/os_power_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/linux/mock_sysman_fixture.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "mock_sysfs_power.h"
#include "sysman/power/power_imp.h"
using ::testing::DoDefault;
using ::testing::Matcher;
using ::testing::Return;
#include "level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power.h"
namespace L0 {
namespace ult {
constexpr uint64_t convertJouleToMicroJoule = 1000000u;
constexpr uint32_t powerHandleComponentCount = 1u;
const std::map<std::string, uint64_t> deviceKeyOffsetMapPower = {
{"PACKAGE_ENERGY", 0x400},
{"COMPUTE_TEMPERATURES", 0x68},
{"SOC_TEMPERATURES", 0x60},
{"CORE_TEMPERATURES", 0x6c}};
class SysmanDevicePowerFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<PublicLinuxPowerImp> pPublicLinuxPowerImp;
std::unique_ptr<Mock<PowerPmt>> pPmt;
std::unique_ptr<Mock<PowerFsAccess>> pFsAccess;
std::unique_ptr<Mock<PowerSysfsAccess>> pSysfsAccess;
SysfsAccess *pSysfsAccessOld = nullptr;
FsAccess *pFsAccessOriginal = nullptr;
OsPower *pOsPowerOriginal = nullptr;
std::vector<ze_device_handle_t> deviceHandles;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pFsAccess = std::make_unique<NiceMock<Mock<PowerFsAccess>>>();
pFsAccessOriginal = pLinuxSysmanImp->pFsAccess;
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pSysfsAccess = std::make_unique<NiceMock<Mock<PowerSysfsAccess>>>();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
ON_CALL(*pFsAccess.get(), listDirectory(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::listDirectorySuccess));
ON_CALL(*pFsAccess.get(), getRealPath(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<PowerFsAccess>::getRealPathSuccess));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<std::string &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValString));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedLong));
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint32_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedInt));
ON_CALL(*pSysfsAccess.get(), write(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setVal));
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntries));
uint32_t subDeviceCount = 0;
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());
}
for (auto &deviceHandle : deviceHandles) {
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
auto pPmt = new NiceMock<Mock<PowerPmt>>(pFsAccess.get(), deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE,
deviceProperties.subdeviceId);
pPmt->mockedInit(pFsAccess.get());
pPmt->keyOffsetMap = deviceKeyOffsetMapPower;
pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject.emplace(deviceProperties.subdeviceId, pPmt);
}
pSysmanDeviceImp->pPowerHandleContext->init();
}
void TearDown() override {
SysmanDeviceFixture::TearDown();
pLinuxSysmanImp->pFsAccess = pFsAccessOriginal;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOld;
}
std::vector<zes_pwr_handle_t> getPowerHandles(uint32_t count) {
std::vector<zes_pwr_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDomainsWhenhwmonInterfaceExistsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) {
uint32_t count = 0;
@ -147,7 +66,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_properties_t properties;
@ -171,7 +90,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_properties_t properties;
@ -194,7 +113,7 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_properties_t properties;
@ -207,21 +126,11 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterWhenHwmonInterfaceExistThenValidPowerReadingsRetrieved) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_energy_counter_t energyCounter = {};
ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter));
EXPECT_EQ(energyCounter.energy, expectedEnergyCounter);
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterFailedWhenHwmonInterfaceExistThenValidErrorCodeReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedLongReturnErrorForEnergyCounter));
EXPECT_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillRepeatedly(Return(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS));
for (auto handle : handles) {
zes_power_energy_counter_t energyCounter = {};
uint64_t expectedEnergyCounter = convertJouleToMicroJoule * (setEnergyCounter / 1048576);
@ -235,6 +144,7 @@ TEST_F(SysmanDevicePowerFixture, GivenSetPowerLimitsWhenGettingPowerLimitsWhenHw
for (auto handle : handles) {
zes_power_sustained_limit_t sustainedSet = {};
zes_power_sustained_limit_t sustainedGet = {};
sustainedSet.enabled = 1;
sustainedSet.interval = 10;
sustainedSet.power = 300000;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handle, &sustainedSet, nullptr, nullptr));
@ -285,8 +195,8 @@ TEST_F(SysmanDevicePowerFixture, GivenGetPowerLimitsReturnErrorWhenGettingPowerL
TEST_F(SysmanDevicePowerFixture, GivenGetPowerLimitsReturnErrorWhenGettingPowerLimitsWhenHwmonInterfaceExistForBurstPowerLimitThenProperErrorCodesIsReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
ON_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getValUnsignedLongReturnErrorUnknown));
EXPECT_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillRepeatedly(Return(ZE_RESULT_ERROR_UNKNOWN));
for (auto handle : handles) {
zes_power_burst_limit_t burstSet = {};
@ -374,6 +284,7 @@ TEST_F(SysmanDevicePowerFixture, GivenwritingSustainedPowerNodeReturnErrorWhenSe
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setValReturnErrorForSustainedPower));
zes_power_sustained_limit_t sustainedSet = {};
sustainedSet.enabled = 1;
sustainedSet.interval = 10;
sustainedSet.power = 300000;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr));
@ -386,11 +297,39 @@ TEST_F(SysmanDevicePowerFixture, GivenwritingSustainedPowerIntervalNodeReturnErr
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setValReturnErrorForSustainedPowerInterval));
zes_power_sustained_limit_t sustainedSet = {};
sustainedSet.enabled = 1;
sustainedSet.interval = 10;
sustainedSet.power = 300000;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr));
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenWritingToSustainedPowerEnableNodeWithoutPermissionsThenValidErrorIsReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
ON_CALL(*pSysfsAccess.get(), write(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::setValUnsignedLongReturnInsufficientForSustainedPowerLimitEnabled));
zes_power_sustained_limit_t sustainedSet = {};
sustainedSet.enabled = 0;
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr));
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleAndPermissionsThenFirstDisableSustainedPowerLimitAndThenEnableItAndCheckSuccesIsReturned) {
auto handles = getPowerHandles(powerHandleComponentCount);
zes_power_sustained_limit_t sustainedSet = {};
zes_power_sustained_limit_t sustainedGet = {};
sustainedSet.enabled = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr));
sustainedSet.enabled = 1;
sustainedSet.interval = 10;
sustainedSet.power = 300000;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerSetLimits(handles[0], &sustainedSet, nullptr, nullptr));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPowerGetLimits(handles[0], &sustainedGet, nullptr, nullptr));
EXPECT_EQ(sustainedGet.enabled, sustainedSet.enabled);
EXPECT_EQ(sustainedGet.power, sustainedSet.power);
EXPECT_EQ(sustainedGet.interval, sustainedSet.interval);
}
TEST_F(SysmanDevicePowerFixture, GivenGetPowerLimitsWhenPowerLimitsAreDisabledWhenHwmonInterfaceExistThenAllPowerValuesAreIgnored) {
auto handles = getPowerHandles(powerHandleComponentCount);
@ -413,35 +352,37 @@ TEST_F(SysmanDevicePowerFixture, GivenGetPowerLimitsWhenPowerLimitsAreDisabledWh
}
TEST_F(SysmanDevicePowerFixture, GivenScanDiectoriesFailAndPmtIsNotNullPointerThenPowerModuleIsSupported) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
pSysmanDeviceImp->pPowerHandleContext->init();
PublicLinuxPowerImp *pPowerImp = new PublicLinuxPowerImp(pOsSysman);
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(device)->getProperties(&deviceProperties);
PublicLinuxPowerImp *pPowerImp = new PublicLinuxPowerImp(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId);
EXPECT_TRUE(pPowerImp->isPowerModuleSupported());
delete pPowerImp;
}
TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, powerHandleComponentCount);
}
TEST_F(SysmanDevicePowerFixture, GivenInvalidComponentCountWhenEnumeratingPowerDomainsThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, powerHandleComponentCount);
@ -452,13 +393,13 @@ TEST_F(SysmanDevicePowerFixture, GivenInvalidComponentCountWhenEnumeratingPowerD
}
TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDomainsThenValidPowerHandlesIsReturned) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
uint32_t count = 0;
EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, powerHandleComponentCount);
@ -471,13 +412,13 @@ TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDoma
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesThenCallSucceeds) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
@ -489,13 +430,13 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerProperties
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
@ -506,14 +447,39 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCoun
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterWhenEnergyHwmonFileReturnsErrorAndPmtFailsThenFailureIsReturned) {
EXPECT_CALL(*pSysfsAccess.get(), read(_, Matcher<uint64_t &>(_)))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
for (auto &subDeviceIdToPmtEntry : pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject) {
delete subDeviceIdToPmtEntry.second;
}
pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject.clear();
for (auto &deviceHandle : deviceHandles) {
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
pLinuxSysmanImp->mapOfSubDeviceIdToPmtObject.emplace(deviceProperties.subdeviceId, nullptr);
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_energy_counter_t energyCounter = {};
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesPowerGetEnergyCounter(handle, &energyCounter));
}
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyThresholdThenUnsupportedFeatureErrorIsReturned) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
zes_energy_threshold_t threshold;
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
@ -522,13 +488,13 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyThre
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerEnergyThresholdThenUnsupportedFeatureErrorIsReturned) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
double threshold = 0;
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
@ -537,13 +503,13 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerEnergyThre
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerLimitsThenUnsupportedFeatureErrorIsReturned) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_sustained_limit_t sustained;
@ -554,13 +520,13 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerLimitsThen
}
TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerLimitsThenUnsupportedFeatureErrorIsReturned) {
ON_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<PowerSysfsAccess>::getscanDirEntriesStatusReturnError));
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_sustained_limit_t sustained;
@ -570,5 +536,23 @@ TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerLimitsThen
}
}
TEST_F(SysmanDevicePowerMultiDeviceFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterWhenEnergyHwmonFailsThenValidPowerReadingsRetrievedFromPmt) {
EXPECT_CALL(*pSysfsAccess.get(), scanDirEntries(_, _))
.WillRepeatedly(Return(ZE_RESULT_ERROR_NOT_AVAILABLE));
for (const auto &handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles);
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_energy_counter_t energyCounter;
uint64_t expectedEnergyCounter = convertJouleToMicroJoule * (setEnergyCounter / 1048576);
ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter));
EXPECT_EQ(energyCounter.energy, expectedEnergyCounter);
}
}
} // namespace ult
} // namespace L0

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/sysman/power/linux/os_power_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/power/linux/mock_sysfs_power.h"
namespace L0 {
namespace ult {
constexpr uint32_t powerHandleComponentCount = 1u;
using SysmanDevicePowerFixtureHelper = SysmanDevicePowerFixture;
TEST_F(SysmanDevicePowerFixtureHelper, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) {
auto handles = getPowerHandles(powerHandleComponentCount);
for (auto handle : handles) {
zes_power_energy_counter_t energyCounter = {};
ASSERT_EQ(ZE_RESULT_SUCCESS, zesPowerGetEnergyCounter(handle, &energyCounter));
EXPECT_EQ(energyCounter.energy, expectedEnergyCounter);
}
}
using SysmanDevicePowerMultiDeviceFixtureHelper = SysmanDevicePowerMultiDeviceFixture;
TEST_F(SysmanDevicePowerMultiDeviceFixtureHelper, GivenValidDeviceHandlesAndHwmonInterfaceExistThenSuccessIsReturned) {
for (auto &deviceHandle : deviceHandles) {
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
Device::fromHandle(deviceHandle)->getProperties(&deviceProperties);
PublicLinuxPowerImp *pPowerImp = new PublicLinuxPowerImp(pOsSysman, deviceProperties.flags & ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE, deviceProperties.subdeviceId);
EXPECT_TRUE(pPowerImp->isPowerModuleSupported());
delete pPowerImp;
}
}
} // namespace ult
} // namespace L0

View File

@ -38,7 +38,16 @@ class SysmanDevicePowerFixture : public SysmanDeviceFixture {
}
pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
pSysmanDeviceImp->pPowerHandleContext->init();
uint32_t subDeviceCount = 0;
std::vector<ze_device_handle_t> deviceHandles;
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->pPowerHandleContext->init(deviceHandles);
}
void TearDown() override {
SysmanDeviceFixture::TearDown();