1 /*
2  * Copyright (C) 2024 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 <aidl/android/hardware/power/WorkDuration.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "aidl/GpuCalculationHelpers.h"
22 
23 using aidl::android::hardware::power::WorkDuration;
24 using std::literals::chrono_literals::operator""ms;
25 using std::literals::chrono_literals::operator""ns;
26 using std::literals::chrono_literals::operator""h;
27 using testing::DoubleEq;
28 
29 namespace aidl {
30 namespace google {
31 namespace hardware {
32 namespace power {
33 namespace impl {
34 namespace pixel {
35 
36 template <typename R, typename D>
to_int_nanoseconds(std::chrono::duration<R,D> duration)37 inline int64_t to_int_nanoseconds(std::chrono::duration<R, D> duration) {
38     return std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
39 }
40 
TEST(GpuCapacityCalculation,gpu_total_time_attribution)41 TEST(GpuCapacityCalculation, gpu_total_time_attribution) {
42     EXPECT_THAT(gpu_time_attribution(12ms, 0ms), DoubleEq(0));
43     EXPECT_THAT(gpu_time_attribution(12ms, 8ms), DoubleEq(2.0 / 3.0));
44     EXPECT_THAT(gpu_time_attribution(12ms, 6ms), DoubleEq(0.5));
45     EXPECT_THAT(gpu_time_attribution(12ms, 12ms), DoubleEq(1.0));
46     EXPECT_THAT(gpu_time_attribution(12ms, 12ms), DoubleEq(1.0));
47 }
48 
TEST(GpuCapacityCalculation,total_time_of_zero_reports_zero_capacity)49 TEST(GpuCapacityCalculation, total_time_of_zero_reports_zero_capacity) {
50     EXPECT_THAT(gpu_time_attribution(0ms, 8ms), DoubleEq(0.0));
51     EXPECT_THAT(gpu_time_attribution(0ms, 0ms), DoubleEq(0.0));
52 }
53 
TEST(GpuCapacityCalculation,no_overrun_frame)54 TEST(GpuCapacityCalculation, no_overrun_frame) {
55     WorkDuration observation{
56             .durationNanos = to_int_nanoseconds(12ms),
57             .cpuDurationNanos = to_int_nanoseconds(8ms),
58             .gpuDurationNanos = to_int_nanoseconds(8ms),
59     };
60     std::chrono::nanoseconds total_target =
61             std::chrono::duration_cast<std::chrono::nanoseconds>(15ms);
62 
63     EXPECT_EQ(calculate_capacity(observation, total_target, 1000_hz), Cycles(0));
64 }
65 
TEST(GpuCapacityCalculation,basic_50_50_frame)66 TEST(GpuCapacityCalculation, basic_50_50_frame) {
67     WorkDuration observation{
68             .durationNanos = to_int_nanoseconds(12ms),
69             .cpuDurationNanos = to_int_nanoseconds(8ms),
70             .gpuDurationNanos = to_int_nanoseconds(8ms),
71     };
72     EXPECT_EQ(calculate_capacity(observation, 10ms, 1000000_hz), Cycles(1333));
73 }
74 
TEST(GpuCapacityCalculation,frame_10_90)75 TEST(GpuCapacityCalculation, frame_10_90) {
76     WorkDuration observation{
77             .durationNanos = to_int_nanoseconds(10ms),
78             .cpuDurationNanos = to_int_nanoseconds(1ms),
79             .gpuDurationNanos = to_int_nanoseconds(9ms),
80     };
81     EXPECT_EQ(calculate_capacity(observation, 9ms, 100000_hz), Cycles(90));
82 }
83 
TEST(GpuCapacityCalculation,frame_0_100)84 TEST(GpuCapacityCalculation, frame_0_100) {
85     WorkDuration observation{
86             .durationNanos = to_int_nanoseconds(10ms),
87             .cpuDurationNanos = to_int_nanoseconds(0ms),
88             .gpuDurationNanos = to_int_nanoseconds(10ms),
89     };
90     EXPECT_EQ(calculate_capacity(observation, 9ms, 100000_hz), Cycles(100));
91 }
92 
TEST(GpuCapacityCalculation,frame_40_60_parallel)93 TEST(GpuCapacityCalculation, frame_40_60_parallel) {
94     WorkDuration observation{
95             .durationNanos = to_int_nanoseconds(10ms),
96             .cpuDurationNanos = to_int_nanoseconds(6ms),
97             .gpuDurationNanos = to_int_nanoseconds(8ms),
98     };
99     EXPECT_EQ(calculate_capacity(observation, 9ms, 100000000_hz), Cycles(80000));
100 }
101 
TEST(GpuCapacityCalculation,frame_100_0)102 TEST(GpuCapacityCalculation, frame_100_0) {
103     WorkDuration observation{
104             .durationNanos = to_int_nanoseconds(10ms),
105             .cpuDurationNanos = to_int_nanoseconds(10ms),
106             .gpuDurationNanos = to_int_nanoseconds(0ms),
107     };
108     EXPECT_EQ(calculate_capacity(observation, 9ms, 100000_hz), Cycles(0));
109 }
110 
TEST(GpuCapacityCalculation,frame_100_100)111 TEST(GpuCapacityCalculation, frame_100_100) {
112     WorkDuration observation{
113             .durationNanos = to_int_nanoseconds(10ms),
114             .cpuDurationNanos = to_int_nanoseconds(10ms),
115             .gpuDurationNanos = to_int_nanoseconds(10ms),
116     };
117     EXPECT_EQ(calculate_capacity(observation, 9ms, 100000_hz), Cycles(100));
118 }
119 
TEST(GpuCapacityCalculation,report_underaccounts_total_50_50)120 TEST(GpuCapacityCalculation, report_underaccounts_total_50_50) {
121     WorkDuration observation{
122             .durationNanos = to_int_nanoseconds(12ms),
123             .cpuDurationNanos = to_int_nanoseconds(4ms),
124             .gpuDurationNanos = to_int_nanoseconds(4ms),
125     };
126     EXPECT_EQ(calculate_capacity(observation, 10ms, 1000_hz), Cycles(1));
127 }
128 
TEST(GpuCapacityCalculation,report_underaccounts_total_90_10)129 TEST(GpuCapacityCalculation, report_underaccounts_total_90_10) {
130     WorkDuration observation{
131             .durationNanos = to_int_nanoseconds(20ms),
132             .cpuDurationNanos = to_int_nanoseconds(9ms),
133             .gpuDurationNanos = to_int_nanoseconds(1ms),
134     };
135     EXPECT_EQ(calculate_capacity(observation, 10ms, 100000_hz), Cycles(100));
136 }
137 
TEST(GpuCapacityCalculation,frame_very_long_report)138 TEST(GpuCapacityCalculation, frame_very_long_report) {
139     WorkDuration observation{
140             .durationNanos = to_int_nanoseconds(10h),
141             .cpuDurationNanos = to_int_nanoseconds(1h),
142             .gpuDurationNanos = to_int_nanoseconds(9h),
143     };
144     EXPECT_EQ(calculate_capacity(observation, 9h, 10_hz),
145               Cycles(9 * std::chrono::duration_cast<std::chrono::seconds>(1h).count()));
146 }
147 
TEST(GpuCapacityCalculation,frame_nonsense_frequency)148 TEST(GpuCapacityCalculation, frame_nonsense_frequency) {
149     WorkDuration observation{
150             .durationNanos = to_int_nanoseconds(10ms),
151             .cpuDurationNanos = to_int_nanoseconds(1ms),
152             .gpuDurationNanos = to_int_nanoseconds(9ms),
153     };
154     EXPECT_EQ(calculate_capacity(observation, 9ms, Frequency(-10)), Cycles(0));
155     EXPECT_EQ(calculate_capacity(observation, 9ms, Frequency(0)), Cycles(0));
156 }
157 
TEST(GpuCapacityCalculation,frame_nonsense_report)158 TEST(GpuCapacityCalculation, frame_nonsense_report) {
159     WorkDuration observation{
160             .durationNanos = to_int_nanoseconds(10ms),
161             .cpuDurationNanos = to_int_nanoseconds(1ms),
162             .gpuDurationNanos = to_int_nanoseconds(1ms),
163     };
164     EXPECT_EQ(calculate_capacity(observation, 9ms, 100_hz), Cycles(0));
165 }
166 
TEST(GpuCapacityCalculation,frame_nonsense_target)167 TEST(GpuCapacityCalculation, frame_nonsense_target) {
168     WorkDuration observation{
169             .durationNanos = to_int_nanoseconds(10ms),
170             .cpuDurationNanos = to_int_nanoseconds(1ms),
171             .gpuDurationNanos = to_int_nanoseconds(1ms),
172     };
173     EXPECT_EQ(calculate_capacity(observation, 0ms, 100_hz), Cycles(0));
174     EXPECT_EQ(calculate_capacity(observation, -1ms, 100_hz), Cycles(0));
175 }
176 
TEST(GpuCapacityCalculation,frame_nonsense_subtarget_cpu)177 TEST(GpuCapacityCalculation, frame_nonsense_subtarget_cpu) {
178     WorkDuration observation{
179             .durationNanos = to_int_nanoseconds(20ms),
180             .cpuDurationNanos = to_int_nanoseconds(40ms),
181             .gpuDurationNanos = to_int_nanoseconds(20ms),
182     };
183     EXPECT_EQ(calculate_capacity(observation, 10ms, 100000_hz), Cycles(0));
184 }
185 
TEST(GpuCapacityCalculation,frame_nonsense_subtarget_gpu)186 TEST(GpuCapacityCalculation, frame_nonsense_subtarget_gpu) {
187     WorkDuration observation{
188             .durationNanos = to_int_nanoseconds(20ms),
189             .cpuDurationNanos = to_int_nanoseconds(20ms),
190             .gpuDurationNanos = to_int_nanoseconds(40ms),
191     };
192     EXPECT_EQ(calculate_capacity(observation, 10ms, 100000_hz), Cycles(0));
193 }
194 
195 }  // namespace pixel
196 }  // namespace impl
197 }  // namespace power
198 }  // namespace hardware
199 }  // namespace google
200 }  // namespace aidl
201