1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6dbdd20aSAndroid Build Coastguard Worker# Copyright 2020 The Chromium Authors. All rights reserved. 3*6dbdd20aSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*6dbdd20aSAndroid Build Coastguard Worker# found in the LICENSE file. 5*6dbdd20aSAndroid Build Coastguard Worker 6*6dbdd20aSAndroid Build Coastguard Workerimport argparse 7*6dbdd20aSAndroid Build Coastguard Workerimport os 8*6dbdd20aSAndroid Build Coastguard Workerimport sys 9*6dbdd20aSAndroid Build Coastguard Workerimport xml.etree.ElementTree as ET 10*6dbdd20aSAndroid Build Coastguard Worker 11*6dbdd20aSAndroid Build Coastguard Worker 12*6dbdd20aSAndroid Build Coastguard Workerdef ExtractValues(xml_path, correction): 13*6dbdd20aSAndroid Build Coastguard Worker root = ET.parse(xml_path).getroot() 14*6dbdd20aSAndroid Build Coastguard Worker 15*6dbdd20aSAndroid Build Coastguard Worker speeds = [] 16*6dbdd20aSAndroid Build Coastguard Worker power = [] 17*6dbdd20aSAndroid Build Coastguard Worker clusters = [] 18*6dbdd20aSAndroid Build Coastguard Worker for array in root.iter('array'): 19*6dbdd20aSAndroid Build Coastguard Worker if array.get('name') == 'cpu.clusters.cores': 20*6dbdd20aSAndroid Build Coastguard Worker clusters = [int(value.text) for value in array.iter('value')] 21*6dbdd20aSAndroid Build Coastguard Worker if array.get('name').startswith('cpu.core_speeds.'): 22*6dbdd20aSAndroid Build Coastguard Worker speeds.append([int(value.text) for value in array.iter('value')]) 23*6dbdd20aSAndroid Build Coastguard Worker if array.get('name').startswith('cpu.core_power.'): 24*6dbdd20aSAndroid Build Coastguard Worker power.append([float(value.text) for value in array.iter('value')]) 25*6dbdd20aSAndroid Build Coastguard Worker 26*6dbdd20aSAndroid Build Coastguard Worker values = [] 27*6dbdd20aSAndroid Build Coastguard Worker cpu = 0 28*6dbdd20aSAndroid Build Coastguard Worker for cluster, n_cpus in enumerate(clusters): 29*6dbdd20aSAndroid Build Coastguard Worker for _ in range(n_cpus): 30*6dbdd20aSAndroid Build Coastguard Worker for freq, drain in zip(speeds[cluster], power[cluster]): 31*6dbdd20aSAndroid Build Coastguard Worker if correction: 32*6dbdd20aSAndroid Build Coastguard Worker drain /= n_cpus 33*6dbdd20aSAndroid Build Coastguard Worker values.append((cpu, cluster, freq, drain)) 34*6dbdd20aSAndroid Build Coastguard Worker cpu += 1 35*6dbdd20aSAndroid Build Coastguard Worker 36*6dbdd20aSAndroid Build Coastguard Worker return values 37*6dbdd20aSAndroid Build Coastguard Worker 38*6dbdd20aSAndroid Build Coastguard Worker 39*6dbdd20aSAndroid Build Coastguard Workerdef ExportProfiles(device_xmls, sql_path): 40*6dbdd20aSAndroid Build Coastguard Worker sql_values = [] 41*6dbdd20aSAndroid Build Coastguard Worker for device, xml_path, correction in device_xmls: 42*6dbdd20aSAndroid Build Coastguard Worker sql_values += [ 43*6dbdd20aSAndroid Build Coastguard Worker '("%s", %s, %s, %s, %s)' % ((device,) + v) 44*6dbdd20aSAndroid Build Coastguard Worker for v in ExtractValues(xml_path, correction == 'yes') 45*6dbdd20aSAndroid Build Coastguard Worker ] 46*6dbdd20aSAndroid Build Coastguard Worker 47*6dbdd20aSAndroid Build Coastguard Worker with open(sql_path, 'w') as sql_file: 48*6dbdd20aSAndroid Build Coastguard Worker sql_file.write('INSERT OR REPLACE INTO power_profile VALUES\n') 49*6dbdd20aSAndroid Build Coastguard Worker sql_file.write(',\n'.join(sql_values)) 50*6dbdd20aSAndroid Build Coastguard Worker sql_file.write(';\n') 51*6dbdd20aSAndroid Build Coastguard Worker 52*6dbdd20aSAndroid Build Coastguard Worker 53*6dbdd20aSAndroid Build Coastguard Workerdef main(args): 54*6dbdd20aSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 55*6dbdd20aSAndroid Build Coastguard Worker description='Export XML power profile as a SQL INSERT query.', 56*6dbdd20aSAndroid Build Coastguard Worker epilog='Example usage:\n' 57*6dbdd20aSAndroid Build Coastguard Worker 'python export_power_profiles.py ' 58*6dbdd20aSAndroid Build Coastguard Worker '--device-xml sailfish sailfish/power_profile.xml no ' 59*6dbdd20aSAndroid Build Coastguard Worker '--device-xml sargo sargo/power_profile.xml yes ' 60*6dbdd20aSAndroid Build Coastguard Worker '--output power_profile_data.sql') 61*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 62*6dbdd20aSAndroid Build Coastguard Worker '--device-xml', 63*6dbdd20aSAndroid Build Coastguard Worker nargs=3, 64*6dbdd20aSAndroid Build Coastguard Worker metavar=('DEVICE', 'XML_FILE', 'CORRECTION'), 65*6dbdd20aSAndroid Build Coastguard Worker action='append', 66*6dbdd20aSAndroid Build Coastguard Worker help='First argument: device name; second argument: path to the XML ' 67*6dbdd20aSAndroid Build Coastguard Worker 'file with the device power profile; third argument(yes|no): ' 68*6dbdd20aSAndroid Build Coastguard Worker 'whether correction is necessary. Can be used multiple times.') 69*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 70*6dbdd20aSAndroid Build Coastguard Worker '--output', metavar='SQL_FILE', help='Path to the output file.') 71*6dbdd20aSAndroid Build Coastguard Worker 72*6dbdd20aSAndroid Build Coastguard Worker args = parser.parse_args(args) 73*6dbdd20aSAndroid Build Coastguard Worker 74*6dbdd20aSAndroid Build Coastguard Worker sql_path = 'result.sql' 75*6dbdd20aSAndroid Build Coastguard Worker ExportProfiles(args.device_xml, args.output) 76*6dbdd20aSAndroid Build Coastguard Worker 77*6dbdd20aSAndroid Build Coastguard Worker 78*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__': 79*6dbdd20aSAndroid Build Coastguard Worker sys.exit(main(sys.argv[1:])) 80