1 /*
2  * Copyright (C) 2018 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 package com.android.powermodel.component;
18 
19 import java.util.Arrays;
20 import java.util.HashMap;
21 
22 import com.android.powermodel.ComponentProfile;
23 import com.android.powermodel.ParseException;
24 
25 public class CpuProfile extends ComponentProfile {
26     public float suspendMa;
27     public float idleMa;
28     public float activeMa;
29     public Cluster[] clusters;
30 
31     public static class Cluster {
32         public int coreCount;
33         public float onMa;
34         public Frequency[] frequencies;
35     }
36 
37     public static class Frequency {
38         public int speedHz;
39         public float onMa;
40     }
41 
42     public static class Builder {
43         private float mSuspendMa;
44         private float mIdleMa;
45         private float mActiveMa;
46         private int[] mCoreCount;
47         private HashMap<Integer,Float> mClusterOnPower = new HashMap<Integer,Float>();
48         private HashMap<Integer,int[]> mCoreSpeeds = new HashMap<Integer,int[]>();
49         private HashMap<Integer,float[]> mCorePower = new HashMap<Integer,float[]>();
50 
Builder()51         public Builder() {
52         }
53 
setSuspendMa(float value)54         public void setSuspendMa(float value) throws ParseException {
55             mSuspendMa = value;
56         }
57 
setIdleMa(float value)58         public void setIdleMa(float value) throws ParseException {
59             mIdleMa = value;
60         }
61 
setActiveMa(float value)62         public void setActiveMa(float value) throws ParseException {
63             mActiveMa = value;
64         }
65 
setCoreCount(int[] value)66         public void setCoreCount(int[] value) throws ParseException {
67             mCoreCount = Arrays.copyOf(value, value.length);
68         }
69 
setClusterPower(int cluster, float value)70         public void setClusterPower(int cluster, float value) throws ParseException {
71             mClusterOnPower.put(cluster, value);
72         }
73 
setCoreSpeeds(int cluster, int[] value)74         public void setCoreSpeeds(int cluster, int[] value) throws ParseException {
75             mCoreSpeeds.put(cluster, Arrays.copyOf(value, value.length));
76             float[] power = mCorePower.get(cluster);
77             if (power != null && value.length != power.length) {
78                 throw new ParseException("length of cpu.core_speeds.cluster" + cluster
79                         + " (" + value.length + ") is different from length of"
80                         + " cpu.core_power.cluster" + cluster + " (" + power.length + ")");
81             }
82             if (mCoreCount != null && cluster >= mCoreCount.length) {
83                 throw new ParseException("cluster " + cluster
84                         + " in cpu.core_speeds.cluster" + cluster
85                         + " is larger than the number of clusters specified in cpu.clusters.cores ("
86                         + mCoreCount.length + ")");
87             }
88         }
89 
setCorePower(int cluster, float[] value)90         public void setCorePower(int cluster, float[] value) throws ParseException {
91             mCorePower.put(cluster, Arrays.copyOf(value, value.length));
92             int[] speeds = mCoreSpeeds.get(cluster);
93             if (speeds != null && value.length != speeds.length) {
94                 throw new ParseException("length of cpu.core_power.cluster" + cluster
95                         + " (" + value.length + ") is different from length of"
96                         + " cpu.clusters.cores" + cluster + " (" + speeds.length + ")");
97             }
98             if (mCoreCount != null && cluster >= mCoreCount.length) {
99                 throw new ParseException("cluster " + cluster
100                         + " in cpu.core_power.cluster" + cluster
101                         + " is larger than the number of clusters specified in cpu.clusters.cores ("
102                         + mCoreCount.length + ")");
103             }
104         }
105 
build()106         public CpuProfile build() throws ParseException {
107             final CpuProfile result = new CpuProfile();
108 
109             // Validate cluster count
110 
111             // All null or none null
112             // TODO
113 
114             // Same size
115             // TODO
116 
117             // No gaps
118             // TODO
119 
120             // Fill in values
121             result.suspendMa = mSuspendMa;
122             result.idleMa = mIdleMa;
123             result.activeMa = mActiveMa;
124             if (mCoreCount != null) {
125                 result.clusters = new Cluster[mCoreCount.length];
126                 for (int i = 0; i < result.clusters.length; i++) {
127                     final Cluster cluster = result.clusters[i] = new Cluster();
128                     cluster.coreCount = mCoreCount[i];
129                     cluster.onMa = mClusterOnPower.get(i);
130                     int[] speeds = mCoreSpeeds.get(i);
131                     float[] power = mCorePower.get(i);
132                     cluster.frequencies = new Frequency[speeds.length];
133                     for (int j = 0; j < speeds.length; j++) {
134                         final Frequency freq = cluster.frequencies[j] = new Frequency();
135                         freq.speedHz = speeds[j];
136                         freq.onMa = power[j];
137                     }
138                 }
139             }
140 
141             return result;
142         }
143     }
144 }
145 
146