1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include <random>
20 #include <set>
21
22 #include "adaptivecpu/Model.h"
23 #include "mocks.h"
24
25 using std::chrono_literals::operator""ns;
26 using testing::_;
27 using testing::ByMove;
28 using testing::Return;
29 using testing::UnorderedElementsAre;
30
31 namespace aidl {
32 namespace google {
33 namespace hardware {
34 namespace power {
35 namespace impl {
36 namespace pixel {
37
TEST(ModelTest,ModelInput_SetCpuFreqiencies)38 TEST(ModelTest, ModelInput_SetCpuFreqiencies) {
39 const ModelInput expected{
40 .cpuPolicyAverageFrequencyHz = {100, 101, 102},
41 };
42 ModelInput actual;
43 ASSERT_TRUE(actual.SetCpuFreqiencies({
44 {.policyId = 0, .averageFrequencyHz = 100},
45 {.policyId = 4, .averageFrequencyHz = 101},
46 {.policyId = 6, .averageFrequencyHz = 102},
47 }));
48 ASSERT_EQ(actual, expected);
49 }
50
TEST(ModelTest,ModelInput_SetCpuFreqiencies_failsWithOutOfOrderFrquencies)51 TEST(ModelTest, ModelInput_SetCpuFreqiencies_failsWithOutOfOrderFrquencies) {
52 ASSERT_FALSE(ModelInput().SetCpuFreqiencies({
53 {.policyId = 0, .averageFrequencyHz = 100},
54 {.policyId = 6, .averageFrequencyHz = 102},
55 {.policyId = 4, .averageFrequencyHz = 101},
56 }));
57 }
58
TEST(ModelTest,Run_randomInputs)59 TEST(ModelTest, Run_randomInputs) {
60 std::default_random_engine generator;
61 std::uniform_real_distribution<double> frequencyDistribution(0, 1e6);
62 std::uniform_real_distribution<double> idleTimesDistribution(0, 1);
63 std::uniform_int_distribution<uint32_t> frameTimeDistribution(1, 100);
64 std::uniform_int_distribution<uint16_t> numRenderedFramesDistribution(1, 20);
65 std::uniform_int_distribution<uint32_t> throttleDecisionDistribution(0, 3);
66
67 const auto randomModelInput = [&]() {
68 return ModelInput{
69 .cpuPolicyAverageFrequencyHz = {frequencyDistribution(generator),
70 frequencyDistribution(generator),
71 frequencyDistribution(generator)},
72 .cpuCoreIdleTimesPercentage =
73 {idleTimesDistribution(generator), idleTimesDistribution(generator),
74 idleTimesDistribution(generator), idleTimesDistribution(generator),
75 idleTimesDistribution(generator), idleTimesDistribution(generator),
76 idleTimesDistribution(generator), idleTimesDistribution(generator)},
77 .workDurationFeatures =
78 {.averageDuration =
79 std::chrono::nanoseconds(frameTimeDistribution(generator)),
80 .maxDuration = std::chrono::nanoseconds(frameTimeDistribution(generator)),
81 .numMissedDeadlines = numRenderedFramesDistribution(generator),
82 .numDurations = numRenderedFramesDistribution(generator)},
83 .previousThrottleDecision =
84 static_cast<ThrottleDecision>(throttleDecisionDistribution(generator)),
85 };
86 };
87
88 for (int i = 0; i < 10; i++) {
89 std::deque<ModelInput> modelInputs{randomModelInput(), randomModelInput(),
90 randomModelInput()};
91 Model().Run(modelInputs, AdaptiveCpuConfig::DEFAULT);
92 }
93 }
94
TEST(ModelTest,Run_randomThrottling)95 TEST(ModelTest, Run_randomThrottling) {
96 ModelInput modelInput{
97 .cpuPolicyAverageFrequencyHz = {0, 0, 0},
98 .cpuCoreIdleTimesPercentage = {0, 0, 0, 0, 0, 0, 0, 0},
99 .workDurationFeatures = {.averageDuration = 0ns,
100 .maxDuration = 0ns,
101 .numMissedDeadlines = 0,
102 .numDurations = 0},
103 .previousThrottleDecision = ThrottleDecision::NO_THROTTLE,
104 };
105 std::deque<ModelInput> modelInputs{modelInput, modelInput, modelInput};
106
107 AdaptiveCpuConfig config = AdaptiveCpuConfig::DEFAULT;
108 config.randomThrottleOptions = {ThrottleDecision::THROTTLE_70, ThrottleDecision::THROTTLE_80};
109 config.randomThrottleDecisionProbability = 1;
110
111 std::set<ThrottleDecision> actualThrottleDecisions;
112 Model model;
113 for (int i = 0; i < 100; i++) {
114 ThrottleDecision throttleDecision = model.Run(modelInputs, config);
115 actualThrottleDecisions.insert(throttleDecision);
116 }
117 ASSERT_THAT(actualThrottleDecisions,
118 UnorderedElementsAre(ThrottleDecision::THROTTLE_70, ThrottleDecision::THROTTLE_80));
119 }
120
121 } // namespace pixel
122 } // namespace impl
123 } // namespace power
124 } // namespace hardware
125 } // namespace google
126 } // namespace aidl
127