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 #define LOG_TAG "powerhal-adaptivecpu"
18 #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
19
20 #include "Model.h"
21
22 #include <android-base/logging.h>
23 #include <utils/Trace.h>
24
25 namespace aidl {
26 namespace google {
27 namespace hardware {
28 namespace power {
29 namespace impl {
30 namespace pixel {
31
SetCpuFreqiencies(const std::vector<CpuPolicyAverageFrequency> & cpuPolicyAverageFrequencies)32 bool ModelInput::SetCpuFreqiencies(
33 const std::vector<CpuPolicyAverageFrequency> &cpuPolicyAverageFrequencies) {
34 ATRACE_CALL();
35 if (cpuPolicyAverageFrequencies.size() != cpuPolicyAverageFrequencyHz.size()) {
36 LOG(ERROR) << "Received incorrect amount of CPU policy frequencies, expected "
37 << cpuPolicyAverageFrequencyHz.size() << ", received "
38 << cpuPolicyAverageFrequencies.size();
39 return false;
40 }
41 int32_t previousPolicyId = -1;
42 for (uint32_t i = 0; i < cpuPolicyAverageFrequencies.size(); i++) {
43 if (previousPolicyId >= static_cast<int32_t>(cpuPolicyAverageFrequencies[i].policyId)) {
44 LOG(ERROR) << "CPU frequencies weren't sorted by policy ID, found " << previousPolicyId
45 << " " << cpuPolicyAverageFrequencies[i].policyId;
46 return false;
47 }
48 previousPolicyId = cpuPolicyAverageFrequencies[i].policyId;
49 cpuPolicyAverageFrequencyHz[i] = cpuPolicyAverageFrequencies[i].averageFrequencyHz;
50 }
51 return true;
52 }
53
LogToAtrace() const54 void ModelInput::LogToAtrace() const {
55 if (!ATRACE_ENABLED()) {
56 return;
57 }
58 ATRACE_CALL();
59 for (int i = 0; i < cpuPolicyAverageFrequencyHz.size(); i++) {
60 ATRACE_INT((std::string("ModelInput_frequency_") + std::to_string(i)).c_str(),
61 static_cast<int>(cpuPolicyAverageFrequencyHz[i]));
62 }
63 for (int i = 0; i < cpuCoreIdleTimesPercentage.size(); i++) {
64 ATRACE_INT((std::string("ModelInput_idle_") + std::to_string(i)).c_str(),
65 static_cast<int>(cpuCoreIdleTimesPercentage[i] * 100));
66 }
67 ATRACE_INT("ModelInput_workDurations_averageDurationNs",
68 workDurationFeatures.averageDuration.count());
69 ATRACE_INT("ModelInput_workDurations_maxDurationNs", workDurationFeatures.maxDuration.count());
70 ATRACE_INT("ModelInput_workDurations_numMissedDeadlines",
71 workDurationFeatures.numMissedDeadlines);
72 ATRACE_INT("ModelInput_workDurations_numDurations", workDurationFeatures.numDurations);
73 ATRACE_INT("ModelInput_prevThrottle", (int)previousThrottleDecision);
74 ATRACE_INT("ModelInput_device", static_cast<int>(device));
75 }
76
Run(const std::deque<ModelInput> & modelInputs,const AdaptiveCpuConfig & config)77 ThrottleDecision Model::Run(const std::deque<ModelInput> &modelInputs,
78 const AdaptiveCpuConfig &config) {
79 ATRACE_CALL();
80 if (config.randomThrottleDecisionProbability > 0 &&
81 mShouldRandomThrottleDistribution(mGenerator) < config.randomThrottleDecisionProbability) {
82 std::uniform_int_distribution<uint32_t> optionDistribution(
83 0, config.randomThrottleOptions.size() - 1);
84 const ThrottleDecision throttleDecision =
85 config.randomThrottleOptions[optionDistribution(mGenerator)];
86 LOG(VERBOSE) << "Randomly overrided throttle decision: "
87 << static_cast<uint32_t>(throttleDecision);
88 ATRACE_INT("AdaptiveCpu_randomThrottleDecision", static_cast<uint32_t>(throttleDecision));
89 return throttleDecision;
90 }
91 ATRACE_INT("AdaptiveCpu_randomThrottleDecision", -1);
92 return RunDecisionTree(modelInputs);
93 }
94
RunDecisionTree(const std::deque<ModelInput> & modelInputs)95 ThrottleDecision Model::RunDecisionTree(const std::deque<ModelInput> &modelInputs
96 __attribute__((unused))) {
97 ATRACE_CALL();
98 #include "models/model.inc"
99 }
100
101 } // namespace pixel
102 } // namespace impl
103 } // namespace power
104 } // namespace hardware
105 } // namespace google
106 } // namespace aidl
107