blob: 0179c4e14bd40d6060455bad4af321ee26ebbcc7 [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tutorial Goal"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial aims to show how to **configure and run** a **synthetic workload** using the **wlgen module** provided by LISA."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Configure logging"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import logging\n",
"from conf import LisaLogging\n",
"LisaLogging.setup()"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Execute this cell to enabled devlib debugging statements\n",
"logging.getLogger('ssh').setLevel(logging.DEBUG)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Other python modules required by this notebook\n",
"import json\n",
"import os"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test environment setup"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Setup a target configuration\n",
"conf = {\n",
" \n",
" # Target is localhost\n",
" \"platform\" : 'linux',\n",
" \"board\" : \"juno\",\n",
" \n",
" # Login credentials\n",
" \"host\" : \"192.168.0.1\",\n",
" \"username\" : \"root\",\n",
" \"password\" : \"\",\n",
"\n",
" # Binary tools required to run this experiment\n",
" # These tools must be present in the tools/ folder for the architecture\n",
" \"tools\" : ['rt-app', 'taskset', 'trace-cmd'],\n",
" \n",
" # Comment the following line to force rt-app calibration on your target\n",
"# \"rtapp-calib\" : {\n",
"# \"0\": 355, \"1\": 138, \"2\": 138, \"3\": 355, \"4\": 354, \"5\": 354\n",
"# },\n",
" \n",
" # FTrace events end buffer configuration\n",
" \"ftrace\" : {\n",
" \"events\" : [\n",
" \"sched_switch\",\n",
" \"cpu_frequency\"\n",
" ],\n",
" \"buffsize\" : 10240\n",
" },\n",
"\n",
" # Where results are collected\n",
" \"results_dir\" : \"WlgenExample\",\n",
" \n",
" # Devlib modules we'll need\n",
" \"modules\": [\"cpufreq\"]\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:22:12 INFO : Target - Using base path: /home/derkling/Code/lisa\n",
"12:22:12 INFO : Target - Loading custom (inline) target configuration\n",
"12:22:12 INFO : Target - Devlib modules to load: ['bl', 'hwmon', 'cpufreq']\n",
"12:22:12 INFO : Target - Connecting linux target:\n",
"12:22:12 INFO : Target - username : root\n",
"12:22:12 INFO : Target - host : 192.168.0.1\n",
"12:22:12 INFO : Target - password : \n",
"12:22:50 INFO : Target - Initializing target workdir:\n",
"12:22:50 INFO : Target - /root/devlib-target\n",
"12:22:59 INFO : Target - Topology:\n",
"12:22:59 INFO : Target - [[0, 3, 4, 5], [1, 2]]\n",
"12:23:01 INFO : Platform - Loading default EM:\n",
"12:23:01 INFO : Platform - /home/derkling/Code/lisa/libs/utils/platforms/juno.json\n",
"12:23:02 INFO : FTrace - Enabled tracepoints:\n",
"12:23:02 INFO : FTrace - sched_switch\n",
"12:23:02 INFO : FTrace - cpu_frequency\n",
"12:23:02 INFO : EnergyMeter - Scanning for HWMON channels, may take some time...\n",
"12:23:02 INFO : EnergyMeter - Channels selected for energy sampling:\n",
"12:23:02 INFO : EnergyMeter - a57_energy\n",
"12:23:02 INFO : EnergyMeter - a53_energy\n",
"12:23:02 WARNING : Target - Using configuration provided RTApp calibration\n",
"12:23:02 INFO : Target - Using RT-App calibration values:\n",
"12:23:02 INFO : Target - {\"0\": 355, \"1\": 138, \"2\": 138, \"3\": 355, \"4\": 354, \"5\": 354}\n",
"12:23:02 WARNING : TestEnv - Wipe previous contents of the results folder:\n",
"12:23:02 WARNING : TestEnv - /home/derkling/Code/lisa/results/WlgenExample\n",
"12:23:02 INFO : TestEnv - Set results folder to:\n",
"12:23:02 INFO : TestEnv - /home/derkling/Code/lisa/results/WlgenExample\n",
"12:23:02 INFO : TestEnv - Experiment results available also in:\n",
"12:23:02 INFO : TestEnv - /home/derkling/Code/lisa/results_latest\n"
]
}
],
"source": [
"# Support to access the remote target\n",
"from env import TestEnv\n",
"\n",
"# Initialize a test environment using:\n",
"# the provided target configuration (my_target_conf)\n",
"# the provided test configuration (my_test_conf)\n",
"te = TestEnv(conf)\n",
"target = te.target"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Workload execution utility"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def execute(te, wload, res_dir):\n",
" \n",
" logging.info('# Create results folder for this execution')\n",
" !mkdir {res_dir}\n",
" \n",
" logging.info('# Setup FTrace')\n",
" te.ftrace.start()\n",
"\n",
" logging.info('## Start energy sampling')\n",
" te.emeter.reset()\n",
"\n",
" logging.info('### Start RTApp execution')\n",
" wload.run(out_dir=res_dir)\n",
"\n",
" logging.info('## Read energy consumption: %s/energy.json', res_dir)\n",
" nrg_report = te.emeter.report(out_dir=res_dir)\n",
"\n",
" logging.info('# Stop FTrace')\n",
" te.ftrace.stop()\n",
"\n",
" trace_file = os.path.join(res_dir, 'trace.dat')\n",
" logging.info('# Save FTrace: %s', trace_file)\n",
" te.ftrace.get_trace(trace_file)\n",
"\n",
" logging.info('# Save platform description: %s/platform.json', res_dir)\n",
" plt, plt_file = te.platform_dump(res_dir)\n",
" \n",
" logging.info('# Report collected data:')\n",
" logging.info(' %s', res_dir)\n",
" !ls -la {res_dir}\n",
" \n",
" return nrg_report, plt, plt_file, trace_file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Single task RTApp workload"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1) creation"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:38:37 INFO : WlGen - Setup new workload example1\n"
]
}
],
"source": [
"# Support to configure and run RTApp based workloads\n",
"from wlgen import RTA\n",
"\n",
"# Create a new RTApp workload generator using the calibration values\n",
"# reported by the TestEnv module\n",
"rtapp_name = 'example1'\n",
"rtapp = RTA(target, rtapp_name, calibration=te.calibration())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2) configuration"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:38:39 INFO : RTApp - Workload duration defined by longest task\n",
"12:38:39 INFO : RTApp - Default policy: SCHED_OTHER\n",
"12:38:39 INFO : RTApp - ------------------------\n",
"12:38:39 INFO : RTApp - task [task_p20], sched: {'policy': 'OTHER', 'priotity': 130}\n",
"12:38:39 INFO : RTApp - | calibration CPU: 1\n",
"12:38:39 INFO : RTApp - | loops count: 1\n",
"12:38:39 INFO : RTApp - | CPUs affinity: 0\n",
"12:38:39 INFO : RTApp - + phase_000001: duration 5.000000 [s] (50 loops)\n",
"12:38:39 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n",
"12:38:39 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n"
]
}
],
"source": [
"# RTApp configurator for generation of PERIODIC tasks\n",
"from wlgen import Periodic \n",
"\n",
"# Configure this RTApp instance to:\n",
"rtapp.conf(\n",
"\n",
" # 1. generate a \"profile based\" set of tasks\n",
" kind = 'profile',\n",
" \n",
" # 2. define the \"profile\" of each task\n",
" params = {\n",
" \n",
" # 3. PERIODIC task with\n",
" 'task_p20': Periodic (\n",
" period_ms = 100, # period [ms]\n",
" duty_cycle_pct = 20, # duty cycle [%]\n",
" duration_s = 5, # duration [s]\n",
" delay_s = 0, # start after that delay [s]\n",
" sched = { # run as a low-priority SCHED_OTHER task\n",
" 'policy' : 'OTHER',\n",
" 'priotity' : 130,\n",
" },\n",
" cpus = # pinned on first online CPU\n",
" str(target.list_online_cpus()[0])\n",
" # ADD OTHER PARAMETERS\n",
" ).get(),\n",
"\n",
" },\n",
" \n",
");"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:38:42 INFO : Generated RTApp JSON file:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"global\": {\n",
" \"calibration\": 138, \n",
" \"default_policy\": \"SCHED_OTHER\", \n",
" \"duration\": -1, \n",
" \"logdir\": \"/root/devlib-target\"\n",
" }, \n",
" \"tasks\": {\n",
" \"task_p20\": {\n",
" \"cpus\": [\n",
" 0\n",
" ], \n",
" \"loop\": 1, \n",
" \"phases\": {\n",
" \"p000001\": {\n",
" \"loop\": 50, \n",
" \"run\": 20000, \n",
" \"timer\": {\n",
" \"period\": 100000, \n",
" \"ref\": \"task_p20\"\n",
" }\n",
" }\n",
" }, \n",
" \"policy\": \"SCHED_OTHER\", \n",
" \"priotity\": 130\n",
" }\n",
" }\n",
"}\n"
]
}
],
"source": [
"# Inspect the JSON file used to run the application\n",
"with open('./{}_00.json'.format(rtapp_name), 'r') as fh:\n",
" rtapp_json = json.load(fh)\n",
"logging.info('Generated RTApp JSON file:')\n",
"print json.dumps(rtapp_json, indent=4, sort_keys=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3) execution"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:38:45 INFO : # Create results folder for this execution\n",
"12:38:45 INFO : # Setup FTrace\n",
"12:38:49 INFO : ## Start energy sampling\n",
"12:38:51 INFO : ### Start RTApp execution\n",
"12:38:51 INFO : WlGen - Workload execution START:\n",
"12:38:51 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/example1_00.json\n",
"12:38:57 INFO : ## Read energy consumption: /home/derkling/Code/lisa/results/WlgenExample/example1/energy.json\n",
"12:38:57 INFO : EnergyReport - Energy [ a53]: 5.125284\n",
"12:38:57 INFO : EnergyReport - Energy [ a57]: 3.037161\n",
"12:38:57 INFO : # Stop FTrace\n",
"12:38:59 INFO : # Save FTrace: /home/derkling/Code/lisa/results/WlgenExample/example1/trace.dat\n",
"12:39:01 INFO : # Save platform description: /home/derkling/Code/lisa/results/WlgenExample/example1/platform.json\n",
"12:39:01 INFO : # Report collected data:\n",
"12:39:01 INFO : /home/derkling/Code/lisa/results/WlgenExample/example1\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"total 4008\r\n",
"drwxrwxr-x 2 derkling derkling 4096 Mar 2 12:39 .\r\n",
"drwxrwxr-x 3 derkling derkling 4096 Mar 2 12:38 ..\r\n",
"-rw-rw-r-- 1 derkling derkling 52 Mar 2 12:38 energy.json\r\n",
"-rw-r--r-- 1 derkling derkling 644 Mar 2 12:38 example1_00.json\r\n",
"-rw-rw-r-- 1 derkling derkling 235 Mar 2 12:38 output.log\r\n",
"-rw-rw-r-- 1 derkling derkling 1075 Mar 2 12:39 platform.json\r\n",
"-rw-r--r-- 1 derkling derkling 6360 Mar 2 12:38 rt-app-task_p20-0.log\r\n",
"-rw-r--r-- 1 derkling derkling 6360 Mar 2 12:38 rt-app-task_p20-3.log\r\n",
"-rw-r--r-- 1 derkling derkling 4063232 Mar 2 12:39 trace.dat\r\n"
]
}
],
"source": [
"res_dir = os.path.join(te.res_dir, rtapp_name)\n",
"nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4) Check collected data"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:39:07 INFO : Energy: /home/derkling/Code/lisa/results/WlgenExample/example1/energy.json\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"LITTLE\": \"5.125284\", \n",
" \"big\": \"3.037161\"\n",
"}\n"
]
}
],
"source": [
"# Dump the energy measured for the LITTLE and big clusters\n",
"logging.info('Energy: %s', nrg_report.report_file)\n",
"print json.dumps(nrg_report.channels, indent=4, sort_keys=True)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:39:07 INFO : Platform description: /home/derkling/Code/lisa/results/WlgenExample/example1/platform.json\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"clusters\": {\n",
" \"big\": [\n",
" 1, \n",
" 2\n",
" ], \n",
" \"little\": [\n",
" 0, \n",
" 3, \n",
" 4, \n",
" 5\n",
" ]\n",
" }, \n",
" \"cpus_count\": 6, \n",
" \"freqs\": {\n",
" \"big\": [\n",
" 450000, \n",
" 625000, \n",
" 800000, \n",
" 950000, \n",
" 1100000\n",
" ], \n",
" \"little\": [\n",
" 450000, \n",
" 575000, \n",
" 700000, \n",
" 775000, \n",
" 850000\n",
" ]\n",
" }, \n",
" \"nrg_model\": {\n",
" \"big\": {\n",
" \"cluster\": {\n",
" \"nrg_max\": 64\n",
" }, \n",
" \"cpu\": {\n",
" \"cap_max\": 1024, \n",
" \"nrg_max\": 616\n",
" }\n",
" }, \n",
" \"little\": {\n",
" \"cluster\": {\n",
" \"nrg_max\": 57\n",
" }, \n",
" \"cpu\": {\n",
" \"cap_max\": 447, \n",
" \"nrg_max\": 93\n",
" }\n",
" }\n",
" }, \n",
" \"topology\": [\n",
" [\n",
" 0, \n",
" 3, \n",
" 4, \n",
" 5\n",
" ], \n",
" [\n",
" 1, \n",
" 2\n",
" ]\n",
" ]\n",
"}\n"
]
}
],
"source": [
"# Dump the platform descriptor, which could be useful for further analysis\n",
"# of the generated results\n",
"logging.info('Platform description: %s', plt_file)\n",
"print json.dumps(plt, indent=4, sort_keys=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5) trace inspection"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"version = 6\n",
"trace-cmd: No such file or directory\n",
" [vmscan:mm_vmscan_writepage] function sizeof not defined\n",
" unknown op '~'\n",
" Error: expected type 5 but read 0\n",
" Error: expected type 4 but read 0\n",
" unknown op '~'\n",
" Error: expected type 5 but read 0\n",
" Error: expected type 4 but read 0\n",
" unknown op '~'\n",
" Error: expected type 5 but read 0\n",
" Error: expected type 4 but read 0\n",
" unknown op '~'\n",
" Error: expected type 5 but read 0\n",
" Error: expected type 4 but read 0\n",
" [sunrpc:xs_tcp_data_recv] function __builtin_constant_p not defined\n",
" [sunrpc:xprt_transmit] function __builtin_constant_p not defined\n",
" [sunrpc:xprt_lookup_rqst] function __builtin_constant_p not defined\n",
" [sunrpc:xprt_complete_rqst] function __builtin_constant_p not defined\n",
" [sunrpc:svc_send] function __builtin_constant_p not defined\n",
" [sunrpc:svc_recv] function __builtin_constant_p not defined\n",
" [sunrpc:svc_process] function __builtin_constant_p not defined\n",
" [ras:mc_event] function mc_event_error_type not defined\n",
" [libata:ata_qc_complete_internal] function libata_trace_parse_qc_flags not defined\n",
" [libata:ata_qc_complete_failed] function libata_trace_parse_qc_flags not defined\n",
" [libata:ata_qc_complete_done] function libata_trace_parse_qc_flags not defined\n",
" [libata:ata_eh_link_autopsy_qc] function libata_trace_parse_qc_flags not defined\n",
" [libata:ata_eh_link_autopsy] function libata_trace_parse_eh_action not defined\n",
" [kvm:kvm_arm_set_regset] function __print_array not defined\n",
" [kmem:mm_page_pcpu_drain] function sizeof not defined\n",
" [kmem:mm_page_free_batched] function sizeof not defined\n",
" [kmem:mm_page_free] function sizeof not defined\n",
" [kmem:mm_page_alloc_zone_locked] function sizeof not defined\n",
" Error: expected type 4 but read 0\n",
" [kmem:mm_page_alloc_extfrag] function sizeof not defined\n",
" [kmem:mm_page_alloc] function sizeof not defined\n",
" Error: expected type 4 but read 0\n",
" [filemap:mm_filemap_delete_from_page_cache] function sizeof not defined\n",
" [filemap:mm_filemap_add_to_page_cache] function sizeof not defined\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n",
"\n",
"(kernelshark:11002): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n",
"\n",
"(kernelshark:11002): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n"
]
}
],
"source": [
"!kernelshark {trace_file} 2>/dev/null"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Workload composition using RTApp"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1) creation"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:43:40 INFO : WlGen - Setup new workload example2\n"
]
}
],
"source": [
"# Support to configure and run RTApp based workloads\n",
"from wlgen import RTA\n",
"\n",
"# Create a new RTApp workload generator using the calibration values\n",
"# reported by the TestEnv module\n",
"rtapp_name = 'example2'\n",
"rtapp = RTA(target, rtapp_name, calibration=te.calibration())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2) configuration"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:44:39 INFO : RTApp - Workload duration defined by longest task\n",
"12:44:39 INFO : RTApp - Default policy: SCHED_OTHER\n",
"12:44:39 INFO : RTApp - ------------------------\n",
"12:44:39 INFO : RTApp - task [task_ramp], sched: using default policy\n",
"12:44:39 INFO : RTApp - | calibration CPU: 1\n",
"12:44:39 INFO : RTApp - | loops count: 1\n",
"12:44:39 INFO : RTApp - | CPUs affinity: 1\n",
"12:44:39 INFO : RTApp - + phase_000001: duration 1.000000 [s] (100 loops)\n",
"12:44:39 INFO : RTApp - | period 10000 [us], duty_cycle 10 %\n",
"12:44:39 INFO : RTApp - | run_time 1000 [us], sleep_time 9000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000002: duration 1.000000 [s] (20 loops)\n",
"12:44:39 INFO : RTApp - | period 50000 [us], duty_cycle 10 %\n",
"12:44:39 INFO : RTApp - | run_time 5000 [us], sleep_time 45000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000003: duration 1.000000 [s] (20 loops)\n",
"12:44:39 INFO : RTApp - | period 50000 [us], duty_cycle 30 %\n",
"12:44:39 INFO : RTApp - | run_time 15000 [us], sleep_time 35000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000004: duration 1.000000 [s] (20 loops)\n",
"12:44:39 INFO : RTApp - | period 50000 [us], duty_cycle 50 %\n",
"12:44:39 INFO : RTApp - | run_time 25000 [us], sleep_time 25000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000005: duration 1.000000 [s] (20 loops)\n",
"12:44:39 INFO : RTApp - | period 50000 [us], duty_cycle 70 %\n",
"12:44:39 INFO : RTApp - | run_time 35000 [us], sleep_time 15000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000006: duration 1.000000 [s] (20 loops)\n",
"12:44:39 INFO : RTApp - | period 50000 [us], duty_cycle 90 %\n",
"12:44:39 INFO : RTApp - | run_time 45000 [us], sleep_time 5000 [us]\n",
"12:44:39 INFO : RTApp - + phase_000007: duration 0.100000 [s] (1 loops)\n",
"12:44:39 INFO : RTApp - | period 100000 [us], duty_cycle 90 %\n",
"12:44:39 INFO : RTApp - | run_time 90000 [us], sleep_time 10000 [us]\n"
]
}
],
"source": [
"# RTApp configurator for generation of PERIODIC tasks\n",
"from wlgen import Periodic, Ramp\n",
"\n",
"# Light workload\n",
"light = Periodic(duty_cycle_pct=10, duration_s=1.0, period_ms= 10,\n",
" cpus=str(target.bl.bigs_online[0]))\n",
"# Ramp workload\n",
"ramp = Ramp(start_pct=10, end_pct=90, delta_pct=20, time_s=1, period_ms=50)\n",
"# Heavy workload\n",
"heavy = Periodic(duty_cycle_pct=90, duration_s=0.1, period_ms=100)\n",
"\n",
"# Composed workload\n",
"lrh_task = light + ramp + heavy\n",
"\n",
"# Configure this RTApp instance to:\n",
"rtapp.conf(\n",
"\n",
" # 1. generate a \"profile based\" set of tasks\n",
" kind = 'profile',\n",
" \n",
" # 2. define the \"profile\" of each task\n",
" params = {\n",
" \n",
" # 3. PERIODIC task with\n",
" 'task_ramp': lrh_task.get() \n",
"\n",
" },\n",
" \n",
");"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:45:34 INFO : Generated RTApp JSON file:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"global\": {\n",
" \"calibration\": 138, \n",
" \"default_policy\": \"SCHED_OTHER\", \n",
" \"duration\": -1, \n",
" \"logdir\": \"/root/devlib-target\"\n",
" }, \n",
" \"tasks\": {\n",
" \"task_ramp\": {\n",
" \"cpus\": [\n",
" 1\n",
" ], \n",
" \"loop\": 1, \n",
" \"phases\": {\n",
" \"p000001\": {\n",
" \"loop\": 100, \n",
" \"run\": 1000, \n",
" \"timer\": {\n",
" \"period\": 10000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000002\": {\n",
" \"loop\": 20, \n",
" \"run\": 5000, \n",
" \"timer\": {\n",
" \"period\": 50000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000003\": {\n",
" \"loop\": 20, \n",
" \"run\": 15000, \n",
" \"timer\": {\n",
" \"period\": 50000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000004\": {\n",
" \"loop\": 20, \n",
" \"run\": 25000, \n",
" \"timer\": {\n",
" \"period\": 50000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000005\": {\n",
" \"loop\": 20, \n",
" \"run\": 35000, \n",
" \"timer\": {\n",
" \"period\": 50000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000006\": {\n",
" \"loop\": 20, \n",
" \"run\": 45000, \n",
" \"timer\": {\n",
" \"period\": 50000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }, \n",
" \"p000007\": {\n",
" \"loop\": 1, \n",
" \"run\": 90000, \n",
" \"timer\": {\n",
" \"period\": 100000, \n",
" \"ref\": \"task_ramp\"\n",
" }\n",
" }\n",
" }, \n",
" \"policy\": \"SCHED_OTHER\"\n",
" }\n",
" }\n",
"}\n"
]
}
],
"source": [
"# Inspect the JSON file used to run the application\n",
"with open('./{}_00.json'.format(rtapp_name), 'r') as fh:\n",
" rtapp_json = json.load(fh)\n",
"logging.info('Generated RTApp JSON file:')\n",
"print json.dumps(rtapp_json, indent=4, sort_keys=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3) execution"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:48:02 INFO : # Create results folder for this execution\n",
"12:48:02 INFO : # Setup FTrace\n",
"12:48:06 INFO : ## Start energy sampling\n",
"12:48:07 INFO : ### Start RTApp execution\n",
"12:48:07 INFO : WlGen - Workload execution START:\n",
"12:48:07 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/example2_00.json\n",
"12:48:14 INFO : ## Read energy consumption: /home/derkling/Code/lisa/results/WlgenExample/example2/energy.json\n",
"12:48:16 INFO : EnergyReport - Energy [ a53]: 1.495969\n",
"12:48:16 INFO : EnergyReport - Energy [ a57]: 25.145680\n",
"12:48:16 INFO : # Stop FTrace\n",
"12:48:17 INFO : # Save FTrace: /home/derkling/Code/lisa/results/WlgenExample/example2/trace.dat\n",
"12:48:19 INFO : # Save platform description: /home/derkling/Code/lisa/results/WlgenExample/example2/platform.json\n",
"12:48:19 INFO : # Report collected data:\n",
"12:48:19 INFO : /home/derkling/Code/lisa/results/WlgenExample/example2\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"total 4124\r\n",
"drwxrwxr-x 2 derkling derkling 4096 Mar 2 12:48 .\r\n",
"drwxrwxr-x 4 derkling derkling 4096 Mar 2 12:48 ..\r\n",
"-rw-rw-r-- 1 derkling derkling 53 Mar 2 12:48 energy.json\r\n",
"-rw-r--r-- 1 derkling derkling 2121 Mar 2 12:48 example2_00.json\r\n",
"-rw-rw-r-- 1 derkling derkling 235 Mar 2 12:48 output.log\r\n",
"-rw-rw-r-- 1 derkling derkling 1075 Mar 2 12:48 platform.json\r\n",
"-rw-r--r-- 1 derkling derkling 25084 Mar 2 12:48 rt-app-task_ramp-0.log\r\n",
"-rw-r--r-- 1 derkling derkling 4169728 Mar 2 12:48 trace.dat\r\n"
]
}
],
"source": [
"res_dir = os.path.join(te.res_dir, rtapp_name)\n",
"nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4) trace inspection"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"version = 6\r\n"
]
}
],
"source": [
"!kernelshark {trace_file} 2>/dev/null"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Custom RTApp connfiguration"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:55:36 INFO : WlGen - Setup new workload example3\n"
]
}
],
"source": [
"# Support to configure and run RTApp based workloads\n",
"from wlgen import RTA\n",
"\n",
"# Create a new RTApp workload generator using the calibration values\n",
"# reported by the TestEnv module\n",
"rtapp_name = 'example3'\n",
"rtapp = RTA(target, rtapp_name, calibration=te.calibration())\n",
"\n",
"# Configure this RTApp to use a custom JSON\n",
"rtapp.conf(\n",
"\n",
" # 1. generate a \"custom\" set of tasks\n",
" kind = 'custom',\n",
" \n",
" # 2. define the \"profile\" of each task\n",
" params = \"../../assets/mp3-short.json\",\n",
" \n",
" # In this case only few values of the orignal JSON can be tuned:\n",
" # DURATION : maximum duration of the workload [s]\n",
" # PVALUE : calibration value\n",
" # LOGDIR : folder used for generated logs\n",
" # WORKDIR : working directory on target\n",
" \n",
" # 3. defined a maximum duration for that workload\n",
" duration = 5,\n",
" \n",
");"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:55:53 INFO : # Create results folder for this execution\n",
"12:55:53 INFO : # Setup FTrace\n",
"12:55:57 INFO : ## Start energy sampling\n",
"12:55:58 INFO : ### Start RTApp execution\n",
"12:55:58 INFO : WlGen - Workload execution START:\n",
"12:55:58 INFO : WlGen - /root/devlib-target/bin/rt-app /root/devlib-target/example3_00.json\n",
"12:56:03 INFO : ## Read energy consumption: /home/derkling/Code/lisa/results/WlgenExample/example3/energy.json\n",
"12:56:04 INFO : EnergyReport - Energy [ a53]: 2.481205\n",
"12:56:04 INFO : EnergyReport - Energy [ a57]: 8.981533\n",
"12:56:04 INFO : # Stop FTrace\n",
"12:56:05 INFO : # Save FTrace: /home/derkling/Code/lisa/results/WlgenExample/example3/trace.dat\n",
"12:56:07 INFO : # Save platform description: /home/derkling/Code/lisa/results/WlgenExample/example3/platform.json\n",
"12:56:07 INFO : # Report collected data:\n",
"12:56:07 INFO : /home/derkling/Code/lisa/results/WlgenExample/example3\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"total 5048\r\n",
"drwxrwxr-x 2 derkling derkling 4096 Mar 2 12:56 .\r\n",
"drwxrwxr-x 5 derkling derkling 4096 Mar 2 12:55 ..\r\n",
"-rw-rw-r-- 1 derkling derkling 52 Mar 2 12:56 energy.json\r\n",
"-rw-r--r-- 1 derkling derkling 1324 Mar 2 12:56 example3_00.json\r\n",
"-rw-rw-r-- 1 derkling derkling 807 Mar 2 12:56 output.log\r\n",
"-rw-rw-r-- 1 derkling derkling 1075 Mar 2 12:56 platform.json\r\n",
"-rw-r--r-- 1 derkling derkling 5144576 Mar 2 12:56 trace.dat\r\n"
]
}
],
"source": [
"res_dir = os.path.join(te.res_dir, rtapp_name)\n",
"nrg_report, plt, plt_file, trace_file = execute(te, rtapp, res_dir)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"12:56:21 INFO : Generated RTApp JSON file:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"global\": {\n",
" \"calibration\": 138, \n",
" \"default_policy\": \"SCHED_OTHER\", \n",
" \"duration\": 5, \n",
" \"frag\": 1, \n",
" \"ftrace\": false, \n",
" \"gnuplot\": false, \n",
" \"lock_pages\": true, \n",
" \"log_basename\": \"mp3\", \n",
" \"logdir\": \"/root/devlib-target\"\n",
" }, \n",
" \"tasks\": {\n",
" \"AudioOut\": {\n",
" \"loop\": -1, \n",
" \"priority\": -19, \n",
" \"resume\": \"AudioTrack\", \n",
" \"run\": 4725, \n",
" \"suspend\": \"AudioOut\"\n",
" }, \n",
" \"AudioTick\": {\n",
" \"cpus\": [\n",
" 0\n",
" ], \n",
" \"loop\": -1, \n",
" \"phases\": {\n",
" \"p1\": {\n",
" \"loop\": 1, \n",
" \"resume\": \"AudioOut\", \n",
" \"timer\": {\n",
" \"period\": 6000, \n",
" \"ref\": \"tick\"\n",
" }\n",
" }, \n",
" \"p2\": {\n",
" \"loop\": 4, \n",
" \"timer\": {\n",
" \"period\": 6000, \n",
" \"ref\": \"tick\"\n",
" }\n",
" }\n",
" }, \n",
" \"priority\": -19\n",
" }, \n",
" \"AudioTrack\": {\n",
" \"loop\": -1, \n",
" \"priority\": -16, \n",
" \"resume\": \"mp3.decoder\", \n",
" \"run\": 300, \n",
" \"suspend\": \"AudioTrack\"\n",
" }, \n",
" \"OMXCall\": {\n",
" \"lock\": \"mutex\", \n",
" \"loop\": -1, \n",
" \"priority\": -2, \n",
" \"run\": 300, \n",
" \"signal\": \"queue\", \n",
" \"unlock\": \"mutex\", \n",
" \"wait\": {\n",
" \"mutex\": \"mutex\", \n",
" \"ref\": \"queue\"\n",
" }\n",
" }, \n",
" \"mp3.decoder\": {\n",
" \"lock\": \"mutex\", \n",
" \"loop\": -1, \n",
" \"priority\": -2, \n",
" \"run\": 150, \n",
" \"signal\": \"queue\", \n",
" \"suspend\": \"mp3.decoder\", \n",
" \"unlock\": \"mutex\", \n",
" \"wait\": {\n",
" \"mutex\": \"mutex\", \n",
" \"ref\": \"queue\"\n",
" }\n",
" }\n",
" }\n",
"}\n"
]
}
],
"source": [
"# Inspect the JSON file used to run the application\n",
"with open('./{}_00.json'.format(rtapp_name), 'r') as fh:\n",
" rtapp_json = json.load(fh)\n",
"logging.info('Generated RTApp JSON file:')\n",
"print json.dumps(rtapp_json, indent=4, sort_keys=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Running Hackbench"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1) creation and configuration"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"01:08:28 INFO : WlGen - Setup new workload hackbench\n"
]
},
{
"data": {
"text/plain": [
"'hackbench_00'"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Support to configure and run RTApp based workloads\n",
"from wlgen import PerfMessaging\n",
"\n",
"# Create a \"perf bench sched messages\" (i.e. hackbench) workload\n",
"perf_name = 'hackbench'\n",
"perf = PerfMessaging(target, perf_name)\n",
"\n",
"perf.conf(group=1, loop=100, pipe=True, thread=True)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2) execution"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"01:08:29 INFO : # Create results folder for this execution\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"mkdir: cannot create directory ‘/home/derkling/Code/lisa/results/WlgenExample/hackbench’: File exists\r\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"01:08:29 INFO : # Setup FTrace\n",
"01:08:31 INFO : ## Start energy sampling\n",
"01:08:31 INFO : ### Start RTApp execution\n",
"01:08:31 INFO : WlGen - Workload execution START:\n",
"01:08:31 INFO : WlGen - /root/devlib-target/bin/perf bench sched messaging --pipe --thread --group 1 --loop 100\n",
"01:08:32 INFO : PerfBench - Completion time: 0.126000, Performance 7.936508\n",
"01:08:32 INFO : ## Read energy consumption: /home/derkling/Code/lisa/results/WlgenExample/hackbench/energy.json\n",
"01:08:33 INFO : EnergyReport - Energy [ a53]: 1.066525\n",
"01:08:33 INFO : EnergyReport - Energy [ a57]: 2.245705\n",
"01:08:33 INFO : # Stop FTrace\n",
"01:08:34 INFO : # Save FTrace: /home/derkling/Code/lisa/results/WlgenExample/hackbench/trace.dat\n",
"01:08:36 INFO : # Save platform description: /home/derkling/Code/lisa/results/WlgenExample/hackbench/platform.json\n",
"01:08:36 INFO : # Report collected data:\n",
"01:08:36 INFO : /home/derkling/Code/lisa/results/WlgenExample/hackbench\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"total 10396\r\n",
"drwxrwxr-x 2 derkling derkling 4096 Mar 2 13:08 .\r\n",
"drwxrwxr-x 6 derkling derkling 4096 Mar 2 13:08 ..\r\n",
"-rw-rw-r-- 1 derkling derkling 52 Mar 2 13:08 energy.json\r\n",
"-rw-rw-r-- 1 derkling derkling 147 Mar 2 13:08 output.log\r\n",
"-rw-rw-r-- 1 derkling derkling 61 Mar 2 13:08 performance.json\r\n",
"-rw-rw-r-- 1 derkling derkling 1075 Mar 2 13:08 platform.json\r\n",
"-rw-r--r-- 1 derkling derkling 10620928 Mar 2 13:08 trace.dat\r\n"
]
}
],
"source": [
"res_dir = os.path.join(te.res_dir, perf_name)\n",
"nrg_report, plt, plt_file, trace_file = execute(te, perf, res_dir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3) explore the performance report"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"01:10:40 INFO : Generated performance JSON file:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"ctime\": 0.126, \n",
" \"performance\": 7.936507936507937\n",
"}\n"
]
}
],
"source": [
"# Inspect the generated performance report\n",
"perf_file = os.path.join(te.res_dir, perf_name, 'performance.json')\n",
"with open(perf_file, 'r') as fh:\n",
" perf_json = json.load(fh)\n",
"logging.info('Generated performance JSON file:')\n",
"print json.dumps(perf_json, indent=4, sort_keys=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4) trace inspection "
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"version = 6\r\n"
]
}
],
"source": [
"!kernelshark {trace_file} 2>/dev/null"
]
}
],
"metadata": {
"celltoolbar": "Raw Cell Format",
"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.9"
}
},
"nbformat": 4,
"nbformat_minor": 0
}