| #!/usr/bin/env vpython3 |
| # Copyright 2020 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import datetime |
| import os |
| import sys |
| import xml.etree.ElementTree as ET |
| |
| # Add tools/perf to sys.path. |
| sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) |
| |
| from core import path_util |
| path_util.AddPyUtilsToPath() |
| path_util.AddTracingToPath() |
| |
| from core.perfetto_binary_roller import binary_deps_manager |
| from core.tbmv3 import trace_processor |
| from py_utils import tempfile_ext |
| |
| |
| def ExtractValues(xml_path): |
| root = ET.parse(xml_path).getroot() |
| |
| speeds = [] |
| power = [] |
| clusters = [] |
| for array in root.iter('array'): |
| if array.get('name') == 'cpu.clusters.cores': |
| clusters = [int(value.text) for value in array.iter('value')] |
| if array.get('name').startswith('cpu.core_speeds.'): |
| speeds.append([int(value.text) for value in array.iter('value')]) |
| if array.get('name').startswith('cpu.core_power.'): |
| power.append([float(value.text) for value in array.iter('value')]) |
| |
| values = [] |
| cpu = 0 |
| for cluster, n_cpus in enumerate(clusters): |
| for _ in range(n_cpus): |
| for freq, drain in zip(speeds[cluster], power[cluster]): |
| # TODO(khokhlov): Remove the correction when power profiles are updated. |
| corrected_drain = drain / n_cpus |
| values.append((cpu, cluster, freq, corrected_drain)) |
| cpu += 1 |
| |
| return values |
| |
| |
| def ExportProfiles(device_xmls, sql_path): |
| sql_values = [] |
| for device, xml_path in device_xmls: |
| sql_values += [ |
| '("%s", %s, %s, %s, %s)' % ((device, ) + v) |
| for v in ExtractValues(xml_path) |
| ] |
| |
| with open(sql_path, 'w') as sql_file: |
| sql_file.write('INSERT INTO power_profile VALUES\n') |
| sql_file.write(',\n'.join(sql_values)) |
| sql_file.write(';\n') |
| |
| |
| def main(args): |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| '--device-xml', |
| nargs=2, |
| metavar=('DEVICE', 'XML_FILE'), |
| action='append', |
| help='Device name and path to the XML file with the device ' |
| 'power profile. Can be used multiple times.') |
| |
| args = parser.parse_args(args) |
| |
| with tempfile_ext.NamedTemporaryDirectory() as tempdir: |
| sql_path = os.path.join(tempdir, trace_processor.POWER_PROFILE_SQL) |
| ExportProfiles(args.device_xml, sql_path) |
| version = datetime.datetime.now().strftime('%Y%m%dT%H%M%S') |
| binary_deps_manager.UploadAndSwitchDataFile( |
| trace_processor.POWER_PROFILE_SQL, sql_path, version) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |