Energy Meter Examples
BayLibre's ACME Cape and IIOCapture


Import Required Modules


In [1]:
import logging
reload(logging)
logging.basicConfig(
    format='%(asctime)-9s %(levelname)-8s: %(message)s',
    datefmt='%I:%M:%S')

# Enable logging at INFO level
logging.getLogger().setLevel(logging.INFO)

In [2]:
# Generate plots inline
%matplotlib inline

import os

# Support to access the remote target
import devlib
from env import TestEnv

# RTApp configurator for generation of PERIODIC tasks
from wlgen import RTA, Ramp

Target Configuration


In [3]:
# Setup target configuration
my_conf = {

    # Target platform and board
    "platform"    : 'linux',
    "board"       : 'juno',
    "host"        : '192.168.0.1',

    # Folder where all the results will be collected
    "results_dir" : "EnergyMeter_IIOCapture",

    # Define devlib modules to load
    "exclude_modules" : [ 'hwmon' ],

    # Energy Meters Configuration for BayLibre's ACME Cape
    "emeter" : {
        "instrument" : "acme",
        "conf" : {
            #'iio-capture' : '/usr/bin/iio-capture',
            #'ip_address' : 'baylibre-acme.local',
            'channels' : {
                'Device0' : 0,
                'Device1' : 1,
            }
        }
    },
    
    # Tools required by the experiments
    "tools"   : [ 'trace-cmd', 'rt-app' ],
    
    # Comment this line to calibrate RTApp in your own platform
    "rtapp-calib" :  {"0": 360, "1": 142, "2": 138, "3": 352, "4": 352, "5": 353},
}

In [4]:
# Initialize a test environment using:
te = TestEnv(my_conf, wipe=False, force_new=True)
target = te.target


06:32:20  INFO    :         Target - Using base path: /home/derkling/Code/lisa
06:32:20  INFO    :         Target - Loading custom (inline) target configuration
06:32:20  INFO    :         Target - Devlib modules to load: ['bl', 'cpufreq']
06:32:20  INFO    :         Target - Connecting linux target:
06:32:20  INFO    :         Target -   username : root
06:32:20  INFO    :         Target -       host : 192.168.0.1
06:32:20  INFO    :         Target -   password : 
06:32:20  INFO    :         Target - Connection settings:
06:32:20  INFO    :         Target -    {'username': 'root', 'host': '192.168.0.1', 'password': ''}
06:32:24  INFO    :         Target - Initializing target workdir:
06:32:24  INFO    :         Target -    /root/devlib-target
06:32:31  INFO    :         Target - Topology:
06:32:31  INFO    :         Target -    [[0, 3, 4, 5], [1, 2]]
06:32:33  INFO    :       Platform - Loading default EM:
06:32:33  INFO    :       Platform -    /home/derkling/Code/lisa/libs/utils/platforms/juno.json
06:32:33  WARNING :         Target - Using configuration provided RTApp calibration
06:32:33  INFO    :         Target - Using RT-App calibration values:
06:32:33  INFO    :         Target -    {"0": 360, "1": 142, "2": 138, "3": 352, "4": 352, "5": 353}
06:32:33  INFO    :           ACME - ACME configuration:
06:32:33  INFO    :           ACME -     binary: iio-capture
06:32:33  INFO    :           ACME -     device: baylibre-acme.local
06:32:33  INFO    :           ACME -   channels:
06:32:33  INFO    :           ACME -      Device1 (iio:device1)
06:32:33  INFO    :           ACME -      Device0 (iio:device0)
06:32:33  INFO    :        TestEnv - Set results folder to:
06:32:33  INFO    :        TestEnv -    /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture
06:32:33  INFO    :        TestEnv - Experiment results available also in:
06:32:33  INFO    :        TestEnv -    /home/derkling/Code/lisa/results_latest

Workload Execution and Power Consumptions Samping


In [5]:
# Create and RTApp RAMP task
rtapp = RTA(te.target, 'ramp', calibration=te.calibration())
rtapp.conf(kind='profile',
           params={
                'ramp' : Ramp(
                    start_pct =  60,
                    end_pct   =  20,
                    delta_pct =   5,
                    time_s    =   0.5).get()
          })

# EnergyMeter Start
te.emeter.reset()

rtapp.run(out_dir=te.res_dir)

# EnergyMeter Stop and samples collection
channels_nrg, nrg_file = te.emeter.report(te.res_dir)


