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