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