diff --git a/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb b/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb index 8dc705bd3ae16e2ee7ece90040232399f307f122..13fc942eaac8c5df5d51f67a2763a5114afacec5 100644 --- a/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb +++ b/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb @@ -92,10 +92,10 @@ " \"conf\" : {\n", " #'iio-capture' : '/usr/bin/iio-capture',\n", " #'ip_address' : 'baylibre-acme.local',\n", - " 'channels' : {\n", - " 'Device0' : 0,\n", - " 'Device1' : 1,\n", - " }\n", + " },\n", + " 'channel_map' : {\n", + " 'Device0' : 0,\n", + " 'Device1' : 1,\n", " }\n", " },\n", " \n", @@ -235,7 +235,7 @@ "rtapp.run(out_dir=te.res_dir)\n", "\n", "# EnergyMeter Stop and samples collection\n", - "channels_nrg, nrg_file = te.emeter.report(te.res_dir)" + "nrg_report = te.emeter.report(te.res_dir)" ] }, { @@ -299,7 +299,7 @@ ], "source": [ "logging.info(\"Measured channels energy:\")\n", - "logging.info(\"%s\", channels_nrg)" + "logging.info(\"%s\", nrg_report.channels)" ] }, { @@ -330,8 +330,8 @@ ], "source": [ "logging.info(\"Returned energy file:\")\n", - "logging.info(\" %s\", nrg_file)\n", - "!cat $nrg_file" + "logging.info(\" %s\", nrg_report.report_file)\n", + "!cat $nrg_report.report_file" ] }, { @@ -377,7 +377,7 @@ } ], "source": [ - "stats_file = nrg_file.replace('.json', '_stats.json')\n", + "stats_file = nrg_report.report_file.replace('.json', '_stats.json')\n", "logging.info(\"Complete energy stats:\")\n", "logging.info(\" %s\", stats_file)\n", "!cat $stats_file" diff --git a/ipynb/examples/energy_meter/EnergyMeter_AEP.ipynb b/ipynb/examples/energy_meter/EnergyMeter_AEP.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..0ceeeb6845cdf8b93fae46b0336fdeb7353fa213 --- /dev/null +++ b/ipynb/examples/energy_meter/EnergyMeter_AEP.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Energy Meter Examples\n", + "
\n", + "ARM Energy Probe\n", + "
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook shows how to use the `AEP` energy meters.\n", + "\n", + "*NOTE*: `caiman` is required to collect data from the probe. Instructions on how to install it can be found here https://github.com/ARM-software/lisa/wiki/Energy-Meters-Requirements#arm-energy-probe-aep" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Import Required Modules" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import logging\n", + "reload(logging)\n", + "logging.basicConfig(\n", + " format='%(asctime)-9s %(levelname)-8s: %(message)s',\n", + " datefmt='%I:%M:%S')\n", + "\n", + "# Enable logging at INFO level\n", + "logging.getLogger().setLevel(logging.INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Generate plots inline\n", + "%matplotlib inline\n", + "\n", + "import os\n", + "\n", + "# Support to access the remote target\n", + "import devlib\n", + "from env import TestEnv\n", + "\n", + "# RTApp configurator for generation of PERIODIC tasks\n", + "from wlgen import RTA, Ramp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Target Configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Setup target configuration\n", + "my_conf = {\n", + "\n", + " # Target platform and board\n", + " \"platform\" : 'linux',\n", + " \"board\" : 'juno',\n", + " \"host\" : '192.168.0.1',\n", + "\n", + " # Folder where all the results will be collected\n", + " \"results_dir\" : \"EnergyMeter_AEP\",\n", + "\n", + " # Define devlib modules to load\n", + " \"exclude_modules\" : [ 'hwmon' ],\n", + "\n", + " # Energy Meters Configuration for ARM Energy Probe\n", + " \"emeter\" : {\n", + " \"instrument\" : \"aep\",\n", + " \"conf\" : {\n", + " # Value of the shunt resistor in Ohm\n", + " 'resistor_values' : [0.099],\n", + " # Device entry assigned to the probe on the host\n", + " 'device_entry' : '/dev/ttyACM0',\n", + " },\n", + " 'channel_map' : {\n", + " 'BAT' : 'BAT'\n", + " }\n", + " },\n", + " \n", + " # Tools required by the experiments\n", + " \"tools\" : [ 'trace-cmd', 'rt-app' ],\n", + " \n", + " # Comment this line to calibrate RTApp in your own platform\n", + " \"rtapp-calib\" : {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353},\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:29 INFO : Target - Using base path: /data/lisa\n", + "03:58:29 INFO : Target - Loading custom (inline) target configuration\n", + "03:58:29 INFO : Target - Devlib modules to load: ['bl', 'cpufreq']\n", + "03:58:29 INFO : Target - Connecting linux target:\n", + "03:58:29 INFO : Target - username : root\n", + "03:58:29 INFO : Target - host : 192.168.0.1\n", + "03:58:29 INFO : Target - password : \n", + "03:58:29 INFO : Target - Connection settings:\n", + "03:58:29 INFO : Target - {'username': 'root', 'host': '192.168.0.1', 'password': ''}\n", + "03:58:33 INFO : Target - Initializing target workdir:\n", + "03:58:33 INFO : Target - /root/devlib-target\n", + "03:58:39 INFO : Target - Topology:\n", + "03:58:39 INFO : Target - [[0, 3, 4, 5], [1, 2]]\n", + "03:58:40 INFO : Platform - Loading default EM:\n", + "03:58:40 INFO : Platform - /data/lisa/libs/utils/platforms/juno.json\n", + "03:58:40 WARNING : Target - Using configuration provided RTApp calibration\n", + "03:58:40 INFO : Target - Using RT-App calibration values:\n", + "03:58:40 INFO : Target - {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353}\n", + "03:58:40 INFO : AEP - AEP configuration\n", + "03:58:40 INFO : AEP - {'instrument': 'aep', 'channel_map': {'BAT': 'BAT'}, 'conf': {'resistor_values': [0.099], 'device_entry': '/dev/ttyACM0'}}\n", + "03:58:40 INFO : AEP - Channels selected for energy sampling:\n", + "[CHAN(BAT_current), CHAN(BAT_power), CHAN(BAT_voltage)]\n", + "03:58:40 INFO : TestEnv - Set results folder to:\n", + "03:58:40 INFO : TestEnv - /data/lisa/results/EnergyMeter_AEP\n", + "03:58:40 INFO : TestEnv - Experiment results available also in:\n", + "03:58:40 INFO : TestEnv - /data/lisa/results_latest\n" + ] + } + ], + "source": [ + "# Initialize a test environment using:\n", + "te = TestEnv(my_conf, wipe=False, force_new=True)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Workload Execution and Power Consumptions Samping" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:42 INFO : WlGen - Setup new workload ramp\n", + "03:58:42 INFO : RTApp - Workload duration defined by longest task\n", + "03:58:42 INFO : RTApp - Default policy: SCHED_OTHER\n", + "03:58:42 INFO : RTApp - ------------------------\n", + "03:58:42 INFO : RTApp - task [ramp], sched: using default policy\n", + "03:58:42 INFO : RTApp - | calibration CPU: 1\n", + "03:58:42 INFO : RTApp - | loops count: 1\n", + "03:58:42 INFO : RTApp - + phase_000001: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 60 %\n", + "03:58:42 INFO : RTApp - | run_time 60000 [us], sleep_time 40000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000002: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 55 %\n", + "03:58:42 INFO : RTApp - | run_time 55000 [us], sleep_time 45000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000003: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 50 %\n", + "03:58:42 INFO : RTApp - | run_time 50000 [us], sleep_time 50000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000004: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 45 %\n", + "03:58:42 INFO : RTApp - | run_time 45000 [us], sleep_time 55000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000005: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 40 %\n", + "03:58:42 INFO : RTApp - | run_time 40000 [us], sleep_time 60000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000006: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 35 %\n", + "03:58:42 INFO : RTApp - | run_time 35000 [us], sleep_time 65000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000007: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 30 %\n", + "03:58:42 INFO : RTApp - | run_time 30000 [us], sleep_time 70000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000008: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 25 %\n", + "03:58:42 INFO : RTApp - | run_time 25000 [us], sleep_time 75000 [us]\n", + "03:58:42 INFO : RTApp - + phase_000009: duration 0.500000 [s] (5 loops)\n", + "03:58:42 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", + "03:58:42 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", + "03:58:44 INFO : WlGen - Workload execution START:\n", + "03:58:44 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/ramp_00.json 2>&1\n" + ] + } + ], + "source": [ + "# Create and RTApp RAMP task\n", + "rtapp = RTA(te.target, 'ramp', calibration=te.calibration())\n", + "rtapp.conf(kind='profile',\n", + " params={\n", + " 'ramp' : Ramp(\n", + " start_pct = 60,\n", + " end_pct = 20,\n", + " delta_pct = 5,\n", + " time_s = 0.5).get()\n", + " })\n", + "\n", + "# EnergyMeter Start\n", + "te.emeter.reset()\n", + "\n", + "rtapp.run(out_dir=te.res_dir)\n", + "\n", + "# EnergyMeter Stop and samples collection\n", + "nrg_report = te.emeter.report(te.res_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:50 INFO : Collected data:\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[01;34m/data/lisa/results/EnergyMeter_AEP\u001b[00m\r\n", + "├── energy.json\r\n", + "├── output.log\r\n", + "├── ramp_00.json\r\n", + "├── rt-app-ramp-0.log\r\n", + "└── samples.csv\r\n", + "\r\n", + "0 directories, 5 files\r\n" + ] + } + ], + "source": [ + "logging.info(\"Collected data:\")\n", + "!tree $te.res_dir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Power Measurements Data" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:50 INFO : Measured channels energy:\n", + "03:58:50 INFO : {'BAT': 0.02506927080038548}\n" + ] + } + ], + "source": [ + "logging.info(\"Measured channels energy:\")\n", + "logging.info(\"%s\", nrg_report.channels)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:51 INFO : Generated energy file:\n", + "03:58:51 INFO : /data/lisa/results/EnergyMeter_AEP/energy.json\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"BAT\": 0.02506927080038548\r\n", + "}" + ] + } + ], + "source": [ + "logging.info(\"Generated energy file:\")\n", + "logging.info(\" %s\", nrg_report.report_file)\n", + "!cat $nrg_report.report_file" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:58:52 INFO : Samples collected for the BAT channel (only first 10)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BAT_current,BAT_power,BAT_voltage\r", + "\r\n", + "0.049,0.007,0.146\r", + "\r\n", + "0.035,0.004,0.142\r", + "\r\n", + "0.027,0.003,0.141\r", + "\r\n", + "0.029,0.004,0.151\r", + "\r\n", + "0.046,0.006,0.147\r", + "\r\n", + "0.033,0.004,0.143\r", + "\r\n", + "0.025,0.003,0.142\r", + "\r\n", + "0.029,0.004,0.154\r", + "\r\n", + "0.049,0.007,0.15\r", + "\r\n" + ] + } + ], + "source": [ + "logging.info(\"Samples collected for the BAT channel (only first 10)\")\n", + "samples_file = os.path.join(te.res_dir, 'samples.csv')\n", + "!head $samples_file" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + }, + "toc": { + "toc_cell": false, + "toc_number_sections": true, + "toc_threshold": 6, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/ipynb/examples/energy_meter/EnergyMeter_HWMON.ipynb b/ipynb/examples/energy_meter/EnergyMeter_HWMON.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..3e44599c9d9b9b99448948dc801a6e4245c91d69 --- /dev/null +++ b/ipynb/examples/energy_meter/EnergyMeter_HWMON.ipynb @@ -0,0 +1,358 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Energy Meter Examples\n", + "
\n", + "Linux Kernel HWMon\n", + "
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Import Required Modules" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import logging\n", + "reload(logging)\n", + "logging.basicConfig(\n", + " format='%(asctime)-9s %(levelname)-8s: %(message)s',\n", + " datefmt='%I:%M:%S')\n", + "\n", + "# Enable logging at INFO level\n", + "logging.getLogger().setLevel(logging.INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Generate plots inline\n", + "%matplotlib inline\n", + "\n", + "import os\n", + "\n", + "# Support to access the remote target\n", + "import devlib\n", + "from env import TestEnv\n", + "\n", + "# RTApp configurator for generation of PERIODIC tasks\n", + "from wlgen import RTA, Ramp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Target Configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Setup target configuration\n", + "my_conf = {\n", + "\n", + " # Target platform and board\n", + " \"platform\" : 'linux',\n", + " \"board\" : 'juno',\n", + " \"host\" : '192.168.0.1',\n", + "\n", + " # Folder where all the results will be collected\n", + " \"results_dir\" : \"EnergyMeter_HWMON\",\n", + "\n", + " # Energy Meters Configuration for BayLibre's ACME Cape\n", + " \"emeter\" : {\n", + " \"instrument\" : \"hwmon\",\n", + " \"conf\" : {\n", + " # Prefixes of the HWMon labels\n", + " 'sites' : ['a53', 'a57'],\n", + " # Type of hardware monitor to be used\n", + " 'kinds' : ['energy']\n", + " },\n", + " 'channel_map' : {\n", + " 'LITTLE' : 'a53',\n", + " 'big' : 'a57',\n", + " }\n", + " },\n", + " \n", + " # Tools required by the experiments\n", + " \"tools\" : [ 'trace-cmd', 'rt-app' ],\n", + " \n", + " # Comment this line to calibrate RTApp in your own platform\n", + " \"rtapp-calib\" : {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353},\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "03:59:42 INFO : Target - Using base path: /data/lisa\n", + "03:59:42 INFO : Target - Loading custom (inline) target configuration\n", + "03:59:42 INFO : Target - Devlib modules to load: ['bl', 'hwmon', 'cpufreq']\n", + "03:59:42 INFO : Target - Connecting linux target:\n", + "03:59:42 INFO : Target - username : root\n", + "03:59:42 INFO : Target - host : 192.168.0.1\n", + "03:59:42 INFO : Target - password : \n", + "03:59:42 INFO : Target - Connection settings:\n", + "03:59:42 INFO : Target - {'username': 'root', 'host': '192.168.0.1', 'password': ''}\n", + "04:00:23 INFO : Target - Initializing target workdir:\n", + "04:00:23 INFO : Target - /root/devlib-target\n", + "04:00:28 INFO : Target - Topology:\n", + "04:00:28 INFO : Target - [[0, 3, 4, 5], [1, 2]]\n", + "04:00:30 INFO : Platform - Loading default EM:\n", + "04:00:30 INFO : Platform - /data/lisa/libs/utils/platforms/juno.json\n", + "04:00:30 WARNING : Target - Using configuration provided RTApp calibration\n", + "04:00:30 INFO : Target - Using RT-App calibration values:\n", + "04:00:30 INFO : Target - {\"0\": 360, \"1\": 142, \"2\": 138, \"3\": 352, \"4\": 352, \"5\": 353}\n", + "04:00:30 INFO : HWMon - Scanning for HWMON channels, may take some time...\n", + "04:00:30 INFO : HWMon - Channels selected for energy sampling:\n", + "04:00:30 INFO : HWMon - a57_energy\n", + "04:00:30 INFO : HWMon - a53_energy\n", + "04:00:30 INFO : TestEnv - Set results folder to:\n", + "04:00:30 INFO : TestEnv - /data/lisa/results/EnergyMeter_HWMON\n", + "04:00:30 INFO : TestEnv - Experiment results available also in:\n", + "04:00:30 INFO : TestEnv - /data/lisa/results_latest\n" + ] + } + ], + "source": [ + "# Initialize a test environment using:\n", + "te = TestEnv(my_conf, wipe=False, force_new=True)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Workload Execution and Power Consumptions Samping" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "04:00:30 INFO : WlGen - Setup new workload ramp\n", + "04:00:30 INFO : RTApp - Workload duration defined by longest task\n", + "04:00:30 INFO : RTApp - Default policy: SCHED_OTHER\n", + "04:00:30 INFO : RTApp - ------------------------\n", + "04:00:30 INFO : RTApp - task [ramp], sched: using default policy\n", + "04:00:30 INFO : RTApp - | calibration CPU: 1\n", + "04:00:30 INFO : RTApp - | loops count: 1\n", + "04:00:30 INFO : RTApp - + phase_000001: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 60 %\n", + "04:00:30 INFO : RTApp - | run_time 60000 [us], sleep_time 40000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000002: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 55 %\n", + "04:00:30 INFO : RTApp - | run_time 55000 [us], sleep_time 45000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000003: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 50 %\n", + "04:00:30 INFO : RTApp - | run_time 50000 [us], sleep_time 50000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000004: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 45 %\n", + "04:00:30 INFO : RTApp - | run_time 45000 [us], sleep_time 55000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000005: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 40 %\n", + "04:00:30 INFO : RTApp - | run_time 40000 [us], sleep_time 60000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000006: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 35 %\n", + "04:00:30 INFO : RTApp - | run_time 35000 [us], sleep_time 65000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000007: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 30 %\n", + "04:00:30 INFO : RTApp - | run_time 30000 [us], sleep_time 70000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000008: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 25 %\n", + "04:00:30 INFO : RTApp - | run_time 25000 [us], sleep_time 75000 [us]\n", + "04:00:30 INFO : RTApp - + phase_000009: duration 0.500000 [s] (5 loops)\n", + "04:00:30 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", + "04:00:30 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", + "04:00:35 INFO : WlGen - Workload execution START:\n", + "04:00:35 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/ramp_00.json 2>&1\n" + ] + } + ], + "source": [ + "# Create and RTApp RAMP task\n", + "rtapp = RTA(te.target, 'ramp', calibration=te.calibration())\n", + "rtapp.conf(kind='profile',\n", + " params={\n", + " 'ramp' : Ramp(\n", + " start_pct = 60,\n", + " end_pct = 20,\n", + " delta_pct = 5,\n", + " time_s = 0.5).get()\n", + " })\n", + "\n", + "# EnergyMeter Start\n", + "te.emeter.reset()\n", + "\n", + "rtapp.run(out_dir=te.res_dir)\n", + "\n", + "# EnergyMeter Stop and samples collection\n", + "nrg_report = te.emeter.report(te.res_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "04:00:41 INFO : Collected data:\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[01;34m/data/lisa/results/EnergyMeter_HWMON\u001b[00m\r\n", + "├── energy.json\r\n", + "├── output.log\r\n", + "├── ramp_00.json\r\n", + "├── rt-app-ramp-0.log\r\n", + "├── trace.dat\r\n", + "├── trace.raw.txt\r\n", + "└── trace.txt\r\n", + "\r\n", + "0 directories, 7 files\r\n" + ] + } + ], + "source": [ + "logging.info(\"Collected data:\")\n", + "!tree $te.res_dir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Power Measurements Data" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "04:00:41 INFO : Measured channels energy:\n", + "04:00:41 INFO : {'big': 14.410717999999179, 'LITTLE': 1.1058980000016163}\n" + ] + } + ], + "source": [ + "logging.info(\"Measured channels energy:\")\n", + "logging.info(\"%s\", nrg_report.channels)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "04:00:41 INFO : Generated energy file:\n", + "04:00:41 INFO : /data/lisa/results/EnergyMeter_HWMON/energy.json\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\r\n", + " \"LITTLE\": 1.1058980000016163, \r\n", + " \"big\": 14.410717999999179\r\n", + "}" + ] + } + ], + "source": [ + "logging.info(\"Generated energy file:\")\n", + "logging.info(\" %s\", nrg_report.report_file)\n", + "!cat $nrg_report.report_file" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + }, + "toc": { + "toc_cell": false, + "toc_number_sections": true, + "toc_threshold": 6, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/ipynb/sched_dvfs/smoke_test.ipynb b/ipynb/sched_dvfs/smoke_test.ipynb index 9eab63f45898fd1b3c684ff2ec957890c6b8923f..f1699ec44ad08251fcc7b31e42b51d25209460c0 100644 --- a/ipynb/sched_dvfs/smoke_test.ipynb +++ b/ipynb/sched_dvfs/smoke_test.ipynb @@ -324,7 +324,7 @@ " rtapp.run(out_dir=exp_dir)\n", " \n", " # Stop FTrace and sample Energy consumption\n", - " nrg = te.emeter.sample()\n", + " nrg = te.emeter.report(exp_dir).channels\n", " te.ftrace.stop()\n", " \n", " logging.info('Energy: %s', nrg)\n", @@ -392,8 +392,8 @@ " for governor in confs:\n", " plot_title = \"{}\".format(governor.upper())\n", " nrg = results[tid][governor]['energy']\n", - " nrg_little = float(nrg['a53']['delta'])\n", - " nrg_big = float(nrg['a57']['delta'])\n", + " nrg_little = float(nrg['little'])\n", + " nrg_big = float(nrg['big'])\n", " nrg_sum = nrg_little + nrg_big\n", " print \"{:15s} | {:9.3f} {:9.3f} {:9.3f}\"\\\n", " .format(governor, nrg_little, nrg_big, nrg_sum)" diff --git a/ipynb/tutorial/00_LisaInANutshell.ipynb b/ipynb/tutorial/00_LisaInANutshell.ipynb index c4edc58c17399e8646115d039075695a4a01c1c7..a0a9f78c90e09a3b3370c70fbedf628f42505c32 100644 --- a/ipynb/tutorial/00_LisaInANutshell.ipynb +++ b/ipynb/tutorial/00_LisaInANutshell.ipynb @@ -881,7 +881,7 @@ " wload.run(out_dir=res_dir)\n", "\n", " logging.info('## Read energy consumption: %s/energy.json', res_dir)\n", - " nrg, nrg_file = te.emeter.report(out_dir=res_dir)\n", + " nrg_report = te.emeter.report(out_dir=res_dir)\n", "\n", " logging.info('# Stop FTrace')\n", " te.ftrace.stop()\n", @@ -897,7 +897,7 @@ " logging.info(' %s', res_dir)\n", " !tree {res_dir}\n", " \n", - " return nrg, nrg_file, plt, plt_file, trace_file" + " return nrg_report, plt, plt_file, trace_file" ] }, { @@ -963,7 +963,7 @@ } ], "source": [ - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, rtapp, te.res_dir)" + "nrg_report, plt, plt_file, trace_file = execute(te, rtapp, te.res_dir)" ] }, { @@ -1023,7 +1023,7 @@ "source": [ "import pandas as pd\n", "\n", - "df = pd.DataFrame(list(nrg.iteritems()),\n", + "df = pd.DataFrame(list(nrg_report.channels.iteritems()),\n", " columns=['Cluster', 'Energy'])\n", "df = df.set_index('Cluster')\n", "df" diff --git a/ipynb/tutorial/03_WlGenUsage.ipynb b/ipynb/tutorial/03_WlGenUsage.ipynb index c01a95ff0660932b409465611047209549a80d7f..aed96f51e56ebac2ca43d22bedffce75c405ffef 100644 --- a/ipynb/tutorial/03_WlGenUsage.ipynb +++ b/ipynb/tutorial/03_WlGenUsage.ipynb @@ -200,7 +200,7 @@ " wload.run(out_dir=res_dir)\n", "\n", " logging.info('## Read energy consumption: %s/energy.json', res_dir)\n", - " nrg, nrg_file = te.emeter.report(out_dir=res_dir)\n", + " nrg_report = te.emeter.report(out_dir=res_dir)\n", "\n", " logging.info('# Stop FTrace')\n", " te.ftrace.stop()\n", @@ -216,7 +216,7 @@ " logging.info(' %s', res_dir)\n", " !ls -la {res_dir}\n", " \n", - " return nrg, nrg_file, plt, plt_file, trace_file" + " return nrg_report, plt, plt_file, trace_file" ] }, { @@ -432,7 +432,7 @@ ], "source": [ "res_dir = os.path.join(te.res_dir, rtapp_name)\n", - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" + "nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" ] }, { @@ -469,8 +469,8 @@ ], "source": [ "# Dump the energy measured for the LITTLE and big clusters\n", - "logging.info('Energy: %s', nrg_file)\n", - "print json.dumps(nrg, indent=4, sort_keys=True)" + "logging.info('Energy: %s', nrg_report.report_file)\n", + "print json.dumps(nrg_report.channels, indent=4, sort_keys=True)" ] }, { @@ -983,7 +983,7 @@ ], "source": [ "res_dir = os.path.join(te.res_dir, rtapp_name)\n", - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" + "nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" ] }, { @@ -1108,7 +1108,7 @@ ], "source": [ "res_dir = os.path.join(te.res_dir, rtapp_name)\n", - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" + "nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)" ] }, { @@ -1333,7 +1333,7 @@ ], "source": [ "res_dir = os.path.join(te.res_dir, perf_name)\n", - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, perf, res_dir)" + "nrg_report, plt, plt_file, trace_file = execute(te, perf, res_dir)" ] }, { diff --git a/ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb b/ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb index 45881f6c4d278e62bc99c5ffcc788200fa615bd5..e92bd3f32a273cde146ac547a5cc7ffbe7deca79 100644 --- a/ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb +++ b/ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb @@ -2237,9 +2237,9 @@ "\n", " if te.emeter:\n", " logging.info('## Read energy consumption: %s/energy.json', res_dir)\n", - " nrg, nrg_file = te.emeter.report(out_dir=res_dir)\n", + " nrg_report = te.emeter.report(out_dir=res_dir)\n", " else:\n", - " nrg, nrg_file = None, None\n", + " nrg_report = None\n", "\n", " logging.info('# Stop FTrace')\n", " te.ftrace.stop()\n", @@ -2255,7 +2255,7 @@ " logging.info(' %s', res_dir)\n", " !tree {res_dir}\n", " \n", - " return nrg, nrg_file, plt, plt_file, trace_file" + " return nrg_report, plt, plt_file, trace_file" ] }, { @@ -2267,7 +2267,7 @@ }, "outputs": [], "source": [ - "nrg, nrg_file, plt, plt_file, trace_file = execute(te, rtapp, te.res_dir, cg=boostgroup.name)" + "nrg_report, plt, plt_file, trace_file = execute(te, rtapp, te.res_dir, cg=boostgroup.name)" ] }, { diff --git a/ipynb/wlgen/simple_rtapp.ipynb b/ipynb/wlgen/simple_rtapp.ipynb index d274f2bebe0920d5d3250bf476df6b25b0a4bfe9..a14398b8129a26fe53c74a749a454cf9906e34a9 100644 --- a/ipynb/wlgen/simple_rtapp.ipynb +++ b/ipynb/wlgen/simple_rtapp.ipynb @@ -298,7 +298,7 @@ "rtapp.run(out_dir=te.res_dir, cgroup=\"\")\n", "\n", "logging.info('#### Read energy consumption: %s/energy.json', te.res_dir)\n", - "(nrg, nrg_file) = te.emeter.report(out_dir=te.res_dir)\n", + "nrg_report = te.emeter.report(out_dir=te.res_dir)\n", "\n", "logging.info('#### Stop FTrace')\n", "te.ftrace.stop()\n", @@ -482,8 +482,8 @@ ], "source": [ "# Dump the energy measured for the LITTLE and big clusters\n", - "logging.info('Energy: %s', nrg_file)\n", - "print json.dumps(nrg, indent=4, sort_keys=True)" + "logging.info('Energy: %s', nrg_report.report_file)\n", + "print json.dumps(nrg_report.channels, indent=4, sort_keys=True)" ] }, { diff --git a/libs/utils/android/workloads/jankbench.py b/libs/utils/android/workloads/jankbench.py index cd9fd3c2bd9da38b40f3ac4ae78c6b4842c226cf..b7044ed708232cdeb9fa0e9f7fc387f6379db729 100644 --- a/libs/utils/android/workloads/jankbench.py +++ b/libs/utils/android/workloads/jankbench.py @@ -78,7 +78,7 @@ class Jankbench(Workload): raise ValueError('Jankbench test [%s] not supported', test_name) # Initialize energy meter results - nrg_data, nrg_file = None, None + nrg_report = None self.target.execute('input keyevent 82') # Press Back button to be sure we run the video from the start @@ -129,9 +129,9 @@ class Jankbench(Workload): match = JANKBENCH_BENCHMARK_DONE_RE.search(message) if match: if 'energy' in collect and self.te.emeter: - nrg_data, nrg_file = self.te.emeter.report(exp_dir) + nrg_report = self.te.emeter.report(exp_dir) self.logger.info("Estimated energy: %7.3f", - float(nrg_data['BAT'])) + float(nrg_report.channels['BAT'])) self.logger.debug("Benchmark done!") break @@ -164,6 +164,6 @@ class Jankbench(Workload): # Switch back to screen auto rotation Screen.set_orientation(self.target, auto=True) - return db_file, nrg_data, nrg_file + return db_file, nrg_report # vim :set tabstop=4 shiftwidth=4 expandtab diff --git a/libs/utils/android/workloads/youtube.py b/libs/utils/android/workloads/youtube.py index 018bc036716d1e4f7eff83be76ac6fad6045085e..d9186a12abde9611f8586e38b67cc3135ce2f6e3 100644 --- a/libs/utils/android/workloads/youtube.py +++ b/libs/utils/android/workloads/youtube.py @@ -46,7 +46,7 @@ class YouTube(Workload): def run(self, exp_dir, video_url, video_duration_s, collect=''): # Initialize energy meter results - nrg_data, nrg_file = None, None + nrg_report = None # Unlock device screen (assume no password required) self.target.execute('input keyevent 82') @@ -77,8 +77,9 @@ class YouTube(Workload): # Stop energy collection if 'energy' in collect and self.te.emeter: - nrg_data, nrg_file = self.te.emeter.report(exp_dir) - logging.info("Estimated energy: %7.3f", float(nrg_data['BAT'])) + nrg_report = self.te.emeter.report(exp_dir) + logging.info("Estimated energy: %7.3f", + float(nrg_report.channels['BAT'])) # Get frame stats db_file = os.path.join(exp_dir, "framestats.txt") @@ -94,6 +95,6 @@ class YouTube(Workload): # Switch back to screen auto rotation Screen.set_orientation(self.target, auto=True) - return db_file, nrg_data, nrg_file + return db_file, nrg_report # vim :set tabstop=4 shiftwidth=4 expandtab diff --git a/libs/utils/energy.py b/libs/utils/energy.py index 66c47d82c75329e3dafc5e9daeb392e6a57f8477..29fe73032450cee90f32bf7abcc14e8a5df2ead5 100644 --- a/libs/utils/energy.py +++ b/libs/utils/energy.py @@ -20,6 +20,7 @@ import json import logging import os import psutil +import time from collections import namedtuple from subprocess import Popen, PIPE, STDOUT @@ -34,6 +35,10 @@ DEFAULT_ENERGY_METER = { 'conf' : { 'sites' : [ 'A7 Jcore', 'A15 Jcore' ], 'kinds' : [ 'energy'] + }, + 'channel_map' : { + 'LITTLE' : 'A7 Jcore', + 'big' : 'A15 Jcore', } }, @@ -43,6 +48,10 @@ DEFAULT_ENERGY_METER = { 'conf' : { 'sites' : [ 'a53', 'a57' ], 'kinds' : [ 'energy' ], + }, + 'channel_map' : { + 'LITTLE' : 'a53', + 'big' : 'a57', } }, 'juno2' : { @@ -55,7 +64,7 @@ DEFAULT_ENERGY_METER = { # little/big cores on the board, use a channel_map section to # indicate which channel is which 'channel_map' : { - 'little' : 'BOARDLITTLE', + 'LITTLE' : 'BOARDLITTLE', 'big' : 'BOARDBIG', } }, @@ -64,14 +73,21 @@ DEFAULT_ENERGY_METER = { 'hikey' : { 'instrument' : 'aep', 'conf' : { - 'labels' : ['LITTLE'], 'resistor_values' : [0.033], 'device_entry' : '/dev/ttyACM0', + }, + # AEP requires channel_map for compatibility with the generic energy + # meters interface + "channel_map" : { + "LITTLE" : 'LITTLE', } } } +EnergyCounter = namedtuple('EnergyCounter', ['site', 'pwr_total' , 'pwr_samples', 'pwr_avg', 'time', 'nrg']) +EnergyReport = namedtuple('EnergyReport', ['channels', 'report_file']) + class EnergyMeter(object): _meter = None @@ -99,16 +115,16 @@ class EnergyMeter(object): conf['board'] in DEFAULT_ENERGY_METER: emeter = DEFAULT_ENERGY_METER[conf['board']] logging.debug('%14s - using default energy meter for [%s]', - 'EnergyMeter', conf['board']) + 'EnergyMeter', conf['board']) else: return None if emeter['instrument'] == 'hwmon': EnergyMeter._meter = HWMon(target, emeter, res_dir) elif emeter['instrument'] == 'aep': - EnergyMeter._meter = AEP(target, emeter['conf'], res_dir) + EnergyMeter._meter = AEP(target, emeter, res_dir) elif emeter['instrument'] == 'acme': - EnergyMeter._meter = ACME(target, emeter['conf'], res_dir) + EnergyMeter._meter = ACME(target, emeter, res_dir) logging.debug('%14s - Results dir: %s', 'EnergyMeter', res_dir) return EnergyMeter._meter @@ -124,7 +140,7 @@ class EnergyMeter(object): class HWMon(EnergyMeter): - def __init__(self, target, hwmon_conf=None, res_dir=None): + def __init__(self, target, conf=None, res_dir=None): super(HWMon, self).__init__(target, res_dir) # The HWMon energy meter @@ -134,41 +150,33 @@ class HWMon(EnergyMeter): self.readings = {} if 'hwmon' not in self._target.modules: - logging.info('%14s - HWMON module not enabled', - 'EnergyMeter') + logging.info('%14s - HWMON module not enabled', 'HWMon') logging.warning('%14s - Energy sampling disabled by configuration', - 'EnergyMeter') + 'HWMon') return # Initialize HWMON instrument - logging.info('%14s - Scanning for HWMON channels, may take some time...', 'EnergyMeter') + logging.info('%14s - Scanning for HWMON channels, may take some time...', 'HWMon') self._hwmon = devlib.HwmonInstrument(self._target) # Configure channels for energy measurements - logging.debug('%14s - Enabling channels %s', 'EnergyMeter', hwmon_conf['conf']) - self._hwmon.reset(**hwmon_conf['conf']) + logging.debug('%14s - Enabling channels %s', 'HWMon', conf['conf']) + self._hwmon.reset(**conf['conf']) # Logging enabled channels - logging.info('%14s - Channels selected for energy sampling:', - 'EnergyMeter') + logging.info('%14s - Channels selected for energy sampling:', 'HWMon') for channel in self._hwmon.active_channels: - logging.info('%14s - %s', 'EnergyMeter', channel.label) - - # record the hwmon channel mapping - self.little_channel = self._target.little_core.upper() - self.big_channel = self._target.big_core.upper() - if hwmon_conf and 'channel_map' in hwmon_conf: - self.little_channel = hwmon_conf['channel_map']['little'] - self.big_channel = hwmon_conf['channel_map']['big'] - logging.info('%14s - Using channel %s as little channel', - 'EnergyMeter', self.little_channel) - logging.info('%14s - Using channel %s as big channel', - 'EnergyMeter', self.big_channel) + logging.info('%14s - %s', 'HWMon', channel.label) + # record the HWMon channels + self._channels = conf.get('channel_map', { + 'LITTLE': self._target.little_core.upper(), + 'big': self._target.big_core.upper() + }) def sample(self): if self._hwmon is None: - return + return None samples = self._hwmon.take_measurement() for s in samples: label = s.channel.label\ @@ -200,46 +208,29 @@ class HWMon(EnergyMeter): self.readings[label]['total'] = 0 logging.debug('RESET: %s', self.readings) - def report(self, out_dir, out_file='energy.json'): if self._hwmon is None: - return + return (None, None) # Retrive energy consumption data nrg = self.sample() # Reformat data for output generation clusters_nrg = {} - for ch in nrg: - nrg_total = nrg[ch]['total'] - logging.info('%14s - Energy [%16s]: %.6f', - 'EnergyReport', ch, nrg_total) - if ch.upper() == self.little_channel: - clusters_nrg['LITTLE'] = '{:.6f}'.format(nrg_total) - elif ch.upper() == self.big_channel: - clusters_nrg['big'] = '{:.6f}'.format(nrg_total) - else: - logging.warning('%14s - Unable to bind hwmon channel [%s]'\ - ' to a big.LITTLE cluster', - 'EnergyReport', ch) - clusters_nrg[ch] = '{:.6f}'.format(nrg_total) - if 'LITTLE' not in clusters_nrg: - logging.warning('%14s - No energy data for LITTLE cluster', - 'EnergyMeter') - if 'big' not in clusters_nrg: - logging.warning('%14s - No energy data for big cluster', - 'EnergyMeter') + for channel in self._channels: + label = self._channels[channel] + nrg_total = nrg[label]['total'] + logging.debug('%14s - Energy [%16s]: %.6f', 'HWMon', label, nrg_total) + clusters_nrg[channel] = nrg_total # Dump data as JSON file nrg_file = '{}/{}'.format(out_dir, out_file) with open(nrg_file, 'w') as ofile: json.dump(clusters_nrg, ofile, sort_keys=True, indent=4) - return (clusters_nrg, nrg_file) - -EnergyCounter = namedtuple('EnergyCounter', ['site', 'pwr_total' , 'pwr_samples', 'pwr_avg', 'time', 'nrg']) + return EnergyReport(clusters_nrg, nrg_file) class AEP(EnergyMeter): - def __init__(self, target, aep_conf, res_dir): + def __init__(self, target, conf, res_dir): super(AEP, self).__init__(target, res_dir) # Energy channels @@ -249,18 +240,19 @@ class AEP(EnergyMeter): self.time = {} # Configure channels for energy measurements - logging.info('%14s - AEP configuration', 'EnergyMeter') - logging.info('%14s - %s', 'EnergyMeter', aep_conf) - self._aep = devlib.EnergyProbeInstrument(self._target, **aep_conf) + logging.info('%14s - AEP configuration', 'AEP') + logging.info('%14s - %s', 'AEP', conf) + self._aep = devlib.EnergyProbeInstrument( + self._target, labels=conf['channel_map'], **conf['conf']) # Configure channels for energy measurements - logging.debug('EnergyMeter - Enabling channels') + logging.debug('%14s - Enabling channels', 'AEP') self._aep.reset() # Logging enabled channels logging.info('%14s - Channels selected for energy sampling:\n%s', - 'EnergyMeter', str(self._aep.active_channels)) - logging.debug('%14s - Results dir: %s', 'EnergyMeter', self._res_dir) + 'AEP', str(self._aep.active_channels)) + logging.debug('%14s - Results dir: %s', 'AEP', self._res_dir) def _get_energy(self, samples, time, idx, site): pwr_total = 0 @@ -290,15 +282,8 @@ class AEP(EnergyMeter): if channel.kind is not 'power': continue ec = self._get_energy(samples, self.time['diff'], idx, channel.site) - logging.debug('%14s - CH[%s] Power: %.6f (samples: %d, time: %.6f), avg: %.f6', - 'EnergyMeter', channel.site, ec.pwr_total, - ec.pwr_samples, ec.time, ec.pwr_avg) - logging.debug('%14s - CH[%s] Estimated energy: %.6f', - 'EnergyMeter', channel.site, ec.nrg) self.channels.append(ec) - logging.debug('%14s - SAMPLE: %s', 'EnergyMeter', self.channels) - def reset(self): if self._aep is None: return @@ -320,14 +305,16 @@ class AEP(EnergyMeter): # Reformat data for output generation channels_nrg = {} for channel in self.channels: - channels_nrg[channel.site] = '{:.6f}'.format(channel.nrg) + logging.debug('%14s - Energy [%16s]: %.6f', 'AEP', + channel.site, channel.nrg) + channels_nrg[channel.site] = channel.nrg # Dump data as JSON file nrg_file = '{}/{}'.format(out_dir, out_energy) with open(nrg_file, 'w') as ofile: json.dump(channels_nrg, ofile, sort_keys=True, indent=4) - return (channels_nrg, nrg_file) + return EnergyReport(channels_nrg, nrg_file) class ACME(EnergyMeter): """ @@ -338,9 +325,9 @@ class ACME(EnergyMeter): super(ACME, self).__init__(target) # Assume iio-capture is available in PATH - self._iiocapturebin = conf.get('iio-capture', 'iio-capture') - self._hostname = conf.get('ip_address', 'baylibre-acme.local') - self._channels = conf.get('channels', { + self._iiocapturebin = conf['conf'].get('iio-capture', 'iio-capture') + self._hostname = conf['conf'].get('ip_address', 'baylibre-acme.local') + self._channels = conf.get('channel_map', { 'CH0': '0' }) self._iio = [None] * len(self._channels) @@ -487,11 +474,11 @@ class ACME(EnergyMeter): nrg = {} for kv_pair in out.split(): key, val = kv_pair.partition('=')[::2] - nrg[key] = val + nrg[key] = float(val) channels_stats[channel] = nrg - logging.info('%14s - %s', 'ACME', self._str(channel)) - logging.info('%14s - %s', 'ACME', nrg) + logging.debug('%14s - %s', 'ACME', self._str(channel)) + logging.debug('%14s - %s', 'ACME', nrg) # Save CSV samples file to out_dir os.system('mv {}/samples_{}.csv {}' @@ -512,6 +499,6 @@ class ACME(EnergyMeter): with open(nrg_stats_file, 'w') as ofile: json.dump(channels_stats, ofile, sort_keys=True, indent=4) - return (channels_nrg, nrg_file) + return EnergyReport(channels_nrg, nrg_file) # vim :set tabstop=4 shiftwidth=4 expandtab