1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "level_zero/tools/source/sysman/power/windows/os_power_imp.h"
9 #include "level_zero/tools/test/unit_tests/sources/sysman/power/windows/mock_power.h"
10 #include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_sysman_fixture.h"
11 
12 extern bool sysmanUltsEnable;
13 
14 namespace L0 {
15 namespace ult {
16 
17 constexpr uint32_t powerHandleComponentCount = 1u;
18 class SysmanDevicePowerFixture : public SysmanDeviceFixture {
19 
20   protected:
21     std::unique_ptr<Mock<PowerKmdSysManager>> pKmdSysManager;
22     KmdSysManager *pOriginalKmdSysManager = nullptr;
SetUp()23     void SetUp() override {
24         if (!sysmanUltsEnable) {
25             GTEST_SKIP();
26         }
27         SysmanDeviceFixture::SetUp();
28     }
29 
init(bool allowSetCalls)30     void init(bool allowSetCalls) {
31         pKmdSysManager.reset(new Mock<PowerKmdSysManager>);
32 
33         pKmdSysManager->allowSetCalls = allowSetCalls;
34 
35         EXPECT_CALL(*pKmdSysManager, escape(_, _, _, _, _))
36             .WillRepeatedly(::testing::Invoke(pKmdSysManager.get(), &Mock<PowerKmdSysManager>::mock_escape));
37 
38         pOriginalKmdSysManager = pWddmSysmanImp->pKmdSysManager;
39         pWddmSysmanImp->pKmdSysManager = pKmdSysManager.get();
40 
41         for (auto handle : pSysmanDeviceImp->pPowerHandleContext->handleList) {
42             delete handle;
43         }
44 
45         pSysmanDeviceImp->pPowerHandleContext->handleList.clear();
46         uint32_t subDeviceCount = 0;
47         std::vector<ze_device_handle_t> deviceHandles;
48         Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, nullptr);
49         if (subDeviceCount == 0) {
50             deviceHandles.resize(1, device->toHandle());
51         } else {
52             deviceHandles.resize(subDeviceCount, nullptr);
53             Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, deviceHandles.data());
54         }
55         pSysmanDeviceImp->pPowerHandleContext->init(deviceHandles, device->toHandle());
56     }
TearDown()57     void TearDown() override {
58         if (!sysmanUltsEnable) {
59             GTEST_SKIP();
60         }
61         SysmanDeviceFixture::TearDown();
62         pWddmSysmanImp->pKmdSysManager = pOriginalKmdSysManager;
63     }
64 
get_power_handles(uint32_t count)65     std::vector<zes_pwr_handle_t> get_power_handles(uint32_t count) {
66         std::vector<zes_pwr_handle_t> handles(count, nullptr);
67         EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
68         return handles;
69     }
70 };
71 
TEST_F(SysmanDevicePowerFixture,GivenComponentCountZeroWhenEnumeratingPowerDomainThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds)72 TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDomainThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) {
73     init(true);
74 
75     uint32_t count = 0;
76     EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
77     EXPECT_EQ(count, powerHandleComponentCount);
78 }
79 
TEST_F(SysmanDevicePowerFixture,GivenInvalidComponentCountWhenEnumeratingPowerDomainThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds)80 TEST_F(SysmanDevicePowerFixture, GivenInvalidComponentCountWhenEnumeratingPowerDomainThenValidCountIsReturnedAndVerifySysmanPowerGetCallSucceeds) {
81     init(true);
82 
83     uint32_t count = 0;
84     EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
85     EXPECT_EQ(count, powerHandleComponentCount);
86 
87     count = count + 1;
88     EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
89     EXPECT_EQ(count, powerHandleComponentCount);
90 }
91 
TEST_F(SysmanDevicePowerFixture,GivenComponentCountZeroWhenEnumeratingPowerDomainThenValidPowerHandlesIsReturned)92 TEST_F(SysmanDevicePowerFixture, GivenComponentCountZeroWhenEnumeratingPowerDomainThenValidPowerHandlesIsReturned) {
93     init(true);
94 
95     uint32_t count = 0;
96     EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, nullptr), ZE_RESULT_SUCCESS);
97     EXPECT_EQ(count, powerHandleComponentCount);
98 
99     std::vector<zes_pwr_handle_t> handles(count, nullptr);
100     EXPECT_EQ(zesDeviceEnumPowerDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
101     for (auto handle : handles) {
102         EXPECT_NE(handle, nullptr);
103     }
104 }
105 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenGettingPowerPropertiesAllowSetToTrueThenCallSucceeds)106 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAllowSetToTrueThenCallSucceeds) {
107     // Setting allow set calls or not
108     init(true);
109 
110     auto handles = get_power_handles(powerHandleComponentCount);
111 
112     for (auto handle : handles) {
113         zes_power_properties_t properties;
114 
115         ze_result_t result = zesPowerGetProperties(handle, &properties);
116 
117         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
118         EXPECT_FALSE(properties.onSubdevice);
119         EXPECT_EQ(properties.subdeviceId, 0);
120         EXPECT_TRUE(properties.canControl);
121         EXPECT_TRUE(properties.isEnergyThresholdSupported);
122         EXPECT_EQ(properties.maxLimit, pKmdSysManager->mockMaxPowerLimit);
123         EXPECT_EQ(properties.minLimit, pKmdSysManager->mockMinPowerLimit);
124         EXPECT_EQ(properties.defaultLimit, pKmdSysManager->mockTpdDefault);
125     }
126 }
127 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenGettingPowerPropertiesAllowSetToFalseThenCallSucceeds)128 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerPropertiesAllowSetToFalseThenCallSucceeds) {
129     // Setting allow set calls or not
130     init(false);
131 
132     auto handles = get_power_handles(powerHandleComponentCount);
133 
134     for (auto handle : handles) {
135         zes_power_properties_t properties;
136 
137         ze_result_t result = zesPowerGetProperties(handle, &properties);
138 
139         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
140         EXPECT_FALSE(properties.onSubdevice);
141         EXPECT_EQ(properties.subdeviceId, 0);
142         EXPECT_FALSE(properties.canControl);
143         EXPECT_FALSE(properties.isEnergyThresholdSupported);
144         EXPECT_EQ(properties.maxLimit, pKmdSysManager->mockMaxPowerLimit);
145         EXPECT_EQ(properties.minLimit, pKmdSysManager->mockMinPowerLimit);
146         EXPECT_EQ(properties.defaultLimit, pKmdSysManager->mockTpdDefault);
147     }
148 }
149 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved)150 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerEnergyCounterThenValidPowerReadingsRetrieved) {
151     // Setting allow set calls or not
152     init(true);
153 
154     auto handles = get_power_handles(powerHandleComponentCount);
155 
156     for (auto handle : handles) {
157         zes_power_energy_counter_t energyCounter;
158 
159         ze_result_t result = zesPowerGetEnergyCounter(handle, &energyCounter);
160 
161         uint32_t conversionUnit = (1 << pKmdSysManager->mockEnergyUnit);
162         double valueConverted = static_cast<double>(pKmdSysManager->mockEnergyCounter) / static_cast<double>(conversionUnit);
163         valueConverted *= static_cast<double>(convertJouleToMicroJoule);
164         uint64_t mockEnergytoMicroJoules = static_cast<uint64_t>(valueConverted);
165         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
166         EXPECT_EQ(energyCounter.energy, mockEnergytoMicroJoules);
167         EXPECT_EQ(energyCounter.timestamp, convertTStoMicroSec(pKmdSysManager->mockTimeStamp, pKmdSysManager->mockFrequencyTimeStamp));
168     }
169 }
170 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenGettingPowerLimitsAllowSetToFalseThenCallSucceedsWithValidPowerReadingsRetrieved)171 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenGettingPowerLimitsAllowSetToFalseThenCallSucceedsWithValidPowerReadingsRetrieved) {
172     // Setting allow set calls or not
173     init(false);
174 
175     auto handles = get_power_handles(powerHandleComponentCount);
176 
177     for (auto handle : handles) {
178         zes_power_sustained_limit_t sustained;
179         zes_power_burst_limit_t burst;
180         zes_power_peak_limit_t peak;
181 
182         ze_result_t result = zesPowerGetLimits(handle, &sustained, &burst, &peak);
183 
184         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
185         EXPECT_TRUE(sustained.enabled);
186         EXPECT_EQ(sustained.power, pKmdSysManager->mockPowerLimit1);
187         EXPECT_EQ(sustained.interval, pKmdSysManager->mockTauPowerLimit1);
188         EXPECT_TRUE(burst.enabled);
189         EXPECT_EQ(burst.power, pKmdSysManager->mockPowerLimit2);
190         EXPECT_EQ(peak.powerAC, pKmdSysManager->mockAcPowerPeak);
191         EXPECT_EQ(peak.powerDC, pKmdSysManager->mockDcPowerPeak);
192     }
193 }
194 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenSettingPowerLimitsAllowSetToFalseThenCallFails)195 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerLimitsAllowSetToFalseThenCallFails) {
196     // Setting allow set calls or not
197     init(false);
198 
199     auto handles = get_power_handles(powerHandleComponentCount);
200 
201     for (auto handle : handles) {
202         zes_power_sustained_limit_t sustained;
203         zes_power_burst_limit_t burst;
204         zes_power_peak_limit_t peak;
205 
206         ze_result_t result = zesPowerGetLimits(handle, &sustained, &burst, &peak);
207 
208         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
209 
210         sustained.power += 1000;
211 
212         result = zesPowerSetLimits(handle, &sustained, &burst, &peak);
213 
214         EXPECT_NE(ZE_RESULT_SUCCESS, result);
215     }
216 }
217 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenSettingEnergyThresholdAllowSetToFalseThenCallFails)218 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingEnergyThresholdAllowSetToFalseThenCallFails) {
219     // Setting allow set calls or not
220     init(false);
221 
222     auto handles = get_power_handles(powerHandleComponentCount);
223 
224     for (auto handle : handles) {
225         double energyThreshold = 2000;
226 
227         ze_result_t result = zesPowerSetEnergyThreshold(handle, energyThreshold);
228 
229         EXPECT_NE(ZE_RESULT_SUCCESS, result);
230     }
231 }
232 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenSettingEnergyThresholdAllowSetToTrueThenCallSucceeds)233 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingEnergyThresholdAllowSetToTrueThenCallSucceeds) {
234     // Setting allow set calls or not
235     init(true);
236 
237     auto handles = get_power_handles(powerHandleComponentCount);
238 
239     for (auto handle : handles) {
240         double energyThreshold = 2000;
241 
242         ze_result_t result = zesPowerSetEnergyThreshold(handle, energyThreshold);
243 
244         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
245 
246         zes_energy_threshold_t newEnergyThreshold;
247         result = zesPowerGetEnergyThreshold(handle, &newEnergyThreshold);
248 
249         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
250         EXPECT_EQ(newEnergyThreshold.threshold, energyThreshold);
251     }
252 }
253 
TEST_F(SysmanDevicePowerFixture,GivenValidPowerHandleWhenSettingPowerLimitsAllowSetToTrueThenCallSucceeds)254 TEST_F(SysmanDevicePowerFixture, GivenValidPowerHandleWhenSettingPowerLimitsAllowSetToTrueThenCallSucceeds) {
255     // Setting allow set calls or not
256     init(true);
257 
258     auto handles = get_power_handles(powerHandleComponentCount);
259 
260     for (auto handle : handles) {
261         zes_power_sustained_limit_t sustained;
262         zes_power_burst_limit_t burst;
263         zes_power_peak_limit_t peak;
264 
265         uint32_t powerIncrement = 1500;
266         uint32_t timeIncrement = 12000;
267         uint32_t AcPeakPower = 56000;
268         uint32_t DcPeakPower = 44100;
269 
270         ze_result_t result = zesPowerGetLimits(handle, &sustained, &burst, &peak);
271 
272         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
273 
274         sustained.power += powerIncrement;
275         sustained.interval += timeIncrement;
276         burst.power += powerIncrement;
277         peak.powerAC = AcPeakPower;
278         peak.powerDC = DcPeakPower;
279 
280         result = zesPowerSetLimits(handle, &sustained, &burst, &peak);
281 
282         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
283 
284         zes_power_sustained_limit_t newSustained;
285         zes_power_burst_limit_t newBurst;
286         zes_power_peak_limit_t newPeak;
287 
288         result = zesPowerGetLimits(handle, &newSustained, &newBurst, &newPeak);
289 
290         EXPECT_EQ(ZE_RESULT_SUCCESS, result);
291 
292         EXPECT_EQ(newSustained.power, sustained.power);
293         EXPECT_EQ(newSustained.interval, sustained.interval);
294         EXPECT_EQ(newBurst.power, burst.power);
295         EXPECT_EQ(newPeak.powerAC, peak.powerAC);
296         EXPECT_EQ(newPeak.powerDC, peak.powerDC);
297     }
298 }
299 
300 } // namespace ult
301 } // namespace L0
302