06:32:33  INFO    :          WlGen - Setup new workload ramp
06:32:33  INFO    :          RTApp - Workload duration defined by longest task
06:32:33  INFO    :          RTApp - Default policy: SCHED_OTHER
06:32:33  INFO    :          RTApp - ------------------------
06:32:33  INFO    :          RTApp - task [ramp], sched: using default policy
06:32:33  INFO    :          RTApp -  | calibration CPU: 1
06:32:33  INFO    :          RTApp -  | loops count: 1
06:32:33  INFO    :          RTApp - + phase_000001: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  60 %
06:32:33  INFO    :          RTApp - |  run_time  60000 [us], sleep_time  40000 [us]
06:32:33  INFO    :          RTApp - + phase_000002: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  55 %
06:32:33  INFO    :          RTApp - |  run_time  55000 [us], sleep_time  45000 [us]
06:32:33  INFO    :          RTApp - + phase_000003: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  50 %
06:32:33  INFO    :          RTApp - |  run_time  50000 [us], sleep_time  50000 [us]
06:32:33  INFO    :          RTApp - + phase_000004: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  45 %
06:32:33  INFO    :          RTApp - |  run_time  45000 [us], sleep_time  55000 [us]
06:32:33  INFO    :          RTApp - + phase_000005: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  40 %
06:32:33  INFO    :          RTApp - |  run_time  40000 [us], sleep_time  60000 [us]
06:32:33  INFO    :          RTApp - + phase_000006: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  35 %
06:32:33  INFO    :          RTApp - |  run_time  35000 [us], sleep_time  65000 [us]
06:32:33  INFO    :          RTApp - + phase_000007: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  30 %
06:32:33  INFO    :          RTApp - |  run_time  30000 [us], sleep_time  70000 [us]
06:32:33  INFO    :          RTApp - + phase_000008: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  25 %
06:32:33  INFO    :          RTApp - |  run_time  25000 [us], sleep_time  75000 [us]
06:32:33  INFO    :          RTApp - + phase_000009: duration 0.500000 [s] (5 loops)
06:32:33  INFO    :          RTApp - |  period   100000 [us], duty_cycle  20 %
06:32:33  INFO    :          RTApp - |  run_time  20000 [us], sleep_time  80000 [us]
06:32:34  INFO    :          WlGen - Workload execution START:
06:32:34  INFO    :          WlGen -    /root/devlib-target/bin/rt-app /root/devlib-target/ramp_00.json 2>&1
06:32:41  INFO    :           ACME - Device1 (iio:device1)
06:32:41  INFO    :           ACME - {'cmin': '-1.00', 'energy': '324.56', 'pavg': '57.81', 'pmin': '00.00', 'vmax': '4390.00', 'cmax': '22.00', 'pmax': '125.00'}
06:32:42  INFO    :           ACME - Device0 (iio:device0)
06:32:42  INFO    :           ACME - {'cmin': '00.00', 'energy': '220.83', 'pavg': '32.78', 'pmin': '00.00', 'vmax': '4390.00', 'cmax': '15.00', 'pmax': '100.00'}

In [6]:
logging.info("Collected data:")
!tree $te.res_dir


06:32:42  INFO    : Collected data:
/home/derkling/Code/lisa/results/EnergyMeter_IIOCapture
├── energy.json
├── energy_stats.json
├── output.log
├── ramp_00.json
├── rt-app-ramp-0.log
├── samples_Device0.csv
└── samples_Device1.csv

0 directories, 7 files

Power Measurements Data


In [7]:
logging.info("Measured channels energy:")
logging.info("%s", channels_nrg)


06:32:42  INFO    : Measured channels energy:
06:32:42  INFO    : {'Device1': '324.56', 'Device0': '220.83'}

In [8]:
logging.info("Returned energy file:")
logging.info("  %s", nrg_file)
!cat $nrg_file


06:32:42  INFO    : Returned energy file:
06:32:42  INFO    :   /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture/energy.json
{
    "Device0": "220.83", 
    "Device1": "324.56"
}

In [9]:
stats_file = nrg_file.replace('.json', '_stats.json')
logging.info("Complete energy stats:")
logging.info("  %s", stats_file)
!cat $stats_file


06:32:42  INFO    : Complete energy stats:
06:32:42  INFO    :   /home/derkling/Code/lisa/results/EnergyMeter_IIOCapture/energy_stats.json
{
    "Device0": {
        "cmax": "15.00", 
        "cmin": "00.00", 
        "energy": "220.83", 
        "pavg": "32.78", 
        "pmax": "100.00", 
        "pmin": "00.00", 
        "vmax": "4390.00"
    }, 
    "Device1": {
        "cmax": "22.00", 
        "cmin": "-1.00", 
        "energy": "324.56", 
        "pavg": "57.81", 
        "pmax": "125.00", 
        "pmin": "00.00", 
        "vmax": "4390.00"
    }
}

In [10]:
logging.info("Device0 stats (head)")
samples_file = os.path.join(te.res_dir, 'samples_Device0.csv')
!head $samples_file


06:32:43  INFO    : Device0 stats (head)
"vshunt mV", "vbus mV", "power mW", "current mA", "timestamp ms"
35.0, 4387.5, 25.0, 4.0, 0.0
-42.5, 4386.2, 25.0, -4.0, 10.5
50.0, 4385.0, 25.0, 3.0, 20.7
32.5, 4386.2, 0.0, 9.0, 30.8
92.5, 4387.5, 25.0, 0.0, 41.1
2.5, 4387.5, 25.0, 6.0, 51.2
17.5, 4390.0, 50.0, 2.0, 61.1
35.0, 4386.2, 25.0, 4.0, 71.2
72.5, 4388.8, 50.0, 7.0, 81.1

In [11]:
logging.info("Device1 stats (head)")
samples_file = os.path.join(te.res_dir, 'samples_Device1.csv')
!head $samples_file


06:32:43  INFO    : Device1 stats (head)
"vshunt mV", "vbus mV", "power mW", "current mA", "timestamp ms"
115.0, 4388.8, 50.0, 12.0, 0.0
75.0, 4386.2, 50.0, 18.0, 9.5
177.5, 4387.5, 50.0, 11.0, 19.8
112.5, 4388.8, 75.0, 16.0, 29.7
85.0, 4388.8, 50.0, 9.0, 39.8
182.5, 4388.8, 75.0, 18.0, 49.7
65.0, 4390.0, 50.0, 7.0, 59.8
95.0, 4388.8, 50.0, 14.0, 69.8
135.0, 4390.0, 50.0, 5.0, 79.7