diff --git a/ipynb/chromeos/ChromeOS_TestThat.ipynb b/ipynb/deprecated/chromeos/ChromeOS_TestThat.ipynb similarity index 100% rename from ipynb/chromeos/ChromeOS_TestThat.ipynb rename to ipynb/deprecated/chromeos/ChromeOS_TestThat.ipynb diff --git a/ipynb/energy/EnergyModel_ClusterEnergy.ipynb b/ipynb/deprecated/energy/EnergyModel_ClusterEnergy.ipynb similarity index 100% rename from ipynb/energy/EnergyModel_ClusterEnergy.ipynb rename to ipynb/deprecated/energy/EnergyModel_ClusterEnergy.ipynb diff --git a/ipynb/energy/EnergyModel_SystemEnergy.ipynb b/ipynb/deprecated/energy/EnergyModel_SystemEnergy.ipynb similarity index 100% rename from ipynb/energy/EnergyModel_SystemEnergy.ipynb rename to ipynb/deprecated/energy/EnergyModel_SystemEnergy.ipynb diff --git a/ipynb/examples/android/benchmarks/Android_Geekbench.ipynb b/ipynb/deprecated/examples/android/benchmarks/Android_Geekbench.ipynb similarity index 100% rename from ipynb/examples/android/benchmarks/Android_Geekbench.ipynb rename to ipynb/deprecated/examples/android/benchmarks/Android_Geekbench.ipynb diff --git a/ipynb/examples/android/benchmarks/Android_Jankbench.ipynb b/ipynb/deprecated/examples/android/benchmarks/Android_Jankbench.ipynb similarity index 100% rename from ipynb/examples/android/benchmarks/Android_Jankbench.ipynb rename to ipynb/deprecated/examples/android/benchmarks/Android_Jankbench.ipynb diff --git a/ipynb/examples/android/benchmarks/Android_PCMark.ipynb b/ipynb/deprecated/examples/android/benchmarks/Android_PCMark.ipynb similarity index 100% rename from ipynb/examples/android/benchmarks/Android_PCMark.ipynb rename to ipynb/deprecated/examples/android/benchmarks/Android_PCMark.ipynb diff --git a/ipynb/examples/android/benchmarks/Android_UiBench.ipynb b/ipynb/deprecated/examples/android/benchmarks/Android_UiBench.ipynb similarity index 100% rename from ipynb/examples/android/benchmarks/Android_UiBench.ipynb rename to ipynb/deprecated/examples/android/benchmarks/Android_UiBench.ipynb diff --git a/ipynb/examples/android/workloads/Android_Gmaps.ipynb b/ipynb/deprecated/examples/android/workloads/Android_Gmaps.ipynb similarity index 100% rename from ipynb/examples/android/workloads/Android_Gmaps.ipynb rename to ipynb/deprecated/examples/android/workloads/Android_Gmaps.ipynb diff --git a/ipynb/examples/android/workloads/Android_Recents_Fling.ipynb b/ipynb/deprecated/examples/android/workloads/Android_Recents_Fling.ipynb similarity index 100% rename from ipynb/examples/android/workloads/Android_Recents_Fling.ipynb rename to ipynb/deprecated/examples/android/workloads/Android_Recents_Fling.ipynb diff --git a/ipynb/examples/android/workloads/Android_Viewer.ipynb b/ipynb/deprecated/examples/android/workloads/Android_Viewer.ipynb similarity index 100% rename from ipynb/examples/android/workloads/Android_Viewer.ipynb rename to ipynb/deprecated/examples/android/workloads/Android_Viewer.ipynb diff --git a/ipynb/examples/android/workloads/Android_Workloads.ipynb b/ipynb/deprecated/examples/android/workloads/Android_Workloads.ipynb similarity index 100% rename from ipynb/examples/android/workloads/Android_Workloads.ipynb rename to ipynb/deprecated/examples/android/workloads/Android_Workloads.ipynb diff --git a/ipynb/examples/android/workloads/Android_YouTube.ipynb b/ipynb/deprecated/examples/android/workloads/Android_YouTube.ipynb similarity index 100% rename from ipynb/examples/android/workloads/Android_YouTube.ipynb rename to ipynb/deprecated/examples/android/workloads/Android_YouTube.ipynb diff --git a/ipynb/examples/devlib/cgroups_example.ipynb b/ipynb/deprecated/examples/devlib/cgroups_example.ipynb similarity index 100% rename from ipynb/examples/devlib/cgroups_example.ipynb rename to ipynb/deprecated/examples/devlib/cgroups_example.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb b/ipynb/deprecated/examples/energy_meter/EnergyMeter_ACME.ipynb similarity index 100% rename from ipynb/examples/energy_meter/EnergyMeter_ACME.ipynb rename to ipynb/deprecated/examples/energy_meter/EnergyMeter_ACME.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_AEP.ipynb b/ipynb/deprecated/examples/energy_meter/EnergyMeter_AEP.ipynb similarity index 100% rename from ipynb/examples/energy_meter/EnergyMeter_AEP.ipynb rename to ipynb/deprecated/examples/energy_meter/EnergyMeter_AEP.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_Gem5.ipynb b/ipynb/deprecated/examples/energy_meter/EnergyMeter_Gem5.ipynb similarity index 100% rename from ipynb/examples/energy_meter/EnergyMeter_Gem5.ipynb rename to ipynb/deprecated/examples/energy_meter/EnergyMeter_Gem5.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_HWMON.ipynb b/ipynb/deprecated/examples/energy_meter/EnergyMeter_HWMON.ipynb similarity index 100% rename from ipynb/examples/energy_meter/EnergyMeter_HWMON.ipynb rename to ipynb/deprecated/examples/energy_meter/EnergyMeter_HWMON.ipynb diff --git a/ipynb/examples/energy_meter/EnergyMeter_Monsoon.ipynb b/ipynb/deprecated/examples/energy_meter/EnergyMeter_Monsoon.ipynb similarity index 100% rename from ipynb/examples/energy_meter/EnergyMeter_Monsoon.ipynb rename to ipynb/deprecated/examples/energy_meter/EnergyMeter_Monsoon.ipynb diff --git a/ipynb/examples/trace_analysis/TraceAnalysis_FunctionsProfiling.ipynb b/ipynb/deprecated/examples/trace_analysis/TraceAnalysis_FunctionsProfiling.ipynb similarity index 100% rename from ipynb/examples/trace_analysis/TraceAnalysis_FunctionsProfiling.ipynb rename to ipynb/deprecated/examples/trace_analysis/TraceAnalysis_FunctionsProfiling.ipynb diff --git a/ipynb/examples/trace_analysis/TraceAnalysis_IdleStates.ipynb b/ipynb/deprecated/examples/trace_analysis/TraceAnalysis_IdleStates.ipynb similarity index 100% rename from ipynb/examples/trace_analysis/TraceAnalysis_IdleStates.ipynb rename to ipynb/deprecated/examples/trace_analysis/TraceAnalysis_IdleStates.ipynb diff --git a/ipynb/examples/trace_analysis/TraceAnalysis_TasksLatencies.ipynb b/ipynb/deprecated/examples/trace_analysis/TraceAnalysis_TasksLatencies.ipynb similarity index 100% rename from ipynb/examples/trace_analysis/TraceAnalysis_TasksLatencies.ipynb rename to ipynb/deprecated/examples/trace_analysis/TraceAnalysis_TasksLatencies.ipynb diff --git a/ipynb/examples/trappy/custom_events_example.ipynb b/ipynb/deprecated/examples/trappy/custom_events_example.ipynb similarity index 100% rename from ipynb/examples/trappy/custom_events_example.ipynb rename to ipynb/deprecated/examples/trappy/custom_events_example.ipynb diff --git a/ipynb/examples/trappy/trappy_example.ipynb b/ipynb/deprecated/examples/trappy/trappy_example.ipynb similarity index 100% rename from ipynb/examples/trappy/trappy_example.ipynb rename to ipynb/deprecated/examples/trappy/trappy_example.ipynb diff --git a/ipynb/examples/utils/executor_example.ipynb b/ipynb/deprecated/examples/utils/executor_example.ipynb similarity index 100% rename from ipynb/examples/utils/executor_example.ipynb rename to ipynb/deprecated/examples/utils/executor_example.ipynb diff --git a/ipynb/examples/utils/gem5_example.ipynb b/ipynb/deprecated/examples/utils/gem5_example.ipynb similarity index 100% rename from ipynb/examples/utils/gem5_example.ipynb rename to ipynb/deprecated/examples/utils/gem5_example.ipynb diff --git a/ipynb/examples/utils/testenv_example.ipynb b/ipynb/deprecated/examples/utils/testenv_example.ipynb similarity index 100% rename from ipynb/examples/utils/testenv_example.ipynb rename to ipynb/deprecated/examples/utils/testenv_example.ipynb diff --git a/ipynb/examples/wlgen/rtapp_custom_example.ipynb b/ipynb/deprecated/examples/wlgen/rtapp_custom_example.ipynb similarity index 100% rename from ipynb/examples/wlgen/rtapp_custom_example.ipynb rename to ipynb/deprecated/examples/wlgen/rtapp_custom_example.ipynb diff --git a/ipynb/examples/wlgen/rtapp_example.ipynb b/ipynb/deprecated/examples/wlgen/rtapp_example.ipynb similarity index 100% rename from ipynb/examples/wlgen/rtapp_example.ipynb rename to ipynb/deprecated/examples/wlgen/rtapp_example.ipynb diff --git a/ipynb/releases/ReleaseNotes_v16.10.ipynb b/ipynb/deprecated/releases/ReleaseNotes_v16.10.ipynb similarity index 100% rename from ipynb/releases/ReleaseNotes_v16.10.ipynb rename to ipynb/deprecated/releases/ReleaseNotes_v16.10.ipynb diff --git a/ipynb/releases/ReleaseNotes_v16.12.ipynb b/ipynb/deprecated/releases/ReleaseNotes_v16.12.ipynb similarity index 100% rename from ipynb/releases/ReleaseNotes_v16.12.ipynb rename to ipynb/deprecated/releases/ReleaseNotes_v16.12.ipynb diff --git a/ipynb/releases/ReleaseNotes_v17.03.ipynb b/ipynb/deprecated/releases/ReleaseNotes_v17.03.ipynb similarity index 100% rename from ipynb/releases/ReleaseNotes_v17.03.ipynb rename to ipynb/deprecated/releases/ReleaseNotes_v17.03.ipynb diff --git a/ipynb/sched_dvfs/smoke_test.ipynb b/ipynb/deprecated/sched_dvfs/smoke_test.ipynb similarity index 100% rename from ipynb/sched_dvfs/smoke_test.ipynb rename to ipynb/deprecated/sched_dvfs/smoke_test.ipynb diff --git a/ipynb/sched_tune/stune_juno_rampL.ipynb b/ipynb/deprecated/sched_tune/stune_juno_rampL.ipynb similarity index 100% rename from ipynb/sched_tune/stune_juno_rampL.ipynb rename to ipynb/deprecated/sched_tune/stune_juno_rampL.ipynb diff --git a/ipynb/sched_tune/stune_juno_taskonly_rampL.ipynb b/ipynb/deprecated/sched_tune/stune_juno_taskonly_rampL.ipynb similarity index 100% rename from ipynb/sched_tune/stune_juno_taskonly_rampL.ipynb rename to ipynb/deprecated/sched_tune/stune_juno_taskonly_rampL.ipynb diff --git a/ipynb/sched_tune/stune_oak_rampL.ipynb b/ipynb/deprecated/sched_tune/stune_oak_rampL.ipynb similarity index 100% rename from ipynb/sched_tune/stune_oak_rampL.ipynb rename to ipynb/deprecated/sched_tune/stune_oak_rampL.ipynb diff --git a/ipynb/tests/Frequency_Invariance_Test.ipynb b/ipynb/deprecated/tests/Frequency_Invariance_Test.ipynb similarity index 100% rename from ipynb/tests/Frequency_Invariance_Test.ipynb rename to ipynb/deprecated/tests/Frequency_Invariance_Test.ipynb diff --git a/ipynb/tests/Generic_EAS_Tests.ipynb b/ipynb/deprecated/tests/Generic_EAS_Tests.ipynb similarity index 100% rename from ipynb/tests/Generic_EAS_Tests.ipynb rename to ipynb/deprecated/tests/Generic_EAS_Tests.ipynb diff --git a/ipynb/thermal/ThermalSensorCharacterisation.ipynb b/ipynb/deprecated/thermal/ThermalSensorCharacterisation.ipynb similarity index 100% rename from ipynb/thermal/ThermalSensorCharacterisation.ipynb rename to ipynb/deprecated/thermal/ThermalSensorCharacterisation.ipynb diff --git a/ipynb/tutorial/00_LisaInANutshell.ipynb b/ipynb/deprecated/tutorial/00_LisaInANutshell.ipynb similarity index 100% rename from ipynb/tutorial/00_LisaInANutshell.ipynb rename to ipynb/deprecated/tutorial/00_LisaInANutshell.ipynb diff --git a/ipynb/tutorial/01_IPythonNotebooksUsage.ipynb b/ipynb/deprecated/tutorial/01_IPythonNotebooksUsage.ipynb similarity index 100% rename from ipynb/tutorial/01_IPythonNotebooksUsage.ipynb rename to ipynb/deprecated/tutorial/01_IPythonNotebooksUsage.ipynb diff --git a/ipynb/tutorial/02_TestEnvUsage.ipynb b/ipynb/deprecated/tutorial/02_TestEnvUsage.ipynb similarity index 100% rename from ipynb/tutorial/02_TestEnvUsage.ipynb rename to ipynb/deprecated/tutorial/02_TestEnvUsage.ipynb diff --git a/ipynb/tutorial/03_WlGenUsage.ipynb b/ipynb/deprecated/tutorial/03_WlGenUsage.ipynb similarity index 100% rename from ipynb/tutorial/03_WlGenUsage.ipynb rename to ipynb/deprecated/tutorial/03_WlGenUsage.ipynb diff --git a/ipynb/tutorial/04_ExecutorUsage.ipynb b/ipynb/deprecated/tutorial/04_ExecutorUsage.ipynb similarity index 100% rename from ipynb/tutorial/04_ExecutorUsage.ipynb rename to ipynb/deprecated/tutorial/04_ExecutorUsage.ipynb diff --git a/ipynb/tutorial/05_TrappyUsage.ipynb b/ipynb/deprecated/tutorial/05_TrappyUsage.ipynb similarity index 100% rename from ipynb/tutorial/05_TrappyUsage.ipynb rename to ipynb/deprecated/tutorial/05_TrappyUsage.ipynb diff --git a/ipynb/tutorial/06_TraceAnalysis.ipynb b/ipynb/deprecated/tutorial/06_TraceAnalysis.ipynb similarity index 100% rename from ipynb/tutorial/06_TraceAnalysis.ipynb rename to ipynb/deprecated/tutorial/06_TraceAnalysis.ipynb diff --git a/ipynb/tutorial/07_PerfAnalysis.ipynb b/ipynb/deprecated/tutorial/07_PerfAnalysis.ipynb similarity index 100% rename from ipynb/tutorial/07_PerfAnalysis.ipynb rename to ipynb/deprecated/tutorial/07_PerfAnalysis.ipynb diff --git a/ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb b/ipynb/deprecated/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb similarity index 100% rename from ipynb/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb rename to ipynb/deprecated/tutorial/UseCaseExamples_SchedTuneAnalysis.ipynb diff --git a/ipynb/tutorial/example_results/platform.json b/ipynb/deprecated/tutorial/example_results/platform.json similarity index 100% rename from ipynb/tutorial/example_results/platform.json rename to ipynb/deprecated/tutorial/example_results/platform.json diff --git a/ipynb/tutorial/example_results/trace.dat b/ipynb/deprecated/tutorial/example_results/trace.dat similarity index 100% rename from ipynb/tutorial/example_results/trace.dat rename to ipynb/deprecated/tutorial/example_results/trace.dat diff --git a/ipynb/tutorial/example_rtapp/trace.dat b/ipynb/deprecated/tutorial/example_rtapp/trace.dat similarity index 100% rename from ipynb/tutorial/example_rtapp/trace.dat rename to ipynb/deprecated/tutorial/example_rtapp/trace.dat diff --git a/ipynb/examples/New test API example.ipynb b/ipynb/examples/New test API example.ipynb deleted file mode 100644 index f94e8fc337f82a7924d0d7ea356695554b4871d1..0000000000000000000000000000000000000000 --- a/ipynb/examples/New test API example.ipynb +++ /dev/null @@ -1,631 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:16.843906Z", - "start_time": "2018-09-21T16:24:16.832296Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-09-21 17:24:16,841 INFO : root : Using LISA logging configuration:\n", - "2018-09-21 17:24:16,842 INFO : root : /home/dourai01/Data/Git/lisa/py3k/logging.conf\n" - ] - } - ], - "source": [ - "import logging\n", - "from lisa.utils import setup_logging\n", - "setup_logging()" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:16.990593Z", - "start_time": "2018-09-21T16:24:16.845370Z" - } - }, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:17.516760Z", - "start_time": "2018-09-21T16:24:16.992560Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - } - ], - "source": [ - "%pylab inline\n", - "\n", - "import json\n", - "import os\n", - "\n", - "# Support to access the remote target\n", - "import devlib\n", - "from lisa.env import TestEnv, TargetConfig\n", - "\n", - "# Import support for Android devices\n", - "from lisa.android import Screen, Workload\n", - "\n", - "# Support for trace events analysis\n", - "from lisa.trace import Trace\n", - "\n", - "# Suport for FTrace events parsing and visualization\n", - "import trappy\n", - "import pandas as pd\n", - "\n", - "from lisa.wlgen.rta import RTA, Periodic, Ramp\n", - "from time import sleep\n", - "\n", - "from IPython.display import display" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:17.529943Z", - "start_time": "2018-09-21T16:24:17.518146Z" - } - }, - "outputs": [], - "source": [ - "linux_hikey = {\n", - " \"platform\" : \"linux\",\n", - " \"board\" : \"hikey\",\n", - " \"host\": \"pwrsft-hikey620-1\",\n", - " #\"username\" : \"root\",\n", - " #\"password\" : \"root\",\n", - " \"modules\" : [\"sched\", \"cgroups\", \"hotplug\"],\n", - " \"tools\" : [\"taskset\", \"rt-app\"],\n", - " \"rtapp-calib\" : {\n", - " \"0\": 302, \"1\": 302, \"2\": 302, \"3\": 302, \"4\": 136, \"5\": 136, \"6\": 136, \"7\": 136\n", - " }\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:17.590995Z", - "start_time": "2018-09-21T16:24:17.531405Z" - } - }, - "outputs": [], - "source": [ - "linux_juno = {\n", - " \"platform\" : \"linux\",\n", - " \"board\" : \"juno\",\n", - " \"host\": \"192.168.0.1\",\n", - " \"username\" : \"root\",\n", - " \"password\" : \"root\",\n", - " \"modules\" : [\"sched\", \"cgroups\", \"hotplug\"],\n", - " \"tools\" : [\"taskset\", \"rt-app\"]\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:17.665751Z", - "start_time": "2018-09-21T16:24:17.592231Z" - } - }, - "outputs": [], - "source": [ - "android_hikey = {\n", - " \"platform\" : \"android\",\n", - " \"board\" : \"hikey960\",\n", - " \"modules\" : [\"sched\", \"hotplug\"],\n", - " \"tools\" : [\"taskset\", \"rt-app\"]\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:33.107785Z", - "start_time": "2018-09-21T16:24:17.667030Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-09-21 17:24:17,730 INFO : lisa.env.TestEnv : Using base path: /home/dourai01/Data/Git/lisa/py3k\n", - "2018-09-21 17:24:17,731 INFO : lisa.env.TestEnv : Devlib modules to load: ['hotplug', 'sched', 'cpufreq', 'cpuidle', 'cgroups']\n", - "2018-09-21 17:24:17,732 INFO : lisa.env.TestEnv : Connecting linux target:\n", - "2018-09-21 17:24:17,733 INFO : lisa.env.TestEnv : username : root\n", - "2018-09-21 17:24:17,733 INFO : lisa.env.TestEnv : password : \n", - "2018-09-21 17:24:17,734 INFO : lisa.env.TestEnv : host : pwrsft-hikey620-1\n", - "2018-09-21 17:24:17,734 INFO : lisa.env.TestEnv : Connection settings:\n", - "2018-09-21 17:24:17,734 INFO : lisa.env.TestEnv : {'username': 'root', 'password': '', 'host': 'pwrsft-hikey620-1'}\n", - "2018-09-21 17:24:23,869 INFO : lisa.env.TestEnv : Initializing target workdir:\n", - "2018-09-21 17:24:23,870 INFO : lisa.env.TestEnv : /root/devlib-target\n", - "2018-09-21 17:24:24,844 INFO : CGroups : Available controllers:\n", - "2018-09-21 17:24:25,454 INFO : CGroups : cpuset : /root/devlib-target/cgroups/devlib_cgh3\n", - "2018-09-21 17:24:26,070 INFO : CGroups : cpu : /root/devlib-target/cgroups/devlib_cgh2\n", - "2018-09-21 17:24:26,686 INFO : CGroups : cpuacct : /root/devlib-target/cgroups/devlib_cgh2\n", - "2018-09-21 17:24:27,310 INFO : CGroups : blkio : /root/devlib-target/cgroups/devlib_cgh4\n", - "2018-09-21 17:24:27,939 INFO : CGroups : memory : /root/devlib-target/cgroups/devlib_cgh7\n", - "2018-09-21 17:24:28,567 INFO : CGroups : devices : /root/devlib-target/cgroups/devlib_cgh8\n", - "2018-09-21 17:24:29,187 INFO : CGroups : freezer : /root/devlib-target/cgroups/devlib_cgh5\n", - "2018-09-21 17:24:29,793 INFO : CGroups : perf_event : /root/devlib-target/cgroups/devlib_cgh9\n", - "2018-09-21 17:24:30,406 INFO : CGroups : hugetlb : /root/devlib-target/cgroups/devlib_cgh10\n", - "2018-09-21 17:24:31,019 INFO : CGroups : pids : /root/devlib-target/cgroups/devlib_cgh6\n", - "2018-09-21 17:24:32,897 INFO : lisa.env.TestEnv : Topology:\n", - "2018-09-21 17:24:32,898 INFO : lisa.env.TestEnv : [[0, 1, 2, 3, 4, 5, 6, 7]]\n", - "2018-09-21 17:24:33,102 INFO : lisa.env.TestEnv : Loading default EM:\n", - "2018-09-21 17:24:33,103 INFO : lisa.env.TestEnv : /home/dourai01/Data/Git/lisa/py3k/lisa/platforms/hikey.json\n" - ] - } - ], - "source": [ - "te = TestEnv(TargetConfig(linux_hikey))\n", - "target = te.target" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Generics" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:33.126433Z", - "start_time": "2018-09-21T16:24:33.109728Z" - } - }, - "outputs": [], - "source": [ - "from lisa.tests.kernel.scheduler.eas_behaviour import *" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:24:33.198008Z", - "start_time": "2018-09-21T16:24:33.127714Z" - } - }, - "outputs": [], - "source": [ - "tests = [OneSmallTask]#, ThreeSmallTasks, TwoBigTasks, TwoBigThreeSmall, RampUp, RampDown, EnergyModelWakeMigration]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:01.726466Z", - "start_time": "2018-09-21T16:24:33.199384Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-09-21 17:24:37,770 INFO : lisa.env.TestEnv : Using configuration provided RTApp calibration\n", - "2018-09-21 17:24:37,772 INFO : lisa.env.TestEnv : Using RT-App calibration values:\n", - "2018-09-21 17:24:37,773 INFO : lisa.env.TestEnv : {\"0\": 302, \"1\": 302, \"2\": 302, \"3\": 302, \"4\": 136, \"5\": 136, \"6\": 136, \"7\": 136}\n", - "2018-09-21 17:24:38,164 INFO : lisa.wlgen.rta.RTA : Calibration value: 136\n", - "2018-09-21 17:24:38,164 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-09-21 17:24:38,165 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-09-21 17:24:38,165 INFO : lisa.wlgen.rta.RTA : task [small], sched: using default policy\n", - "2018-09-21 17:24:38,166 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-09-21 17:24:38,166 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-09-21 17:24:38,167 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-09-21 17:24:38,167 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (62 loops)\n", - "2018-09-21 17:24:38,168 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 50 %\n", - "2018-09-21 17:24:38,168 INFO : lisa.wlgen.rta.Phase : | run_time 8000 [us], sleep_time 8000 [us]\n", - "2018-09-21 17:24:40,853 INFO : lisa.env.TestEnv : Enabled tracepoints:\n", - "2018-09-21 17:24:40,855 INFO : lisa.env.TestEnv : sched_switch\n", - "2018-09-21 17:24:45,754 INFO : lisa.env.TestEnv : Freezing all tasks except: init,systemd,dbus,sh,ssh,rsyslogd,jbd2\n", - "2018-09-21 17:24:51,854 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_onesmalltask.json 2>&1\n", - "2018-09-21 17:24:53,828 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-09-21 17:24:54,293 INFO : lisa.env.TestEnv : Un-freezing userspace tasks\n" - ] - } - ], - "source": [ - "res = {}\n", - "\n", - "for test in tests:\n", - " bundle = test.from_target(te)\n", - " res[test.__name__] = bundle" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:02.823231Z", - "start_time": "2018-09-21T16:25:01.727972Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "OneSmallTask\n", - "---\n", - "test_slack: FAILED: slack_small_0 = 0.0 %, slack_small_1 = 0.0 %, slack_small_2 = 0.0 %, slack_small = 100.0 %\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-09-21 17:25:02,302 WARNING : lisa.trace.Trace : Kernel version not available from platform data\n", - "2018-09-21 17:25:02,303 INFO : lisa.trace.Trace : Parsing trace assuming kernel v3.18\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "test_task_placement: PASSED: estimated_energy = 144.34142511858244 bogo-joules, energy_threshold = 245.74051446945342 bogo-joules\n", - "\n" - ] - } - ], - "source": [ - "for test_name, bundle in res.items():\n", - " print(test_name)\n", - " print(\"---\")\n", - " print(\"test_slack: {}\".format(bundle.test_slack()))\n", - " print(\"test_task_placement: {}\".format(bundle.test_task_placement()))\n", - " print()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### CPU sanity check" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:02.836776Z", - "start_time": "2018-09-21T16:25:02.824794Z" - } - }, - "outputs": [], - "source": [ - "from lisa.tests.kernel.misc.capacity_sanity import CapacitySanityCheck" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:21.346729Z", - "start_time": "2018-09-21T16:25:02.838148Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-09-21 17:25:07,820 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x1 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:09,002 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:09,337 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x2 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:10,516 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:10,850 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x4 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:12,027 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:12,361 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x8 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:13,539 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:13,871 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x10 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:15,048 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:15,381 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x20 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:16,557 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:16,889 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x40 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:18,069 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n", - "2018-09-21 17:25:18,406 INFO : lisa.wlgen.sysbench.Sysbench : Execution start: /root/devlib-target/bin/taskset 0x80 /root/devlib-target/bin/sysbench --test=cpu --max-time=1 run\n", - "2018-09-21 17:25:19,584 INFO : lisa.wlgen.sysbench.Sysbench : Execution complete\n" - ] - } - ], - "source": [ - "bundle = CapacitySanityCheck.from_target(te)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:21.366713Z", - "start_time": "2018-09-21T16:25:21.351798Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED: Performance @1024 capacity = 227\n" - ] - } - ], - "source": [ - "print(str(bundle.test_capacity_sanity()))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hotplug" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:21.455193Z", - "start_time": "2018-09-21T16:25:21.368362Z" - } - }, - "outputs": [], - "source": [ - "from lisa.tests.kernel.hotplug.torture import HotplugTorture" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:34.940206Z", - "start_time": "2018-09-21T16:25:21.456916Z" - } - }, - "outputs": [], - "source": [ - "bundle = HotplugTorture.from_target(te)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:48.538456Z", - "start_time": "2018-09-21T16:25:48.526819Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED\n" - ] - } - ], - "source": [ - "print(bundle.test_cpus_alive().result.name)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:35.137759Z", - "start_time": "2018-09-21T16:25:34.959131Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'hotpluggable CPUs': TestMetric([0, 1, 2, 3, 4, 5, 6, 7], None), 'Online CPUs': TestMetric([0, 1, 2, 3, 4, 5, 6, 7], None)}\n" - ] - } - ], - "source": [ - "print(bundle.test_cpus_alive().metrics)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "ExecuteTime": { - "end_time": "2018-09-21T16:25:52.892836Z", - "start_time": "2018-09-21T16:25:52.880691Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED\n" - ] - } - ], - "source": [ - "print(bundle.test_target_alive().result.name)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.0" - }, - "toc": { - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/ipynb/examples/kernel_tests/test_bundle_demo.ipynb b/ipynb/examples/kernel_tests/test_bundle_demo.ipynb deleted file mode 100644 index c0649ee443a0ba2f01eaab4a484d2ba821f9c3d8..0000000000000000000000000000000000000000 --- a/ipynb/examples/kernel_tests/test_bundle_demo.ipynb +++ /dev/null @@ -1,675 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-10-17 15:35:35,574 INFO : root : Using LISA logging configuration:\n", - "2018-10-17 15:35:35,575 INFO : root : /data/work/lisa/logging.conf\n" - ] - } - ], - "source": [ - "import logging\n", - "from lisa.utils import setup_logging\n", - "setup_logging()" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-10-17 15:35:35,866 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/Grammar.txt\n", - "2018-10-17 15:35:35,889 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/PatternGrammar.txt\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - } - ], - "source": [ - "%pylab inline\n", - "\n", - "import json\n", - "import os\n", - "\n", - "# Support to access the remote target\n", - "import devlib\n", - "from lisa.env import TestEnv, TargetConf\n", - "from lisa.platforms.platinfo import PlatformInfo\n", - "\n", - "# Support for trace events analysis\n", - "from lisa.trace import Trace\n", - "\n", - "# Suport for FTrace events parsing and visualization\n", - "import trappy\n", - "import pandas as pd\n", - "\n", - "from lisa.wlgen.rta import RTA, Periodic, Ramp\n", - "from time import sleep\n", - "\n", - "from IPython.display import display, Image\n", - "from IPython.display import Image" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# This is information only relevant to create a\n", - "# connection between the host and the target\n", - "target_conf = TargetConf({\n", - " \"kind\" : \"linux\",\n", - " \"name\" : \"hikey960\",\n", - " \"host\": \"192.168.0.1\",\n", - " \"username\" : \"root\",\n", - " \"password\" : \"root\",\n", - "})" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-10-17 15:35:36,295 INFO : lisa.env.TestEnv : Pre-configured platform information:\n", - "\n", - "2018-10-17 15:35:36,409 INFO : lisa.env.TestEnv : linux hikey960 target connection settings:\n", - "2018-10-17 15:35:36,410 INFO : lisa.env.TestEnv : host : 192.168.0.1\n", - "2018-10-17 15:35:36,410 INFO : lisa.env.TestEnv : username : root\n", - "2018-10-17 15:35:36,411 INFO : lisa.env.TestEnv : password : root\n", - "2018-10-17 15:35:36,412 INFO : lisa.env.TestEnv : port : 22\n", - "2018-10-17 15:35:36,428 INFO : lisa.env.TestEnv : Devlib modules to load: ['bl', 'cgroups', 'cpufreq', 'cpuidle', 'devfreq', 'fastboot', 'gem5stats', 'gpufreq', 'hotplug', 'hwmon', 'mbed-fan', 'odroidxu3-fan', 'sched', 'thermal']\n", - "2018-10-17 15:35:41,287 WARNING : LinuxTarget : Module devfreq is not supported by the target\n", - "2018-10-17 15:35:41,289 WARNING : LinuxTarget : Module fastboot is not supported by the target\n", - "2018-10-17 15:35:41,291 WARNING : LinuxTarget : Module gem5stats is not supported by the target\n", - "2018-10-17 15:35:41,460 WARNING : LinuxTarget : Module gpufreq is not supported by the target\n", - "2018-10-17 15:35:42,150 WARNING : LinuxTarget : Module odroidxu3-fan is not supported by the target\n", - "2018-10-17 15:35:43,864 INFO : CGroups : Available controllers:\n", - "2018-10-17 15:35:44,735 INFO : CGroups : cpuset : /root/devlib-target/cgroups/devlib_cgh10\n", - "2018-10-17 15:35:45,605 INFO : CGroups : cpu : /root/devlib-target/cgroups/devlib_cgh5\n", - "2018-10-17 15:35:46,127 INFO : CGroups : cpuacct : /root/devlib-target/cgroups/devlib_cgh5\n", - "2018-10-17 15:35:46,995 INFO : CGroups : blkio : /root/devlib-target/cgroups/devlib_cgh3\n", - "2018-10-17 15:35:47,870 INFO : CGroups : memory : /root/devlib-target/cgroups/devlib_cgh7\n", - "2018-10-17 15:35:48,753 INFO : CGroups : devices : /root/devlib-target/cgroups/devlib_cgh8\n", - "2018-10-17 15:35:49,619 INFO : CGroups : freezer : /root/devlib-target/cgroups/devlib_cgh2\n", - "2018-10-17 15:35:50,488 INFO : CGroups : perf_event : /root/devlib-target/cgroups/devlib_cgh9\n", - "2018-10-17 15:35:51,368 INFO : CGroups : hugetlb : /root/devlib-target/cgroups/devlib_cgh4\n", - "2018-10-17 15:35:52,248 INFO : CGroups : pids : /root/devlib-target/cgroups/devlib_cgh6\n", - "2018-10-17 15:35:52,420 WARNING : lisa.env.TestEnv : Failed to initialized \"devfreq\" devlib Module\n", - "2018-10-17 15:35:52,421 WARNING : lisa.env.TestEnv : Failed to initialized \"fastboot\" devlib Module\n", - "2018-10-17 15:35:52,423 WARNING : lisa.env.TestEnv : Failed to initialized \"gem5stats\" devlib Module\n", - "2018-10-17 15:35:52,424 WARNING : lisa.env.TestEnv : Failed to initialized \"gpufreq\" devlib Module\n", - "2018-10-17 15:35:52,425 WARNING : lisa.env.TestEnv : Failed to initialized \"mbed-fan\" devlib Module\n", - "2018-10-17 15:35:52,427 WARNING : lisa.env.TestEnv : Failed to initialized \"odroidxu3-fan\" devlib Module\n", - "2018-10-17 15:35:52,453 INFO : lisa.platforms.platinfo.PlatformInfo : Attempting to read energy model from target\n", - "2018-10-17 15:35:52,971 INFO : lisa.energy_model.EnergyModel.EMReader : Attempting to load EM using from_simplifiedEM_target\n", - "2018-10-17 15:35:56,696 INFO : lisa.env.TestEnv : Effective platform information:\n", - "|- nrg-model from target (EnergyModel): \n", - "|- clusters from from-nrg-model (dict): {'little': [0, 1, 2, 3], 'big': [4, 5, 6, 7]}\n", - "|- topology from from-nrg-model (Topology):\n", - "| cluster [[0, 1, 2, 3], [4, 5, 6, 7]]\n", - "| cpu [[0], [1], [2], [3], [4], [5], [6], [7]]\n", - "| \n", - "|- freqs from from-nrg-model (dict): {'little': [533000, 999000, 1402000, 1709000, 1844000], 'big': [903000, 1421000, 1805000, 2112000, 2362000]}\n", - "|- cpus-count from from-nrg-model (int): 8\n", - "|- kernel-version from target (KernelVersion): 4.19.0-rc5-00347-ga58f958 2 SMP PREEMPT Tue Oct 16 16:16:46 BST 2018\n", - "|- os from target (str): linux\n", - "|- cpu-capacities from target (dict): {0: 462, 1: 462, 2: 462, 3: 462, 4: 1024, 5: 1024, 6: 1024, 7: 1024}\n", - "|- abi from target (str): arm64\n", - "+- rtapp:\n", - " |- calib from target (DeferredValue): \n" - ] - } - ], - "source": [ - "te = TestEnv(target_conf)\n", - "target = te.target" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Live target experimentation" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from lisa.tests.kernel.scheduler.eas_behaviour import EnergyModelWakeMigration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We want to create a TestBundle from a live target, so we can use the **from_testenv** alternative constructor:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-10-17 15:35:57,545 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/TestEnv_20181017_153536.294978/20181017_153557.545666\n", - "2018-10-17 15:36:13,484 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/TestEnv_20181017_153536.294978/rta_calib-20181017_153613.484460\n", - "2018-10-17 15:36:13,652 INFO : lisa.wlgen.rta.RTA : CPU0 calibration...\n", - "2018-10-17 15:36:13,986 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU0\n", - "2018-10-17 15:36:13,988 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:13,989 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:13,991 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:13,992 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:13,995 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:13,996 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:13,998 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:14,247 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu0.json 2>&1\n", - "2018-10-17 15:36:21,839 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:22,077 INFO : lisa.wlgen.rta.RTA : CPU1 calibration...\n", - "2018-10-17 15:36:22,412 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU1\n", - "2018-10-17 15:36:22,414 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:22,415 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:22,417 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:22,418 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:22,419 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:22,420 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:22,423 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:22,655 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu1.json 2>&1\n", - "2018-10-17 15:36:29,180 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:29,415 INFO : lisa.wlgen.rta.RTA : CPU2 calibration...\n", - "2018-10-17 15:36:29,750 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU2\n", - "2018-10-17 15:36:29,752 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:29,753 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:29,755 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:29,756 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:29,757 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:29,758 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:29,760 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:29,999 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu2.json 2>&1\n", - "2018-10-17 15:36:36,525 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:36,764 INFO : lisa.wlgen.rta.RTA : CPU3 calibration...\n", - "2018-10-17 15:36:37,098 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU3\n", - "2018-10-17 15:36:37,099 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:37,101 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:37,102 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:37,103 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:37,104 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:37,105 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:37,106 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:37,349 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu3.json 2>&1\n", - "2018-10-17 15:36:43,872 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:44,111 INFO : lisa.wlgen.rta.RTA : CPU4 calibration...\n", - "2018-10-17 15:36:44,441 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU4\n", - "2018-10-17 15:36:44,443 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:44,445 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:44,446 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:44,447 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:44,448 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:44,449 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:44,450 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:44,691 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu4.json 2>&1\n", - "2018-10-17 15:36:51,048 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:51,287 INFO : lisa.wlgen.rta.RTA : CPU5 calibration...\n", - "2018-10-17 15:36:51,610 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU5\n", - "2018-10-17 15:36:51,612 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:51,613 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:51,615 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:51,616 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:51,617 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:51,618 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:51,620 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:51,862 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu5.json 2>&1\n", - "2018-10-17 15:36:58,222 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:36:58,457 INFO : lisa.wlgen.rta.RTA : CPU6 calibration...\n", - "2018-10-17 15:36:58,784 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU6\n", - "2018-10-17 15:36:58,785 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:36:58,787 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:36:58,788 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:36:58,789 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:36:58,791 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:36:58,792 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:36:58,794 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:36:59,038 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu6.json 2>&1\n", - "2018-10-17 15:37:06,434 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:37:06,677 INFO : lisa.wlgen.rta.RTA : CPU7 calibration...\n", - "2018-10-17 15:37:07,003 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU7\n", - "2018-10-17 15:37:07,004 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:37:07,006 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:37:07,007 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", - "2018-10-17 15:37:07,008 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:37:07,010 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", - "2018-10-17 15:37:07,011 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:37:07,012 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", - "2018-10-17 15:37:07,257 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu7.json 2>&1\n", - "2018-10-17 15:37:13,617 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:37:13,854 INFO : lisa.wlgen.rta.RTA : Target RT-App calibration: {0: 307, 1: 302, 2: 302, 3: 303, 4: 155, 5: 155, 6: 155, 7: 155}\n", - "2018-10-17 15:37:16,922 INFO : lisa.wlgen.rta.RTA : Calibration value: 155\n", - "2018-10-17 15:37:16,924 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", - "2018-10-17 15:37:16,925 INFO : lisa.wlgen.rta.RTA : ------------------------\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2018-10-17 15:37:16,926 INFO : lisa.wlgen.rta.RTA : task [emwm_0], sched: using default policy\n", - "2018-10-17 15:37:16,927 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:37:16,927 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", - "2018-10-17 15:37:16,928 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:37:16,929 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,930 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", - "2018-10-17 15:37:16,931 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", - "2018-10-17 15:37:16,932 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", - "2018-10-17 15:37:16,933 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,934 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", - "2018-10-17 15:37:16,935 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", - "2018-10-17 15:37:16,936 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:37:16,937 INFO : lisa.wlgen.rta.RTA : task [emwm_1], sched: using default policy\n", - "2018-10-17 15:37:16,938 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:37:16,938 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", - "2018-10-17 15:37:16,939 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:37:16,940 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,940 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", - "2018-10-17 15:37:16,941 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", - "2018-10-17 15:37:16,942 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", - "2018-10-17 15:37:16,942 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,943 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", - "2018-10-17 15:37:16,944 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", - "2018-10-17 15:37:16,945 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:37:16,945 INFO : lisa.wlgen.rta.RTA : task [emwm_2], sched: using default policy\n", - "2018-10-17 15:37:16,946 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:37:16,947 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", - "2018-10-17 15:37:16,947 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:37:16,948 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,949 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", - "2018-10-17 15:37:16,950 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", - "2018-10-17 15:37:16,950 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", - "2018-10-17 15:37:16,951 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,952 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", - "2018-10-17 15:37:16,952 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", - "2018-10-17 15:37:16,953 INFO : lisa.wlgen.rta.RTA : ------------------------\n", - "2018-10-17 15:37:16,954 INFO : lisa.wlgen.rta.RTA : task [emwm_3], sched: using default policy\n", - "2018-10-17 15:37:16,954 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", - "2018-10-17 15:37:16,955 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", - "2018-10-17 15:37:16,956 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", - "2018-10-17 15:37:16,956 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,957 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", - "2018-10-17 15:37:16,958 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", - "2018-10-17 15:37:16,958 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", - "2018-10-17 15:37:16,959 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", - "2018-10-17 15:37:16,960 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", - "2018-10-17 15:37:16,962 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", - "2018-10-17 15:37:19,361 INFO : lisa.env.TestEnv : Enabled tracepoints:\n", - "2018-10-17 15:37:19,364 INFO : lisa.env.TestEnv : sched_switch\n", - "2018-10-17 15:37:24,439 INFO : lisa.env.TestEnv : Freezing all tasks except: init,systemd,dbus,sh,ssh,rsyslogd,jbd2\n", - "2018-10-17 15:37:26,635 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_energymodelwakemigration.json 2>&1\n", - "2018-10-17 15:37:35,005 INFO : lisa.wlgen.rta.RTA : Execution complete\n", - "2018-10-17 15:37:36,710 INFO : lisa.env.TestEnv : Un-freezing userspace tasks\n" - ] - } - ], - "source": [ - "bundle = EnergyModelWakeMigration.from_testenv(te)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We now have a **TestBundle** instance. We're free to play around with its data, more specifically to execute some tests related to this data:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED: emwm_1 slack=2.8 %, emwm_0 slack=2.8 %, emwm_3 slack=2.8 %, emwm_2 slack=3.4 %\n" - ] - } - ], - "source": [ - "print(bundle.test_slack())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Whenever possible, we want to expose test margins to the end user. Here, we can change the failure threshold, and for the sake of demonstration we'll set it way too low (and expect a failure)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "FAILED: emwm_1 slack=2.8 %, emwm_0 slack=2.8 %, emwm_3 slack=2.8 %, emwm_2 slack=3.4 %\n" - ] - } - ], - "source": [ - "print(bundle.test_slack(negative_slack_allowed_pct=1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This test also produces a plot, let's run it and have a look" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED: energy threshold=12697.384476751002 bogo-joules, estimated energy=11223.304584691345 bogo-joules\n" - ] - } - ], - "source": [ - "print(bundle.test_task_placement())" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - "\n", - "\n", - "\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "trappy.plotter.plot_trace(bundle.trace.ftrace, execnames=list(bundle.rtapp_profile.keys()))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "image_path = os.path.join(bundle.res_dir, \"expected_placement.png\")\n", - "Image(image_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Offline replaying" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Say someone executed some tests, and ran into some issues. They can create an archive of the results directory and send it your way, and you'll be able to reload it automagically. This also works if you are working on the test code itself, and don't want to re-execute the workload every single time you change the code." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "# Let's just reuse what was generated in the previous run\n", - "archive_dir = bundle.res_dir" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "reloaded_bundle = EnergyModelWakeMigration.from_dir(archive_dir)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Just to prove we're not cheating!\n", - "reloaded_bundle == bundle" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "PASSED: energy threshold=12697.384476751002 bogo-joules, estimated energy=11223.304584691345 bogo-joules\n" - ] - } - ], - "source": [ - "print(reloaded_bundle.test_task_placement())" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/ipynb/examples/typical_experiment.ipynb b/ipynb/examples/typical_experiment.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..d543a00431ffc3fc2985226d8887bc565e24ac9f --- /dev/null +++ b/ipynb/examples/typical_experiment.ipynb @@ -0,0 +1,3456 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Typical LISA experiment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook shows a typical LISA-use case:\n", + "\n", + "* Connecting to a target\n", + "* Configuring an rt-app workload\n", + "* Collecting a trace while executing a workload\n", + "* Displaying the trace\n", + "* Analysing the trace\n", + "\n", + "It can serve as a template for different kind of experiments, - you could only change the workload to execute & the trace events to collect" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:03:06,789 INFO : root : Using LISA logging configuration:\n", + "2018-12-12 18:03:06,790 INFO : root : /data/work/lisa/logging.conf\n" + ] + } + ], + "source": [ + "import logging\n", + "from lisa.utils import setup_logging\n", + "setup_logging()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Target configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Target communication is abstracted away under a **TestEnv** class. We're going to create an instance of it and that'll let us run whatever experiment we want on a given target.\n", + "\n", + "Relevant documentation:\n", + "* **TestEnv**: https://lisa-linux-integrated-system-analysis.readthedocs.io/en/next/internals.html#lisa.env.TestEnv\n", + "* **TargetConf**: https://lisa-linux-integrated-system-analysis.readthedocs.io/en/next/internals.html#lisa.env.TargetConf" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:03:06,813 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/Grammar.txt\n", + "2018-12-12 18:03:06,836 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/PatternGrammar.txt\n" + ] + } + ], + "source": [ + "from lisa.env import TestEnv, TargetConf" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "target_conf = TargetConf({\n", + " \"kind\" : \"linux\",\n", + " \"name\" : \"hikey960\",\n", + " \n", + " \"host\": \"192.168.0.1\",\n", + " \"username\" : \"root\",\n", + " \"password\" : \"root\"\n", + "})" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:03:07,573 INFO : lisa.env.TestEnv : Target configuration:\n", + "|- kind from user (str): linux\n", + "|- username from user (str): root\n", + "|- name from user (str): hikey960\n", + "|- host from user (str): 192.168.0.1\n", + "|- password from user (str): root\n", + "+- devlib:\n", + " +- platform:\n", + " |- class from default (str): devlib.platform.Platform\n", + "+- ftrace:\n", + " |- buffsize from default (int): 10240\n", + "2018-12-12 18:03:07,642 INFO : lisa.env.TestEnv : User-defined platform information:\n", + "|- name from target-conf (str): hikey960\n", + "2018-12-12 18:03:07,678 INFO : lisa.env.TestEnv : linux hikey960 target connection settings:\n", + "2018-12-12 18:03:07,679 INFO : lisa.env.TestEnv : username : root\n", + "2018-12-12 18:03:07,680 INFO : lisa.env.TestEnv : port : 22\n", + "2018-12-12 18:03:07,680 INFO : lisa.env.TestEnv : host : 192.168.0.1\n", + "2018-12-12 18:03:07,681 INFO : lisa.env.TestEnv : password : root\n", + "2018-12-12 18:03:07,703 INFO : lisa.env.TestEnv : Devlib modules to load: bl, cgroups, cpufreq, cpuidle, devfreq, fastboot, gem5stats, gpufreq, hotplug, hwmon, mbed-fan, odroidxu3-fan, sched, thermal\n", + "2018-12-12 18:03:12,394 WARNING : LinuxTarget : Module devfreq is not supported by the target\n", + "2018-12-12 18:03:12,397 WARNING : LinuxTarget : Module fastboot is not supported by the target\n", + "2018-12-12 18:03:12,398 WARNING : LinuxTarget : Module gem5stats is not supported by the target\n", + "2018-12-12 18:03:12,566 WARNING : LinuxTarget : Module gpufreq is not supported by the target\n", + "2018-12-12 18:03:13,258 WARNING : LinuxTarget : Module odroidxu3-fan is not supported by the target\n", + "2018-12-12 18:03:15,254 INFO : CGroups : Available controllers:\n", + "2018-12-12 18:03:15,779 INFO : CGroups : cpuset : /root/devlib-target/cgroups/devlib_cgh6\n", + "2018-12-12 18:03:16,298 INFO : CGroups : cpu : /root/devlib-target/cgroups/devlib_cgh4\n", + "2018-12-12 18:03:16,820 INFO : CGroups : cpuacct : /root/devlib-target/cgroups/devlib_cgh4\n", + "2018-12-12 18:03:17,347 INFO : CGroups : blkio : /root/devlib-target/cgroups/devlib_cgh9\n", + "2018-12-12 18:03:17,865 INFO : CGroups : memory : /root/devlib-target/cgroups/devlib_cgh2\n", + "2018-12-12 18:03:18,390 INFO : CGroups : devices : /root/devlib-target/cgroups/devlib_cgh7\n", + "2018-12-12 18:03:18,916 INFO : CGroups : freezer : /root/devlib-target/cgroups/devlib_cgh3\n", + "2018-12-12 18:03:19,447 INFO : CGroups : perf_event : /root/devlib-target/cgroups/devlib_cgh5\n", + "2018-12-12 18:03:19,972 INFO : CGroups : hugetlb : /root/devlib-target/cgroups/devlib_cgh10\n", + "2018-12-12 18:03:20,490 INFO : CGroups : pids : /root/devlib-target/cgroups/devlib_cgh8\n", + "2018-12-12 18:03:20,664 WARNING : lisa.env.TestEnv : Failed to initialized \"devfreq\" devlib Module\n", + "2018-12-12 18:03:20,665 WARNING : lisa.env.TestEnv : Failed to initialized \"fastboot\" devlib Module\n", + "2018-12-12 18:03:20,666 WARNING : lisa.env.TestEnv : Failed to initialized \"gem5stats\" devlib Module\n", + "2018-12-12 18:03:20,667 WARNING : lisa.env.TestEnv : Failed to initialized \"gpufreq\" devlib Module\n", + "2018-12-12 18:03:20,668 WARNING : lisa.env.TestEnv : Failed to initialized \"mbed-fan\" devlib Module\n", + "2018-12-12 18:03:20,669 WARNING : lisa.env.TestEnv : Failed to initialized \"odroidxu3-fan\" devlib Module\n", + "2018-12-12 18:03:20,670 INFO : lisa.platforms.platinfo.PlatformInfo : Attempting to read energy model from target\n", + "2018-12-12 18:03:21,175 INFO : lisa.energy_model.EnergyModel.EMReader : Attempting to load EM using from_simplifiedEM_target\n", + "2018-12-12 18:03:26,512 INFO : lisa.env.TestEnv : Effective platform information:\n", + "|- os from target (str): linux\n", + "|- freqs from target (dict): {0: [533000, 999000, 1402000, 1709000, 1844000], 1: [533000, 999000, 1402000, 1709000, 1844000], 2: [533000, 999000, 1402000, 1709000, 1844000], 3: [533000, 999000, 1402000, 1709000, 1844000], 4: [903000, 1421000, 1805000, 2112000, 2362000], 5: [903000, 1421000, 1805000, 2112000, 2362000], 6: [903000, 1421000, 1805000, 2112000, 2362000], 7: [903000, 1421000, 1805000, 2112000, 2362000]}\n", + "|- name from target-conf (str): hikey960\n", + "|- cpu-capacities from target (dict): {0: 462, 1: 462, 2: 462, 3: 462, 4: 1024, 5: 1024, 6: 1024, 7: 1024}\n", + "|- abi from target (str): arm64\n", + "|- cpus-count from target (int): 8\n", + "|- freq-domains from target (list): [[0, 1, 2, 3], [4, 5, 6, 7]]\n", + "|- nrg-model from target (EnergyModel): \n", + "|- kernel-version from target (KernelVersion): 4.19.0-rc5-00347-ga58f958 7 SMP PREEMPT Tue Dec 11 14:03:35 GMT 2018\n", + "+- rtapp:\n", + " |- calib from target (DeferredValue): \n" + ] + } + ], + "source": [ + "te = TestEnv(target_conf)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up an rt-app workload" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "rt-app is very convenient for scheduler experiments, and the majority of the tests within LISA rely on it. Here we're going to create a somewhat useless workload just to show off the API.\n", + "\n", + "Relevant documentation:\n", + "* **rt-app**: https://github.com/scheduler-tools/rt-app\n", + "* **rt-app LISA class**: https://lisa-linux-integrated-system-analysis.readthedocs.io/en/next/wlgen.html#lisa.wlgen.rta.RTA\n", + "* **Periodic class**: https://lisa-linux-integrated-system-analysis.readthedocs.io/en/next/wlgen.html#lisa.wlgen.rta.Periodic" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.wlgen.rta import RTA, Periodic" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "rtapp_profile = {}\n", + "\n", + "for cpu in range(te.target.number_of_cpus):\n", + " for i in range(3):\n", + " rtapp_profile[\"task_{}_{}\".format(cpu, i)] = Periodic(duty_cycle_pct=20)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "rt-app needs some calibration information (20% duty cycle isn't the same amount of work on all platforms!). It can be manually specified like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def provide_calibration(calibration):\n", + " te.plat_info[\"rtapp\"].add_src(\"user\", {\"calib\" : calibration})" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment if you want to use this\n", + "# provide_calibration({0: 307, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, it is automatically collected when first creating an rt-app workload if it is not specified, so you can forego the above step and let the calibration happen on-demand:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:03:26,666 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181212_180307.573496/experiment_wload-20181212_180326.666741\n", + "2018-12-12 18:03:37,098 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181212_180307.573496/rta_calib-20181212_180337.097744\n", + "2018-12-12 18:03:37,261 INFO : lisa.wlgen.rta.RTA : CPU0 calibration...\n", + "2018-12-12 18:03:37,587 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU0\n", + "2018-12-12 18:03:37,588 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:03:37,590 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:03:37,591 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:03:37,592 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:03:37,593 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:03:37,594 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:03:37,595 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:03:37,836 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu0.json 2>&1\n", + "2018-12-12 18:03:44,361 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:03:44,634 INFO : lisa.wlgen.rta.RTA : CPU1 calibration...\n", + "2018-12-12 18:03:44,958 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU1\n", + "2018-12-12 18:03:44,960 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:03:44,961 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:03:44,962 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:03:44,963 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:03:44,964 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:03:44,965 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:03:44,966 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:03:45,200 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu1.json 2>&1\n", + "2018-12-12 18:03:51,719 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:03:51,987 INFO : lisa.wlgen.rta.RTA : CPU2 calibration...\n", + "2018-12-12 18:03:52,314 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU2\n", + "2018-12-12 18:03:52,316 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:03:52,317 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:03:52,318 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:03:52,319 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:03:52,321 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:03:52,322 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:03:52,323 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:03:52,566 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu2.json 2>&1\n", + "2018-12-12 18:03:59,087 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:03:59,358 INFO : lisa.wlgen.rta.RTA : CPU3 calibration...\n", + "2018-12-12 18:03:59,686 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU3\n", + "2018-12-12 18:03:59,687 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:03:59,689 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:03:59,690 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:03:59,691 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:03:59,692 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:03:59,693 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:03:59,694 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:03:59,933 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu3.json 2>&1\n", + "2018-12-12 18:04:06,454 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:04:06,725 INFO : lisa.wlgen.rta.RTA : CPU4 calibration...\n", + "2018-12-12 18:04:07,051 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU4\n", + "2018-12-12 18:04:07,052 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:04:07,054 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:07,055 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:04:07,056 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:07,058 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:07,059 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:07,060 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:04:07,299 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu4.json 2>&1\n", + "2018-12-12 18:04:13,658 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:04:13,923 INFO : lisa.wlgen.rta.RTA : CPU5 calibration...\n", + "2018-12-12 18:04:14,250 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU5\n", + "2018-12-12 18:04:14,251 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:04:14,253 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:14,254 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:04:14,255 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:14,256 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:14,257 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:14,258 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:04:14,501 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu5.json 2>&1\n", + "2018-12-12 18:04:20,866 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:04:21,132 INFO : lisa.wlgen.rta.RTA : CPU6 calibration...\n", + "2018-12-12 18:04:21,457 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU6\n", + "2018-12-12 18:04:21,458 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:04:21,460 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:21,461 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:04:21,462 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:21,463 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:21,464 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:21,465 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:04:21,695 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu6.json 2>&1\n", + "2018-12-12 18:04:28,055 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:04:28,317 INFO : lisa.wlgen.rta.RTA : CPU7 calibration...\n", + "2018-12-12 18:04:28,643 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU7\n", + "2018-12-12 18:04:28,644 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:04:28,646 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:28,647 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:04:28,648 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:28,649 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:28,650 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:28,650 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:04:28,881 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu7.json 2>&1\n", + "2018-12-12 18:04:35,242 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:04:35,511 INFO : lisa.wlgen.rta.RTA : Target RT-App calibration: {0: 307, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155}\n", + "2018-12-12 18:04:46,980 INFO : lisa.wlgen.rta.RTA : Calibration value: 155\n", + "2018-12-12 18:04:46,981 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:04:46,982 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:46,983 INFO : lisa.wlgen.rta.RTA : task [task_6_1], sched: using default policy\n", + "2018-12-12 18:04:46,983 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:46,984 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:46,985 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:46,986 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:46,987 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:46,988 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:46,988 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:46,989 INFO : lisa.wlgen.rta.RTA : task [task_2_2], sched: using default policy\n", + "2018-12-12 18:04:46,990 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:46,990 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:46,991 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:46,992 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:46,993 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:46,994 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:46,995 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:46,995 INFO : lisa.wlgen.rta.RTA : task [task_0_0], sched: using default policy\n", + "2018-12-12 18:04:46,996 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:46,997 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:46,998 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:46,999 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,000 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,000 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,001 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,003 INFO : lisa.wlgen.rta.RTA : task [task_3_1], sched: using default policy\n", + "2018-12-12 18:04:47,004 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,005 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,006 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,006 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,007 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,008 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,010 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,011 INFO : lisa.wlgen.rta.RTA : task [task_4_1], sched: using default policy\n", + "2018-12-12 18:04:47,012 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,012 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,013 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,014 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,016 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,017 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,017 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,018 INFO : lisa.wlgen.rta.RTA : task [task_5_2], sched: using default policy\n", + "2018-12-12 18:04:47,019 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,020 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,020 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,021 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,022 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,022 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,023 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,024 INFO : lisa.wlgen.rta.RTA : task [task_6_2], sched: using default policy\n", + "2018-12-12 18:04:47,024 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,025 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,025 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,026 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,026 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,028 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,030 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,031 INFO : lisa.wlgen.rta.RTA : task [task_1_1], sched: using default policy\n", + "2018-12-12 18:04:47,032 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,034 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,036 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,037 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,040 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,041 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,041 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,042 INFO : lisa.wlgen.rta.RTA : task [task_4_2], sched: using default policy\n", + "2018-12-12 18:04:47,042 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,043 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,044 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,045 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,045 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,046 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,047 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,047 INFO : lisa.wlgen.rta.RTA : task [task_2_1], sched: using default policy\n", + "2018-12-12 18:04:47,048 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,048 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,049 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,050 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,051 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,051 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,052 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,052 INFO : lisa.wlgen.rta.RTA : task [task_5_0], sched: using default policy\n", + "2018-12-12 18:04:47,053 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,054 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,055 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,055 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,056 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,057 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,057 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,058 INFO : lisa.wlgen.rta.RTA : task [task_7_2], sched: using default policy\n", + "2018-12-12 18:04:47,058 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,059 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,060 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,060 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:04:47,061 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,061 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,062 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,063 INFO : lisa.wlgen.rta.RTA : task [task_6_0], sched: using default policy\n", + "2018-12-12 18:04:47,063 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,064 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,064 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,065 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,066 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,066 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,067 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,067 INFO : lisa.wlgen.rta.RTA : task [task_1_2], sched: using default policy\n", + "2018-12-12 18:04:47,068 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,069 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,069 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,070 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,071 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,071 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,072 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,073 INFO : lisa.wlgen.rta.RTA : task [task_5_1], sched: using default policy\n", + "2018-12-12 18:04:47,073 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,074 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,074 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,075 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,076 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,077 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,077 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,078 INFO : lisa.wlgen.rta.RTA : task [task_3_2], sched: using default policy\n", + "2018-12-12 18:04:47,079 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,080 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,081 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,082 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,084 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,085 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,086 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,087 INFO : lisa.wlgen.rta.RTA : task [task_7_1], sched: using default policy\n", + "2018-12-12 18:04:47,088 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,089 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,090 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,090 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,091 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,093 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,094 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,095 INFO : lisa.wlgen.rta.RTA : task [task_0_1], sched: using default policy\n", + "2018-12-12 18:04:47,096 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,097 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,098 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,099 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,100 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,101 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,103 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,104 INFO : lisa.wlgen.rta.RTA : task [task_1_0], sched: using default policy\n", + "2018-12-12 18:04:47,104 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,105 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,106 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,107 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,107 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,108 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,109 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,109 INFO : lisa.wlgen.rta.RTA : task [task_7_0], sched: using default policy\n", + "2018-12-12 18:04:47,110 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,111 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,112 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,112 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,113 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,113 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,114 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,115 INFO : lisa.wlgen.rta.RTA : task [task_3_0], sched: using default policy\n", + "2018-12-12 18:04:47,115 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,116 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,117 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,117 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,118 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,119 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,120 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,120 INFO : lisa.wlgen.rta.RTA : task [task_0_2], sched: using default policy\n", + "2018-12-12 18:04:47,121 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,122 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,123 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,123 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,124 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,124 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,125 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,126 INFO : lisa.wlgen.rta.RTA : task [task_4_0], sched: using default policy\n", + "2018-12-12 18:04:47,126 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:04:47,127 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,128 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,128 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,129 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,130 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-12 18:04:47,130 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:04:47,131 INFO : lisa.wlgen.rta.RTA : task [task_2_0], sched: using default policy\n", + "2018-12-12 18:04:47,132 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:04:47,132 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:04:47,133 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:04:47,134 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-12 18:04:47,134 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-12 18:04:47,135 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n" + ] + } + ], + "source": [ + "wload = RTA.by_profile(te, \"experiment_wload\", rtapp_profile)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running the workload" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from devlib.trace.ftrace import FtraceCollector" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need to specify the trace events we want to record. We could list what's available like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['sched:sched_util_est_cpu', 'sched:sched_util_est_task', 'sched:sched_load_tg', 'sched:sched_load_se', 'sched:sched_load_cfs_rq', 'sched:sched_wake_idle_without_ipi', 'sched:sched_swap_numa', 'sched:sched_stick_numa', 'sched:sched_move_numa', 'sched:sched_pi_setprio', 'sched:sched_stat_runtime', 'sched:sched_stat_blocked', 'sched:sched_stat_iowait', 'sched:sched_stat_sleep', 'sched:sched_stat_wait', 'sched:sched_process_exec', 'sched:sched_process_fork', 'sched:sched_process_wait', 'sched:sched_wait_task', 'sched:sched_process_exit', 'sched:sched_process_free', 'sched:sched_migrate_task', 'sched:sched_switch', 'sched:sched_wakeup_new', 'sched:sched_wakeup', 'sched:sched_waking', 'sched:sched_kthread_stop_ret', 'sched:sched_kthread_stop']\n" + ] + } + ], + "source": [ + "available_events = target.execute(\"cat /sys/kernel/debug/tracing/available_events\").splitlines()\n", + "\n", + "# That's gonna be a pretty big list, let's focus on the scheduler events\n", + "sched_events = [event for event in available_events if event.startswith(\"sched:\")]\n", + "print(sched_events)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's just collect the base events required to plot task scheduling:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "events = [\n", + " \"sched_switch\",\n", + " \"sched_wakeup\",\n", + " \"sched_wakeup_new\"\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now we can actually record traces while running our workload:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:04:52,602 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/experiment_wload.json 2>&1\n", + "2018-12-12 18:04:53,834 INFO : lisa.wlgen.rta.RTA : Execution complete\n" + ] + } + ], + "source": [ + "ftrace = FtraceCollector(target, events=events, buffer_size=10240)\n", + "\n", + "# This is just nifty Python syntactic sugar that starts/stops\n", + "# the recording for us. You could just do:\n", + "# ftrace.start()\n", + "# wload.run()\n", + "# ftrace.stop()\n", + "with ftrace:\n", + " wload.run()\n", + " \n", + "trace_path = os.path.join(wload.res_dir, \"trace.dat\")\n", + "ftrace.get_trace(trace_path) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading up the trace" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have a Trace class that lets us easily access trace events. It can also do some post-processing to provide different kinds of analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.trace import Trace" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We also save some platform information (number of CPUs, available frequencies, kernel version...) that comes in handy for doing some analysis:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "|- os from target (str): linux\n", + "|- freqs from target (dict): {0: [533000, 999000, 1402000, 1709000, 1844000], 1: [533000, 999000, 1402000, 1709000, 1844000], 2: [533000, 999000, 1402000, 1709000, 1844000], 3: [533000, 999000, 1402000, 1709000, 1844000], 4: [903000, 1421000, 1805000, 2112000, 2362000], 5: [903000, 1421000, 1805000, 2112000, 2362000], 6: [903000, 1421000, 1805000, 2112000, 2362000], 7: [903000, 1421000, 1805000, 2112000, 2362000]}\n", + "|- name from target-conf (str): hikey960\n", + "|- cpu-capacities from target (dict): {0: 462, 1: 462, 2: 462, 3: 462, 4: 1024, 5: 1024, 6: 1024, 7: 1024}\n", + "|- abi from target (str): arm64\n", + "|- cpus-count from target (int): 8\n", + "|- freq-domains from target (list): [[0, 1, 2, 3], [4, 5, 6, 7]]\n", + "|- nrg-model from target (EnergyModel): \n", + "|- kernel-version from target (KernelVersion): 4.19.0-rc5-00347-ga58f958 7 SMP PREEMPT Tue Dec 11 14:03:35 GMT 2018\n", + "+- rtapp:\n", + " |- calib from target (dict): {0: 307, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155}\n" + ] + } + ], + "source": [ + "print(te.plat_info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can pass the platform info directly from the **TestEnv**:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "trace = Trace(wload.res_dir, te.plat_info, events=events)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... But it's a good idea to save it on the disk so that you can re-run whatever analysis code you want several months down the line after the platform was lost in a tragic fire.\n", + "\n", + "It's why we save this information somewhere instead of polling the target when we want to use them - we can run analysis code offline.\n", + "\n", + "Here we show how to save to/restore this platform information from the disk." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "plat_info_path = os.path.join(wload.res_dir, \"platinfo.yaml\")\n", + "te.plat_info.to_yaml_map(plat_info_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.platforms.platinfo import PlatformInfo" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "plat_info = PlatformInfo.from_yaml_map(plat_info_path)\n", + "trace = Trace(wload.res_dir, plat_info, events=events)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Looking at the trace" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One of the first things you can do with that trace is display it in the Notebook. The inline plotter is not as feature-complete as Kernelshark, but it's useful as a quick way to plot the trace." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "from trappy.plotter import plot_trace" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_trace(trace.ftrace)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Kernelshark is still an option:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "version = 6\n", + "trace-cmd: No such file or directory\n", + " [xhci-hcd:xhci_urb_giveback] bad op token {\n", + " [xhci-hcd:xhci_urb_enqueue] bad op token {\n", + " [xhci-hcd:xhci_urb_dequeue] bad op token {\n", + " [xhci-hcd:xhci_setup_device_slot] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_ring_free] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_ring_expansion] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_ring_alloc] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_queue_trb] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_inc_enq] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_inc_deq] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_hub_status_data] function xhci_decode_portsc not defined\n", + " [xhci-hcd:xhci_handle_transfer] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_handle_port_status] function xhci_decode_portsc not defined\n", + " [xhci-hcd:xhci_handle_event] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_handle_command] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_handle_cmd_stop_ep] function xhci_decode_ep_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_set_deq_ep] function xhci_decode_ep_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_set_deq] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_reset_ep] function xhci_decode_ep_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_reset_dev] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_disable_slot] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_config_ep] function xhci_decode_ep_context not defined\n", + " [xhci-hcd:xhci_handle_cmd_addr_dev] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_get_port_status] function xhci_decode_portsc not defined\n", + " [xhci-hcd:xhci_free_dev] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_discover_or_reset_device] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_dbc_handle_transfer] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_dbc_handle_event] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_dbc_gadget_ep_queue] function xhci_ring_type_string not defined\n", + " [xhci-hcd:xhci_configure_endpoint] function xhci_decode_slot_context not defined\n", + " [xhci-hcd:xhci_alloc_dev] function xhci_decode_slot_context 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", + " unknown op '~'\n", + " Error: expected type 5 but read 0\n", + " Error: expected type 4 but read 0\n", + " [ufs:ufshcd_upiu] function sizeof not defined\n", + " Error: expected type 5 but read 0\n", + " [thermal_power_allocator:thermal_power_allocator] function __print_array not defined\n", + " [thermal:thermal_power_cpu_get_power] function __print_array not defined\n", + " [ras:mc_event] function mc_event_error_type not defined\n", + " [ras:aer_event] function __print_array not defined\n", + " Error: expected type 4 but read 0\n", + " [libata:ata_qc_issue] function libata_trace_parse_subcmd 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", + " unknown op '~'\n", + " Error: expected type 5 but read 0\n", + " Error: expected type 4 but read 0\n", + " [dwc3:dwc3_prepare_trb] bad op token {\n", + " [dwc3:dwc3_gadget_generic_cmd] function dwc3_gadget_generic_cmd_string not defined\n", + " [dwc3:dwc3_gadget_ep_cmd] function dwc3_gadget_ep_cmd_string not defined\n", + " [dwc3:dwc3_event] function dwc3_decode_event not defined\n", + " [dwc3:dwc3_ctrl_req] function dwc3_decode_ctrl not defined\n", + " [dwc3:dwc3_complete_trb] bad op token {\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n", + "\n", + "(kernelshark:23483): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkStatusbar'\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_statusbar_push: assertion 'GTK_IS_STATUSBAR (statusbar)' failed\n", + "\n", + "(kernelshark:23483): Gtk-CRITICAL **: IA__gtk_widget_show: assertion 'GTK_IS_WIDGET (widget)' failed\n" + ] + } + ], + "source": [ + "!kernelshark {trace_path}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Analysing the trace" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Relevant documentation: https://lisa-linux-integrated-system-analysis.readthedocs.io/en/next/analysis.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reading trace events" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
__comm__cpu__line__pidnext_commnext_pidnext_prioprev_commprev_pidprev_prioprev_state
Time
0.000030<...>7130543swapper/70120trace-cmd3054312064
0.000063<idle>730kworker/7:230176120swapper/701201
0.000191kworker/7:27430176swapper/70120kworker/7:230176120256
0.000242<idle>650bash29982120swapper/601201
0.000921bash6829982kworker/6:330056120bash29982120256
0.000956kworker/6:36930056bash29982120kworker/6:330056120256
0.001136<idle>5100kworker/u16:229945120swapper/501201
0.001204<...>51129945swapper/50120kworker/u16:229945120256
0.001435bash61329982swapper/60120bash299821202
0.001624<idle>5140kworker/u16:229945120swapper/501201
0.001655<...>51529945swapper/50120kworker/u16:229945120256
0.002190<idle>3170sshd29973120swapper/301201
0.002260<idle>6190rcu_preempt10120swapper/601201
0.002286rcu_preempt62010swapper/60120rcu_preempt10120256
0.002762<idle>0220kworker/0:118292120swapper/001201
0.002966kworker/0:102418292ksoftirqd/09120kworker/0:118292120256
0.003048ksoftirqd/00259kworker/0:118292120ksoftirqd/091202
0.003333sshd32629973swapper/30120sshd299731202
0.003649kworker/0:102818292ksoftirqd/09120kworker/0:118292120256
0.003834ksoftirqd/00299kworker/0:118292120ksoftirqd/091202
0.003920kworker/0:103118292ksoftirqd/09120kworker/0:118292120256
0.003976ksoftirqd/00329kworker/0:118292120ksoftirqd/091202
0.004073kworker/0:103318292swapper/00120kworker/0:1182921204
0.006578<idle>4350rcu_sched11120swapper/401201
0.006617rcu_sched43611swapper/40120rcu_sched11120256
0.006791<idle>6380rcu_preempt10120swapper/601201
0.006819rcu_preempt63910swapper/60120rcu_preempt10120256
0.007133<idle>6410rcu_preempt10120swapper/601201
0.007171rcu_preempt64210swapper/60120rcu_preempt10120256
0.014548<idle>4450kworker/4:129029120swapper/401201
....................................
9.608546kworker/0:103778818292ksoftirqd/09120kworker/0:118292120256
9.608601ksoftirqd/00377899kworker/0:118292120ksoftirqd/091202
9.608704kworker/0:103779018292swapper/00120kworker/0:1182921204
9.623991<idle>0377930ksoftirqd/09120swapper/001201
9.624434ksoftirqd/00377959kworker/0:118292120ksoftirqd/091202
9.624633kworker/0:103779718292ksoftirqd/09120kworker/0:118292120256
9.624690<idle>1377980sshd29973120swapper/101201
9.624694ksoftirqd/00377999kworker/0:118292120ksoftirqd/091202
9.625056kworker/0:103780118292ksoftirqd/09120kworker/0:118292120256
9.625109ksoftirqd/00378029kworker/0:118292120ksoftirqd/091202
9.625192kworker/0:103780418292ksoftirqd/09120kworker/0:118292120256
9.625248ksoftirqd/00378059kworker/0:118292120ksoftirqd/091202
9.625525kworker/0:103780618292swapper/00120kworker/0:1182921204
9.625534sshd13780729973swapper/10120sshd299731202
9.625596<idle>0378090kworker/0:329984120swapper/001201
9.625703kworker/0:303781029984swapper/00120kworker/0:329984120256
9.627280<idle>7378120kworker/u16:130005120swapper/701201
9.627428kworker/u16:173781430005swapper/70120kworker/u16:130005120256
9.628489<idle>6378150bash29982120swapper/601201
9.631280<idle>7378170kworker/u16:130005120swapper/701201
9.631357kworker/u16:173781830005swapper/70120kworker/u16:130005120256
9.632357<idle>1378200sshd29973120swapper/101201
9.633065<idle>4378220bash30858120swapper/401201
9.633134bash63782329982swapper/60120bash299821202
9.633261sshd13782429973swapper/10120sshd299731202
9.635390<idle>2378270kworker/2:312627120swapper/201201
9.635522kworker/2:323782812627rcu_preempt10120kworker/2:312627120256
9.635860rcu_preempt23782910swapper/20120rcu_preempt10120256
9.635913<idle>2378310kworker/2:312627120swapper/201201
9.636188kworker/2:323783212627swapper/20120kworker/2:312627120256
\n", + "

23560 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " __comm __cpu __line __pid next_comm next_pid \\\n", + "Time \n", + "0.000030 <...> 7 1 30543 swapper/7 0 \n", + "0.000063 7 3 0 kworker/7:2 30176 \n", + "0.000191 kworker/7:2 7 4 30176 swapper/7 0 \n", + "0.000242 6 5 0 bash 29982 \n", + "0.000921 bash 6 8 29982 kworker/6:3 30056 \n", + "0.000956 kworker/6:3 6 9 30056 bash 29982 \n", + "0.001136 5 10 0 kworker/u16:2 29945 \n", + "0.001204 <...> 5 11 29945 swapper/5 0 \n", + "0.001435 bash 6 13 29982 swapper/6 0 \n", + "0.001624 5 14 0 kworker/u16:2 29945 \n", + "0.001655 <...> 5 15 29945 swapper/5 0 \n", + "0.002190 3 17 0 sshd 29973 \n", + "0.002260 6 19 0 rcu_preempt 10 \n", + "0.002286 rcu_preempt 6 20 10 swapper/6 0 \n", + "0.002762 0 22 0 kworker/0:1 18292 \n", + "0.002966 kworker/0:1 0 24 18292 ksoftirqd/0 9 \n", + "0.003048 ksoftirqd/0 0 25 9 kworker/0:1 18292 \n", + "0.003333 sshd 3 26 29973 swapper/3 0 \n", + "0.003649 kworker/0:1 0 28 18292 ksoftirqd/0 9 \n", + "0.003834 ksoftirqd/0 0 29 9 kworker/0:1 18292 \n", + "0.003920 kworker/0:1 0 31 18292 ksoftirqd/0 9 \n", + "0.003976 ksoftirqd/0 0 32 9 kworker/0:1 18292 \n", + "0.004073 kworker/0:1 0 33 18292 swapper/0 0 \n", + "0.006578 4 35 0 rcu_sched 11 \n", + "0.006617 rcu_sched 4 36 11 swapper/4 0 \n", + "0.006791 6 38 0 rcu_preempt 10 \n", + "0.006819 rcu_preempt 6 39 10 swapper/6 0 \n", + "0.007133 6 41 0 rcu_preempt 10 \n", + "0.007171 rcu_preempt 6 42 10 swapper/6 0 \n", + "0.014548 4 45 0 kworker/4:1 29029 \n", + "... ... ... ... ... ... ... \n", + "9.608546 kworker/0:1 0 37788 18292 ksoftirqd/0 9 \n", + "9.608601 ksoftirqd/0 0 37789 9 kworker/0:1 18292 \n", + "9.608704 kworker/0:1 0 37790 18292 swapper/0 0 \n", + "9.623991 0 37793 0 ksoftirqd/0 9 \n", + "9.624434 ksoftirqd/0 0 37795 9 kworker/0:1 18292 \n", + "9.624633 kworker/0:1 0 37797 18292 ksoftirqd/0 9 \n", + "9.624690 1 37798 0 sshd 29973 \n", + "9.624694 ksoftirqd/0 0 37799 9 kworker/0:1 18292 \n", + "9.625056 kworker/0:1 0 37801 18292 ksoftirqd/0 9 \n", + "9.625109 ksoftirqd/0 0 37802 9 kworker/0:1 18292 \n", + "9.625192 kworker/0:1 0 37804 18292 ksoftirqd/0 9 \n", + "9.625248 ksoftirqd/0 0 37805 9 kworker/0:1 18292 \n", + "9.625525 kworker/0:1 0 37806 18292 swapper/0 0 \n", + "9.625534 sshd 1 37807 29973 swapper/1 0 \n", + "9.625596 0 37809 0 kworker/0:3 29984 \n", + "9.625703 kworker/0:3 0 37810 29984 swapper/0 0 \n", + "9.627280 7 37812 0 kworker/u16:1 30005 \n", + "9.627428 kworker/u16:1 7 37814 30005 swapper/7 0 \n", + "9.628489 6 37815 0 bash 29982 \n", + "9.631280 7 37817 0 kworker/u16:1 30005 \n", + "9.631357 kworker/u16:1 7 37818 30005 swapper/7 0 \n", + "9.632357 1 37820 0 sshd 29973 \n", + "9.633065 4 37822 0 bash 30858 \n", + "9.633134 bash 6 37823 29982 swapper/6 0 \n", + "9.633261 sshd 1 37824 29973 swapper/1 0 \n", + "9.635390 2 37827 0 kworker/2:3 12627 \n", + "9.635522 kworker/2:3 2 37828 12627 rcu_preempt 10 \n", + "9.635860 rcu_preempt 2 37829 10 swapper/2 0 \n", + "9.635913 2 37831 0 kworker/2:3 12627 \n", + "9.636188 kworker/2:3 2 37832 12627 swapper/2 0 \n", + "\n", + " next_prio prev_comm prev_pid prev_prio prev_state \n", + "Time \n", + "0.000030 120 trace-cmd 30543 120 64 \n", + "0.000063 120 swapper/7 0 120 1 \n", + "0.000191 120 kworker/7:2 30176 120 256 \n", + "0.000242 120 swapper/6 0 120 1 \n", + "0.000921 120 bash 29982 120 256 \n", + "0.000956 120 kworker/6:3 30056 120 256 \n", + "0.001136 120 swapper/5 0 120 1 \n", + "0.001204 120 kworker/u16:2 29945 120 256 \n", + "0.001435 120 bash 29982 120 2 \n", + "0.001624 120 swapper/5 0 120 1 \n", + "0.001655 120 kworker/u16:2 29945 120 256 \n", + "0.002190 120 swapper/3 0 120 1 \n", + "0.002260 120 swapper/6 0 120 1 \n", + "0.002286 120 rcu_preempt 10 120 256 \n", + "0.002762 120 swapper/0 0 120 1 \n", + "0.002966 120 kworker/0:1 18292 120 256 \n", + "0.003048 120 ksoftirqd/0 9 120 2 \n", + "0.003333 120 sshd 29973 120 2 \n", + "0.003649 120 kworker/0:1 18292 120 256 \n", + "0.003834 120 ksoftirqd/0 9 120 2 \n", + "0.003920 120 kworker/0:1 18292 120 256 \n", + "0.003976 120 ksoftirqd/0 9 120 2 \n", + "0.004073 120 kworker/0:1 18292 120 4 \n", + "0.006578 120 swapper/4 0 120 1 \n", + "0.006617 120 rcu_sched 11 120 256 \n", + "0.006791 120 swapper/6 0 120 1 \n", + "0.006819 120 rcu_preempt 10 120 256 \n", + "0.007133 120 swapper/6 0 120 1 \n", + "0.007171 120 rcu_preempt 10 120 256 \n", + "0.014548 120 swapper/4 0 120 1 \n", + "... ... ... ... ... ... \n", + "9.608546 120 kworker/0:1 18292 120 256 \n", + "9.608601 120 ksoftirqd/0 9 120 2 \n", + "9.608704 120 kworker/0:1 18292 120 4 \n", + "9.623991 120 swapper/0 0 120 1 \n", + "9.624434 120 ksoftirqd/0 9 120 2 \n", + "9.624633 120 kworker/0:1 18292 120 256 \n", + "9.624690 120 swapper/1 0 120 1 \n", + "9.624694 120 ksoftirqd/0 9 120 2 \n", + "9.625056 120 kworker/0:1 18292 120 256 \n", + "9.625109 120 ksoftirqd/0 9 120 2 \n", + "9.625192 120 kworker/0:1 18292 120 256 \n", + "9.625248 120 ksoftirqd/0 9 120 2 \n", + "9.625525 120 kworker/0:1 18292 120 4 \n", + "9.625534 120 sshd 29973 120 2 \n", + "9.625596 120 swapper/0 0 120 1 \n", + "9.625703 120 kworker/0:3 29984 120 256 \n", + "9.627280 120 swapper/7 0 120 1 \n", + "9.627428 120 kworker/u16:1 30005 120 256 \n", + "9.628489 120 swapper/6 0 120 1 \n", + "9.631280 120 swapper/7 0 120 1 \n", + "9.631357 120 kworker/u16:1 30005 120 256 \n", + "9.632357 120 swapper/1 0 120 1 \n", + "9.633065 120 swapper/4 0 120 1 \n", + "9.633134 120 bash 29982 120 2 \n", + "9.633261 120 sshd 29973 120 2 \n", + "9.635390 120 swapper/2 0 120 1 \n", + "9.635522 120 kworker/2:3 12627 120 256 \n", + "9.635860 120 rcu_preempt 10 120 256 \n", + "9.635913 120 swapper/2 0 120 1 \n", + "9.636188 120 kworker/2:3 12627 120 256 \n", + "\n", + "[23560 rows x 11 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = trace.df_events(\"sched_switch\")\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The standard DataFrame operations are available, so you can filter/slice it however you wish:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
__comm__cpu__line__pidnext_commnext_pidnext_prioprev_commprev_pidprev_prioprev_state
Time
1.526125kworker/5:15406729971task_4_130569120kworker/5:129971120256
1.546212<...>5413730566task_4_130569120task_1_1305661201
1.574228kworker/5:15418729971task_4_130569120kworker/5:129971120256
1.595006<...>5423830574task_4_130569120task_7_1305741202
1.626245<idle>543420task_4_130569120swapper/501201
1.658211<...>5440130588task_4_130569120task_2_0305881201
1.692301<...>6447130575task_4_130569120task_2_1305751202
1.692324kworker/6:36447430056task_4_130569120kworker/6:330056120256
1.727411<...>7467030568task_4_130569120task_3_1305681202
1.728851<...>7475330568task_4_130569120task_3_130568120256
1.729009<idle>547630task_4_130569120swapper/501201
1.729096<idle>547680task_4_130569120swapper/501201
\n", + "
" + ], + "text/plain": [ + " __comm __cpu __line __pid next_comm next_pid next_prio \\\n", + "Time \n", + "1.526125 kworker/5:1 5 4067 29971 task_4_1 30569 120 \n", + "1.546212 <...> 5 4137 30566 task_4_1 30569 120 \n", + "1.574228 kworker/5:1 5 4187 29971 task_4_1 30569 120 \n", + "1.595006 <...> 5 4238 30574 task_4_1 30569 120 \n", + "1.626245 5 4342 0 task_4_1 30569 120 \n", + "1.658211 <...> 5 4401 30588 task_4_1 30569 120 \n", + "1.692301 <...> 6 4471 30575 task_4_1 30569 120 \n", + "1.692324 kworker/6:3 6 4474 30056 task_4_1 30569 120 \n", + "1.727411 <...> 7 4670 30568 task_4_1 30569 120 \n", + "1.728851 <...> 7 4753 30568 task_4_1 30569 120 \n", + "1.729009 5 4763 0 task_4_1 30569 120 \n", + "1.729096 5 4768 0 task_4_1 30569 120 \n", + "\n", + " prev_comm prev_pid prev_prio prev_state \n", + "Time \n", + "1.526125 kworker/5:1 29971 120 256 \n", + "1.546212 task_1_1 30566 120 1 \n", + "1.574228 kworker/5:1 29971 120 256 \n", + "1.595006 task_7_1 30574 120 2 \n", + "1.626245 swapper/5 0 120 1 \n", + "1.658211 task_2_0 30588 120 1 \n", + "1.692301 task_2_1 30575 120 2 \n", + "1.692324 kworker/6:3 30056 120 256 \n", + "1.727411 task_3_1 30568 120 2 \n", + "1.728851 task_3_1 30568 120 256 \n", + "1.729009 swapper/5 0 120 1 \n", + "1.729096 swapper/5 0 120 1 " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[df.next_comm == \"task_4_1\"][1.5:2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the trace analysis" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Example dataframes" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
priocomm
pid
130migration/0
160migration/1
210migration/2
260migration/3
310migration/4
360migration/5
410migration/6
460migration/7
31010rtkit-daemon
152649irq/63-hisi_the
1743100kworker/0:1H
3658100kworker/2:1H
\n", + "
" + ], + "text/plain": [ + " prio comm\n", + "pid \n", + "13 0 migration/0\n", + "16 0 migration/1\n", + "21 0 migration/2\n", + "26 0 migration/3\n", + "31 0 migration/4\n", + "36 0 migration/5\n", + "41 0 migration/6\n", + "46 0 migration/7\n", + "3101 0 rtkit-daemon\n", + "1526 49 irq/63-hisi_the\n", + "1743 100 kworker/0:1H\n", + "3658 100 kworker/2:1H" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trace.analysis.tasks.df_rt_tasks()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
target_cpucpucurr_statenext_statedelta
Time
0.71969057WA0.000229
0.719919-15AT0.000027
0.719946-15TW0.000117
0.72006357WA0.000228
0.720291-15AT0.000028
0.720319-15TW0.000224
0.72054357WA0.000226
0.720769-15AD0.000050
0.720819-15DW0.000020
0.72083956WA0.000015
0.720854-15AD0.000019
0.720873-15DW0.000314
0.72118755WA0.000011
0.721198-15AT0.000044
0.721242-15TW0.001190
0.72243255WA0.000012
0.722444-15AD0.000068
0.722512-15DW0.008175
0.73068746WA0.000004
0.730691-14AT0.000117
0.730808-14TW0.000010
0.73081846WA0.000006
0.730824-14AS0.007416
0.738240-14SA0.000013
0.738253-14AS0.007983
0.746236-14SA0.000053
0.746289-14AD0.009043
0.755332-14DW0.068873
0.82420544WA0.000035
0.824240-14AS0.009984
..................
1.52599555WA0.000130
1.526125-15AS0.008111
1.534236-15SA0.011976
1.546212-15AS0.004005
1.550217-15SA0.024011
1.574228-15AS0.011990
1.586218-15SA0.008788
1.595006-15AD0.001340
1.596346-15DW0.029869
1.62621555WA0.000030
1.626245-15AS0.007971
1.634216-15SA0.023995
1.658211-15AS0.008001
1.666212-15SA0.026089
1.692301-16AS0.000010
1.692311-16SA0.000013
1.692324-16AD0.006455
1.698779-16DW0.028145
1.72692466WA0.000487
1.727411-17AD0.000046
1.727457-17DW0.001390
1.72884777WA0.000004
1.728851-17AT0.000128
1.728979-17TW0.000024
1.72900355WA0.000006
1.729009-15AT0.000071
1.729080-15TW0.000009
1.72908957WA0.000007
1.729096-15AZ0.000052
1.729148-15ZNaN7.907040
\n", + "

109 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " target_cpu cpu curr_state next_state delta\n", + "Time \n", + "0.719690 5 7 W A 0.000229\n", + "0.719919 -1 5 A T 0.000027\n", + "0.719946 -1 5 T W 0.000117\n", + "0.720063 5 7 W A 0.000228\n", + "0.720291 -1 5 A T 0.000028\n", + "0.720319 -1 5 T W 0.000224\n", + "0.720543 5 7 W A 0.000226\n", + "0.720769 -1 5 A D 0.000050\n", + "0.720819 -1 5 D W 0.000020\n", + "0.720839 5 6 W A 0.000015\n", + "0.720854 -1 5 A D 0.000019\n", + "0.720873 -1 5 D W 0.000314\n", + "0.721187 5 5 W A 0.000011\n", + "0.721198 -1 5 A T 0.000044\n", + "0.721242 -1 5 T W 0.001190\n", + "0.722432 5 5 W A 0.000012\n", + "0.722444 -1 5 A D 0.000068\n", + "0.722512 -1 5 D W 0.008175\n", + "0.730687 4 6 W A 0.000004\n", + "0.730691 -1 4 A T 0.000117\n", + "0.730808 -1 4 T W 0.000010\n", + "0.730818 4 6 W A 0.000006\n", + "0.730824 -1 4 A S 0.007416\n", + "0.738240 -1 4 S A 0.000013\n", + "0.738253 -1 4 A S 0.007983\n", + "0.746236 -1 4 S A 0.000053\n", + "0.746289 -1 4 A D 0.009043\n", + "0.755332 -1 4 D W 0.068873\n", + "0.824205 4 4 W A 0.000035\n", + "0.824240 -1 4 A S 0.009984\n", + "... ... ... ... ... ...\n", + "1.525995 5 5 W A 0.000130\n", + "1.526125 -1 5 A S 0.008111\n", + "1.534236 -1 5 S A 0.011976\n", + "1.546212 -1 5 A S 0.004005\n", + "1.550217 -1 5 S A 0.024011\n", + "1.574228 -1 5 A S 0.011990\n", + "1.586218 -1 5 S A 0.008788\n", + "1.595006 -1 5 A D 0.001340\n", + "1.596346 -1 5 D W 0.029869\n", + "1.626215 5 5 W A 0.000030\n", + "1.626245 -1 5 A S 0.007971\n", + "1.634216 -1 5 S A 0.023995\n", + "1.658211 -1 5 A S 0.008001\n", + "1.666212 -1 5 S A 0.026089\n", + "1.692301 -1 6 A S 0.000010\n", + "1.692311 -1 6 S A 0.000013\n", + "1.692324 -1 6 A D 0.006455\n", + "1.698779 -1 6 D W 0.028145\n", + "1.726924 6 6 W A 0.000487\n", + "1.727411 -1 7 A D 0.000046\n", + "1.727457 -1 7 D W 0.001390\n", + "1.728847 7 7 W A 0.000004\n", + "1.728851 -1 7 A T 0.000128\n", + "1.728979 -1 7 T W 0.000024\n", + "1.729003 5 5 W A 0.000006\n", + "1.729009 -1 5 A T 0.000071\n", + "1.729080 -1 5 T W 0.000009\n", + "1.729089 5 7 W A 0.000007\n", + "1.729096 -1 5 A Z 0.000052\n", + "1.729148 -1 5 Z NaN 7.907040\n", + "\n", + "[109 rows x 5 columns]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = trace.analysis.tasks.df_task_states(\"task_4_1\")\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.analysis.tasks import TaskState" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
target_cpucpucurr_statenext_statedelta
Time
1.034215-14AS0.011998
1.066214-14AD0.008486
1.124711-15AS0.005528
1.154219-15AS0.007998
1.190213-15AS0.007999
\n", + "
" + ], + "text/plain": [ + " target_cpu cpu curr_state next_state delta\n", + "Time \n", + "1.034215 -1 4 A S 0.011998\n", + "1.066214 -1 4 A D 0.008486\n", + "1.124711 -1 5 A S 0.005528\n", + "1.154219 -1 5 A S 0.007998\n", + "1.190213 -1 5 A S 0.007999" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[df.curr_state == TaskState.TASK_ACTIVE.char][1:1.2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Example plots" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trace.analysis.tasks.plot_task_total_residency(\"task_4_1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trace.analysis.tasks.plot_tasks_wakeups_heatmap(xbins=500)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trace.analysis.tasks.plot_tasks_forks_heatmap(xbins=500)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/ipynb/profiling/kernel_functions_profiling.ipynb b/ipynb/profiling/kernel_functions_profiling.ipynb index f4683d7d877e2b6e0602ab61c26b41d45708c30e..7ddf3e0579d94918d89fb70e6f07822eb106f61f 100644 --- a/ipynb/profiling/kernel_functions_profiling.ipynb +++ b/ipynb/profiling/kernel_functions_profiling.ipynb @@ -4,790 +4,1353 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Kernel Functions Profiling
\n", - "
" + "# Kernel Functions Profiling" ] }, { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, "source": [ - "%load_ext autoreload\n", - "%autoreload 2" + "This notebook is there to show how to do some simple function profiling using LISA.\n", + "\n", + "We'll be using the Ftrace function profiler (See \"Function profiling\" in https://lwn.net/Articles/370423/) for that, and will present the relevant Python APIs from Devlib & LISA that make it easier to use." ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-06 12:06:06,453 INFO : root : Using LISA logging configuration:\n", + "2018-12-06 12:06:06,454 INFO : root : /data/work/lisa/logging.conf\n" + ] + } + ], "source": [ "import logging\n", - "from conf import LisaLogging\n", - "LisaLogging.setup()" + "from lisa.utils import setup_logging\n", + "setup_logging()" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, + "execution_count": 2, + "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" + "2018-12-06 12:06:06,478 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/Grammar.txt\n", + "2018-12-06 12:06:06,502 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/PatternGrammar.txt\n" ] } ], "source": [ - "# Generate plots inline\n", - "%pylab inline\n", - "\n", - "import json\n", "import os\n", - "\n", - "import re\n", - "import collections\n", - "import pandas\n", - "\n", - "# Support to tests execution\n", - "from executor import Executor\n", - "from env import TestEnv" + "from lisa.env import TestEnv, TargetConf" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Target configuration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Tests configuration" + "The only target requirement here is to have enough Ftrace goodies enabled (look at the requirements for **CONFIG_FUNCTION_PROFILER**)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "target_conf = TargetConf({\n", + " \"kind\" : \"linux\",\n", + " \"name\" : \"hikey960\",\n", + " \n", + " \"host\": \"192.168.0.1\",\n", + " \"username\" : \"root\",\n", + " \"password\" : \"root\"\n", + "})" ] }, { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "01:43:51 INFO : Target - Using base path: /home/bjackman/sources/lisa\n", - "01:43:51 INFO : Target - Loading custom (inline) target configuration\n", - "01:43:51 INFO : Target - Loading custom (inline) test configuration\n", - "01:43:51 INFO : Target - Devlib modules to load: ['bl', 'cpufreq']\n", - "01:43:51 INFO : Target - Connecting linux target:\n", - "01:43:51 INFO : Target - username : brendan\n", - "01:43:51 INFO : Target - host : 192.168.0.1\n", - "01:43:51 INFO : Target - password : \n", - "01:43:51 INFO : Target - Connection settings:\n", - "01:43:51 INFO : Target - {'username': 'brendan', 'host': '192.168.0.1', 'password': ''}\n", - "01:43:58 INFO : Target - Initializing target workdir:\n", - "01:43:58 INFO : Target - /home/brendan/devlib-target\n", - "01:44:04 INFO : Target - Topology:\n", - "01:44:04 INFO : Target - [[0, 3, 4, 5], [1, 2]]\n", - "01:44:07 INFO : Platform - Loading default EM:\n", - "01:44:07 INFO : Platform - /home/bjackman/sources/lisa/libs/utils/platforms/juno.json\n", - "01:44:11 INFO : FTrace - Enabled tracepoints:\n", - "01:44:11 INFO : FTrace - sched:*\n", - "01:44:11 INFO : FTrace - Kernel functions profiled:\n", - "01:44:11 INFO : FTrace - select_task_rq_fair\n", - "01:44:11 INFO : FTrace - enqueue_task_fair\n", - "01:44:11 INFO : FTrace - dequeue_task_fair\n", - "01:44:11 WARNING : Target - Using configuration provided RTApp calibration\n", - "01:44:11 INFO : Target - Using RT-App calibration values:\n", - "01:44:11 INFO : Target - {\"0\": 358, \"1\": 138, \"2\": 138, \"3\": 357, \"4\": 359, \"5\": 355}\n", - "01:44:11 WARNING : TestEnv - Wipe previous contents of the results folder:\n", - "01:44:11 WARNING : TestEnv - /home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\n", - "01:44:11 INFO : HWMon - HWMON module not enabled\n", - "01:44:11 WARNING : HWMon - Energy sampling disabled by configuration\n", - "01:44:11 INFO : TestEnv - Set results folder to:\n", - "01:44:11 INFO : TestEnv - /home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\n", - "01:44:11 INFO : TestEnv - Experiment results available also in:\n", - "01:44:11 INFO : TestEnv - /home/bjackman/sources/lisa/results_latest\n" + "2018-12-06 12:06:07,215 INFO : lisa.env.TestEnv : Target configuration:\n", + "|- username from user (str): root\n", + "|- name from user (str): hikey960\n", + "|- kind from user (str): linux\n", + "|- host from user (str): 192.168.0.1\n", + "|- password from user (str): root\n", + "+- devlib:\n", + " +- platform:\n", + " |- class from default (str): devlib.platform.Platform\n", + "+- ftrace:\n", + " |- buffsize from default (int): 10240\n", + "2018-12-06 12:06:07,282 INFO : lisa.env.TestEnv : User-defined platform information:\n", + "|- name from target-conf (str): hikey960\n", + "2018-12-06 12:06:07,315 INFO : lisa.env.TestEnv : linux hikey960 target connection settings:\n", + "2018-12-06 12:06:07,316 INFO : lisa.env.TestEnv : username : root\n", + "2018-12-06 12:06:07,317 INFO : lisa.env.TestEnv : password : root\n", + "2018-12-06 12:06:07,318 INFO : lisa.env.TestEnv : host : 192.168.0.1\n", + "2018-12-06 12:06:07,318 INFO : lisa.env.TestEnv : port : 22\n", + "2018-12-06 12:06:07,335 INFO : lisa.env.TestEnv : Devlib modules to load: bl, cgroups, cpufreq, cpuidle, devfreq, fastboot, gem5stats, gpufreq, hotplug, hwmon, mbed-fan, odroidxu3-fan, sched, thermal\n", + "2018-12-06 12:06:12,042 WARNING : LinuxTarget : Module devfreq is not supported by the target\n", + "2018-12-06 12:06:12,044 WARNING : LinuxTarget : Module fastboot is not supported by the target\n", + "2018-12-06 12:06:12,046 WARNING : LinuxTarget : Module gem5stats is not supported by the target\n", + "2018-12-06 12:06:12,215 WARNING : LinuxTarget : Module gpufreq is not supported by the target\n", + "2018-12-06 12:06:12,903 WARNING : LinuxTarget : Module odroidxu3-fan is not supported by the target\n", + "2018-12-06 12:06:14,900 INFO : CGroups : Available controllers:\n", + "2018-12-06 12:06:15,436 INFO : CGroups : cpuset : /root/devlib-target/cgroups/devlib_cgh10\n", + "2018-12-06 12:06:15,967 INFO : CGroups : cpu : /root/devlib-target/cgroups/devlib_cgh5\n", + "2018-12-06 12:06:16,487 INFO : CGroups : cpuacct : /root/devlib-target/cgroups/devlib_cgh5\n", + "2018-12-06 12:06:17,007 INFO : CGroups : blkio : /root/devlib-target/cgroups/devlib_cgh9\n", + "2018-12-06 12:06:17,531 INFO : CGroups : memory : /root/devlib-target/cgroups/devlib_cgh8\n", + "2018-12-06 12:06:18,053 INFO : CGroups : devices : /root/devlib-target/cgroups/devlib_cgh4\n", + "2018-12-06 12:06:18,574 INFO : CGroups : freezer : /root/devlib-target/cgroups/devlib_cgh6\n", + "2018-12-06 12:06:19,100 INFO : CGroups : perf_event : /root/devlib-target/cgroups/devlib_cgh3\n", + "2018-12-06 12:06:19,619 INFO : CGroups : hugetlb : /root/devlib-target/cgroups/devlib_cgh7\n", + "2018-12-06 12:06:20,143 INFO : CGroups : pids : /root/devlib-target/cgroups/devlib_cgh2\n", + "2018-12-06 12:06:20,315 WARNING : lisa.env.TestEnv : Failed to initialized \"devfreq\" devlib Module\n", + "2018-12-06 12:06:20,317 WARNING : lisa.env.TestEnv : Failed to initialized \"fastboot\" devlib Module\n", + "2018-12-06 12:06:20,318 WARNING : lisa.env.TestEnv : Failed to initialized \"gem5stats\" devlib Module\n", + "2018-12-06 12:06:20,320 WARNING : lisa.env.TestEnv : Failed to initialized \"gpufreq\" devlib Module\n", + "2018-12-06 12:06:20,321 WARNING : lisa.env.TestEnv : Failed to initialized \"mbed-fan\" devlib Module\n", + "2018-12-06 12:06:20,322 WARNING : lisa.env.TestEnv : Failed to initialized \"odroidxu3-fan\" devlib Module\n", + "2018-12-06 12:06:20,324 INFO : lisa.platforms.platinfo.PlatformInfo : Attempting to read energy model from target\n", + "2018-12-06 12:06:20,832 INFO : lisa.energy_model.EnergyModel.EMReader : Attempting to load EM using from_simplifiedEM_target\n", + "2018-12-06 12:06:26,145 INFO : lisa.env.TestEnv : Effective platform information:\n", + "|- cpu-capacities from target (dict): {0: 462, 1: 462, 2: 462, 3: 462, 4: 1024, 5: 1024, 6: 1024, 7: 1024}\n", + "|- cpus-count from target (int): 8\n", + "|- abi from target (str): arm64\n", + "|- freq-domains from target (list): [[0, 1, 2, 3], [4, 5, 6, 7]]\n", + "|- kernel-version from target (KernelVersion): 4.19.0-07809-gb630072 2 SMP PREEMPT Wed Dec 5 16:58:20 GMT 2018\n", + "|- name from target-conf (str): hikey960\n", + "|- nrg-model from target (EnergyModel): \n", + "|- freqs from target (dict): {0: [533000, 999000, 1402000, 1709000, 1844000], 1: [533000, 999000, 1402000, 1709000, 1844000], 2: [533000, 999000, 1402000, 1709000, 1844000], 3: [533000, 999000, 1402000, 1709000, 1844000], 4: [903000, 1421000, 1805000, 2112000, 2362000], 5: [903000, 1421000, 1805000, 2112000, 2362000], 6: [903000, 1421000, 1805000, 2112000, 2362000], 7: [903000, 1421000, 1805000, 2112000, 2362000]}\n", + "|- os from target (str): linux\n", + "+- rtapp:\n", + " |- calib from target (DeferredValue): \n" ] } ], "source": [ - "# Setup a target configuration\n", - "target_conf = {\n", - "\n", - " # Platform and board to target\n", - " \"platform\" : \"linux\",\n", - " \"board\" : \"juno\",\n", - "\n", - " # Login credentials\n", - " \"host\" : \"192.168.0.1\",\n", - " \"username\" : \"brendan\",\n", - " \"password\" : \"\",\n", - "\n", - " # Local installation path\n", - " \"tftp\" : {\n", - " \"folder\" : \"/var/lib/tftpboot\",\n", - " \"kernel\" : \"kern.bin\",\n", - " \"dtb\" : \"dtb.bin\",\n", - " },\n", - "\n", - " # RTApp calibration values (comment to let LISA do a calibration run)\n", - " \"rtapp-calib\" : {\n", - " \"0\": 358, \"1\": 138, \"2\": 138, \"3\": 357, \"4\": 359, \"5\": 355\n", - " },\n", - "\n", - "}\n", - "\n", - "test_conf = {\n", - " # Tools to deploy\n", - " \"tools\" : [ \"rt-app\", 'trace-cmd' ],\n", - " \n", - " # Where results are collected\n", - " # NOTE: this folder will be wiped before running the experiments\n", - " \"results_dir\" : \"KernelFunctionsProfilingExample\",\n", - "\n", - " # Modules required by these experiments\n", - " \"exclude_modules\" : [ \"hwmon\" ],\n", - " \n", - " # Kernel functions to profile for all the test\n", - " # configurations which have the \"ftrace\" flag enabled\n", - " \"ftrace\" : {\n", - " \"functions\" : [\n", - " \"select_task_rq_fair\",\n", - " \"enqueue_task_fair\",\n", - " \"dequeue_task_fair\",\n", - " ],\n", - " \"buffsize\" : 80 * 1024,\n", - " },\n", - "}\n", + "te = TestEnv(target_conf)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Experiment setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can run whatever we want here, let's just build a simple ((1 20% task) x NR_CPUS) workload" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.wlgen.rta import RTA, Periodic" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "rtapp_profile = {}\n", "\n", - "env = TestEnv(target_conf, test_conf)" + "for cpu in range(target.number_of_cpus):\n", + " rtapp_profile[\"task{}\".format(cpu)] = Periodic(duty_cycle_pct=20)" ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, + "execution_count": 7, + "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "01:50:59 INFO : Target - Loading custom (inline) test configuration\n", - "01:50:59 INFO : \n", - "01:50:59 INFO : ################################################################################\n", - "01:50:59 INFO : Executor - Experiments configuration\n", - "01:50:59 INFO : ################################################################################\n", - "01:50:59 INFO : Executor - Configured to run:\n", - "01:50:59 INFO : Executor - 2 target configurations:\n", - "01:50:59 INFO : Executor - base, eas\n", - "01:50:59 INFO : Executor - 1 workloads (3 iterations each)\n", - "01:50:59 INFO : Executor - rta\n", - "01:50:59 INFO : Executor - Total: 6 experiments\n", - "01:50:59 INFO : Executor - Results will be collected under:\n", - "01:50:59 INFO : Executor - /home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\n" + "2018-12-06 12:06:26,283 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181206_120607.215627/profiling_wload-20181206_120626.282417\n", + "2018-12-06 12:06:36,702 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181206_120607.215627/rta_calib-20181206_120636.701911\n", + "2018-12-06 12:06:36,865 INFO : lisa.wlgen.rta.RTA : CPU0 calibration...\n", + "2018-12-06 12:06:37,190 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU0\n", + "2018-12-06 12:06:37,192 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:06:37,193 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:06:37,195 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:06:37,196 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:06:37,198 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:06:37,199 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:06:37,200 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:06:37,445 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu0.json 2>&1\n", + "2018-12-06 12:06:43,970 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:06:44,237 INFO : lisa.wlgen.rta.RTA : CPU1 calibration...\n", + "2018-12-06 12:06:44,563 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU1\n", + "2018-12-06 12:06:44,565 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:06:44,566 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:06:44,568 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:06:44,569 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:06:44,571 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:06:44,572 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:06:44,573 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:06:44,809 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu1.json 2>&1\n", + "2018-12-06 12:06:51,329 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:06:51,605 INFO : lisa.wlgen.rta.RTA : CPU2 calibration...\n", + "2018-12-06 12:06:51,930 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU2\n", + "2018-12-06 12:06:51,932 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:06:51,934 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:06:51,935 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:06:51,936 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:06:51,937 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:06:51,939 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:06:51,940 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:06:52,188 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu2.json 2>&1\n", + "2018-12-06 12:06:58,708 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:06:58,967 INFO : lisa.wlgen.rta.RTA : CPU3 calibration...\n", + "2018-12-06 12:06:59,294 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU3\n", + "2018-12-06 12:06:59,295 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:06:59,296 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:06:59,297 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:06:59,298 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:06:59,299 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:06:59,300 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:06:59,301 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:06:59,538 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu3.json 2>&1\n", + "2018-12-06 12:07:06,057 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:07:06,326 INFO : lisa.wlgen.rta.RTA : CPU4 calibration...\n", + "2018-12-06 12:07:06,654 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU4\n", + "2018-12-06 12:07:06,656 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:07:06,657 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:06,658 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:07:06,659 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:06,660 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:06,661 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:06,662 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:07:06,889 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu4.json 2>&1\n", + "2018-12-06 12:07:13,250 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:07:13,503 INFO : lisa.wlgen.rta.RTA : CPU5 calibration...\n", + "2018-12-06 12:07:13,828 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU5\n", + "2018-12-06 12:07:13,830 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:07:13,831 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:13,833 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:07:13,834 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:13,835 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:13,837 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:13,838 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:07:14,071 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu5.json 2>&1\n", + "2018-12-06 12:07:20,434 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:07:20,709 INFO : lisa.wlgen.rta.RTA : CPU6 calibration...\n", + "2018-12-06 12:07:21,037 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU6\n", + "2018-12-06 12:07:21,038 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:07:21,040 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:21,041 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:07:21,043 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:21,044 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:21,045 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:21,047 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:07:21,279 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu6.json 2>&1\n", + "2018-12-06 12:07:27,639 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:07:27,900 INFO : lisa.wlgen.rta.RTA : CPU7 calibration...\n", + "2018-12-06 12:07:28,227 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU7\n", + "2018-12-06 12:07:28,229 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-06 12:07:28,230 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:28,232 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:07:28,233 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:28,235 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:28,236 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:28,238 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-06 12:07:28,480 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu7.json 2>&1\n", + "2018-12-06 12:07:34,841 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-06 12:07:35,107 INFO : lisa.wlgen.rta.RTA : Target RT-App calibration: {0: 309, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155}\n", + "2018-12-06 12:07:46,545 INFO : lisa.wlgen.rta.RTA : Calibration value: 155\n", + "2018-12-06 12:07:46,546 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-06 12:07:46,546 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,547 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-06 12:07:46,548 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,548 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,549 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,549 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,550 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,551 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,551 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,552 INFO : lisa.wlgen.rta.RTA : task [task2], sched: using default policy\n", + "2018-12-06 12:07:46,552 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,553 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,554 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,554 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,555 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,556 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,556 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,557 INFO : lisa.wlgen.rta.RTA : task [task3], sched: using default policy\n", + "2018-12-06 12:07:46,557 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,558 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,559 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,559 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,560 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,561 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,562 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,563 INFO : lisa.wlgen.rta.RTA : task [task5], sched: using default policy\n", + "2018-12-06 12:07:46,563 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,564 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,565 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,565 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,566 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,567 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,568 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,568 INFO : lisa.wlgen.rta.RTA : task [task0], sched: using default policy\n", + "2018-12-06 12:07:46,569 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,570 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,571 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,571 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,572 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,573 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,573 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,574 INFO : lisa.wlgen.rta.RTA : task [task7], sched: using default policy\n", + "2018-12-06 12:07:46,575 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,576 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,576 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,577 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,578 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,579 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,580 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,581 INFO : lisa.wlgen.rta.RTA : task [task4], sched: using default policy\n", + "2018-12-06 12:07:46,582 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,583 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,583 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,584 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,585 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,586 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n", + "2018-12-06 12:07:46,586 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-06 12:07:46,587 INFO : lisa.wlgen.rta.RTA : task [task6], sched: using default policy\n", + "2018-12-06 12:07:46,588 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-06 12:07:46,589 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-06 12:07:46,590 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-06 12:07:46,590 INFO : lisa.wlgen.rta.Phase : | duration 1.000000 [s] (10 loops)\n", + "2018-12-06 12:07:46,591 INFO : lisa.wlgen.rta.Phase : | period 100000 [us], duty_cycle 20 %\n", + "2018-12-06 12:07:46,592 INFO : lisa.wlgen.rta.Phase : | run_time 20000 [us], sleep_time 80000 [us]\n" ] } ], "source": [ - "# Setup tests executions based on our configuration\n", - " \n", - "tests_conf = {\n", - " # Platform configurations to test\n", - " \"confs\" : [\n", - " {\n", - " \"tag\" : \"base\",\n", - " \"flags\" : \"ftrace\",\n", - " \"sched_features\" : \"NO_ENERGY_AWARE\",\n", - " \"cpufreq\" : {\n", - " \"governor\" : \"performance\",\n", - " },\n", - " # provide a set of files and values to write into them\n", - " \"files\" : {\n", - " # if filenames start with !/ then we verify that the content\n", - " # matches what we wrote and raise an exception if it does not.\n", - " # All filenames without an initial decorator are not verified,\n", - " # and we do not assert that the write was allowed\n", - " # (i,e, the file existed, we have write permission, etc.)\n", - " # this means we can use this for sysctls or other files whose\n", - " # presence or permissions might depend upon kernel config or\n", - " # OS support and we reasonably can proceed for either case.\n", - " '/this_file_doesnt_exist_and_we_dont_care' : '1',\n", - " '/proc/sys/kernel/sched_is_big_little' : '0',\n", - " '/proc/sys/kernel/sched_initial_task_util' : '1023',\n", - " '/proc/sys/kernel/sched_use_walt_cpu_util' : '0',\n", - " '/proc/sys/kernel/sched_use_walt_task_util' : '0',\n", - " '/proc/sys/kernel/sched_cstate_aware' : '1',\n", - " '/proc/sys/kernel/sched_walt_cpu_high_irqload' : '10000000',\n", - " '/proc/sys/kernel/sched_init_task_load_pct' : '15',\n", - " '!/proc/sys/kernel/sched_latency_ns' : '10000000',\n", - " '!/proc/sys/kernel/sched_migration_cost_ns' : '500000',\n", - " },\n", - " },\n", - " {\n", - " \"tag\" : \"eas\",\n", - " \"flags\" : \"ftrace\",\n", - " \"sched_features\" : \"ENERGY_AWARE\",\n", - " \"cpufreq\" : {\n", - " \"governor\" : \"performance\",\n", - " },\n", - " \"files\" : {\n", - " '/proc/sys/kernel/sched_is_big_little' : '1',\n", - " '/proc/sys/kernel/sched_initial_task_util' : '1023',\n", - " '/proc/sys/kernel/sched_use_walt_cpu_util' : '0',\n", - " '/proc/sys/kernel/sched_use_walt_task_util' : '0',\n", - " '/proc/sys/kernel/sched_cstate_aware' : '1',\n", - " '/proc/sys/kernel/sched_walt_cpu_high_irqload' : '10000000',\n", - " '/proc/sys/kernel/sched_init_task_load_pct' : '15',\n", - " '!/proc/sys/kernel/sched_latency_ns' : '10000000',\n", - " '!/proc/sys/kernel/sched_migration_cost_ns' : '500000',\n", - " },\n", - " },\n", - " ],\n", - " \n", - " # Workloads to run (on each platform configuration)\n", - " \"wloads\" : {\n", - " \"rta\" : {\n", - " \"type\" : \"rt-app\",\n", - " \"conf\" : {\n", - " \"class\" : \"profile\",\n", - " \"params\" : {\n", - " \"p20\" : {\n", - " \"kind\" : \"Periodic\",\n", - " \"params\" : {\n", - " \"duty_cycle_pct\" : 20,\n", - " },\n", - " \"tasks\" : \"cpus\",\n", - " },\n", - " },\n", - " },\n", - " },\n", - " },\n", - " \n", - " # Number of iterations for each configuration/workload pair\n", - " \"iterations\" : 3,\n", - "}\n", - "\n", - "executor = Executor(env, tests_conf)" + "wload = RTA.by_profile(te, \"profiling_wload\", rtapp_profile)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Tests execution" + "Now, let's define the functions we want to do some profiling on. Do keep in mind all functions might not be profilable - that can happen if they are inline." ] }, { "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false, - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "01:51:01 INFO : \n", - "01:51:01 INFO : ################################################################################\n", - "01:51:01 INFO : Executor - Experiments execution\n", - "01:51:01 INFO : ################################################################################\n", - "01:51:01 INFO : \n", - "01:51:01 INFO : ================================================================================\n", - "01:51:01 INFO : TargetConfig - configuring target for [base] experiments\n", - "01:51:03 INFO : SchedFeatures - Set scheduler feature: NO_ENERGY_AWARE\n", - "01:51:04 INFO : CPUFreq - Configuring all CPUs to use [performance] governor\n", - "01:51:05 INFO : WlGen - Setup new workload rta\n", - "01:51:05 INFO : RTApp - Workload duration defined by longest task\n", - "01:51:05 INFO : RTApp - Default policy: SCHED_OTHER\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p200], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p201], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p202], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p203], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p204], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:05 INFO : RTApp - ------------------------\n", - "01:51:05 INFO : RTApp - task [task_p205], sched: using default policy\n", - "01:51:05 INFO : RTApp - | calibration CPU: 1\n", - "01:51:05 INFO : RTApp - | loops count: 1\n", - "01:51:05 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:51:05 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:51:05 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:51:06 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:51:06 INFO : Executor - Experiment 0/6, [base:rta] 1/3\n", - "01:51:06 WARNING : Executor - FTrace events collection enabled\n", - "01:51:17 INFO : WlGen - Workload execution START:\n", - "01:51:17 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:51:30 INFO : Executor - Collected FTrace binary trace:\n", - "01:51:30 INFO : Executor - /rtapp:base:rta/1/trace.dat\n", - "01:51:31 INFO : Executor - Collected FTrace function profiling:\n", - "01:51:31 INFO : Executor - /rtapp:base:rta/1/trace_stat.json\n", - "01:51:31 INFO : --------------------------------------------------------------------------------\n", - "01:51:31 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:51:31 INFO : Executor - Experiment 1/6, [base:rta] 2/3\n", - "01:51:31 WARNING : Executor - FTrace events collection enabled\n", - "01:51:43 INFO : WlGen - Workload execution START:\n", - "01:51:43 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:51:52 INFO : Executor - Collected FTrace binary trace:\n", - "01:51:52 INFO : Executor - /rtapp:base:rta/2/trace.dat\n", - "01:51:53 INFO : Executor - Collected FTrace function profiling:\n", - "01:51:53 INFO : Executor - /rtapp:base:rta/2/trace_stat.json\n", - "01:51:53 INFO : --------------------------------------------------------------------------------\n", - "01:51:53 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:51:53 INFO : Executor - Experiment 2/6, [base:rta] 3/3\n", - "01:51:53 WARNING : Executor - FTrace events collection enabled\n", - "01:52:05 INFO : WlGen - Workload execution START:\n", - "01:52:05 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:52:19 INFO : Executor - Collected FTrace binary trace:\n", - "01:52:19 INFO : Executor - /rtapp:base:rta/3/trace.dat\n", - "01:52:20 INFO : Executor - Collected FTrace function profiling:\n", - "01:52:20 INFO : Executor - /rtapp:base:rta/3/trace_stat.json\n", - "01:52:20 INFO : --------------------------------------------------------------------------------\n", - "01:52:20 INFO : \n", - "01:52:20 INFO : ================================================================================\n", - "01:52:20 INFO : TargetConfig - configuring target for [eas] experiments\n", - "01:52:22 INFO : SchedFeatures - Set scheduler feature: ENERGY_AWARE\n", - "01:52:23 INFO : CPUFreq - Configuring all CPUs to use [performance] governor\n", - "01:52:24 INFO : WlGen - Setup new workload rta\n", - "01:52:24 INFO : RTApp - Workload duration defined by longest task\n", - "01:52:24 INFO : RTApp - Default policy: SCHED_OTHER\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p200], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p201], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p202], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p203], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p204], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : RTApp - ------------------------\n", - "01:52:24 INFO : RTApp - task [task_p205], sched: using default policy\n", - "01:52:24 INFO : RTApp - | calibration CPU: 1\n", - "01:52:24 INFO : RTApp - | loops count: 1\n", - "01:52:24 INFO : RTApp - + phase_000001: duration 1.000000 [s] (10 loops)\n", - "01:52:24 INFO : RTApp - | period 100000 [us], duty_cycle 20 %\n", - "01:52:24 INFO : RTApp - | run_time 20000 [us], sleep_time 80000 [us]\n", - "01:52:24 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:52:24 INFO : Executor - Experiment 0/6, [base:rta] 1/3\n", - "01:52:24 WARNING : Executor - FTrace events collection enabled\n", - "01:52:37 INFO : WlGen - Workload execution START:\n", - "01:52:37 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:52:47 INFO : Executor - Collected FTrace binary trace:\n", - "01:52:47 INFO : Executor - /rtapp:base:rta/1/trace.dat\n", - "01:52:48 INFO : Executor - Collected FTrace function profiling:\n", - "01:52:48 INFO : Executor - /rtapp:base:rta/1/trace_stat.json\n", - "01:52:48 INFO : --------------------------------------------------------------------------------\n", - "01:52:48 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:52:48 INFO : Executor - Experiment 1/6, [base:rta] 2/3\n", - "01:52:48 WARNING : Executor - FTrace events collection enabled\n", - "01:53:00 INFO : WlGen - Workload execution START:\n", - "01:53:00 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:53:12 INFO : Executor - Collected FTrace binary trace:\n", - "01:53:12 INFO : Executor - /rtapp:base:rta/2/trace.dat\n", - "01:53:13 INFO : Executor - Collected FTrace function profiling:\n", - "01:53:13 INFO : Executor - /rtapp:base:rta/2/trace_stat.json\n", - "01:53:13 INFO : --------------------------------------------------------------------------------\n", - "01:53:13 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:53:13 INFO : Executor - Experiment 2/6, [base:rta] 3/3\n", - "01:53:13 WARNING : Executor - FTrace events collection enabled\n", - "01:53:25 INFO : WlGen - Workload execution START:\n", - "01:53:25 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:53:35 INFO : Executor - Collected FTrace binary trace:\n", - "01:53:35 INFO : Executor - /rtapp:base:rta/3/trace.dat\n", - "01:53:36 INFO : Executor - Collected FTrace function profiling:\n", - "01:53:36 INFO : Executor - /rtapp:base:rta/3/trace_stat.json\n", - "01:53:36 INFO : --------------------------------------------------------------------------------\n", - "01:53:36 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:53:36 INFO : Executor - Experiment 3/6, [eas:rta] 1/3\n", - "01:53:36 WARNING : Executor - FTrace events collection enabled\n", - "01:53:48 INFO : WlGen - Workload execution START:\n", - "01:53:48 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:53:57 INFO : Executor - Collected FTrace binary trace:\n", - "01:53:57 INFO : Executor - /rtapp:eas:rta/1/trace.dat\n", - "01:53:58 INFO : Executor - Collected FTrace function profiling:\n", - "01:53:58 INFO : Executor - /rtapp:eas:rta/1/trace_stat.json\n", - "01:53:58 INFO : --------------------------------------------------------------------------------\n", - "01:53:58 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:53:58 INFO : Executor - Experiment 4/6, [eas:rta] 2/3\n", - "01:53:58 WARNING : Executor - FTrace events collection enabled\n", - "01:54:10 INFO : WlGen - Workload execution START:\n", - "01:54:10 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:54:22 INFO : Executor - Collected FTrace binary trace:\n", - "01:54:22 INFO : Executor - /rtapp:eas:rta/2/trace.dat\n", - "01:54:23 INFO : Executor - Collected FTrace function profiling:\n", - "01:54:23 INFO : Executor - /rtapp:eas:rta/2/trace_stat.json\n", - "01:54:23 INFO : --------------------------------------------------------------------------------\n", - "01:54:23 INFO : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", - "01:54:23 INFO : Executor - Experiment 5/6, [eas:rta] 3/3\n", - "01:54:23 WARNING : Executor - FTrace events collection enabled\n", - "01:54:35 INFO : WlGen - Workload execution START:\n", - "01:54:35 INFO : WlGen - /home/brendan/devlib-target/bin/rt-app /home/brendan/devlib-target/run_dir/rta_00.json 2>&1\n", - "01:54:45 INFO : Executor - Collected FTrace binary trace:\n", - "01:54:45 INFO : Executor - /rtapp:eas:rta/3/trace.dat\n", - "01:54:46 INFO : Executor - Collected FTrace function profiling:\n", - "01:54:46 INFO : Executor - /rtapp:eas:rta/3/trace_stat.json\n", - "01:54:46 INFO : --------------------------------------------------------------------------------\n", - "01:54:46 INFO : \n", - "01:54:46 INFO : ################################################################################\n", - "01:54:46 INFO : Executor - Experiments execution completed\n", - "01:54:46 INFO : ################################################################################\n", - "01:54:46 INFO : Executor - Results available in:\n", - "01:54:46 INFO : Executor - /home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\n" - ] - } - ], + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "functions = [\n", + " \"scheduler_tick\",\n", + " \"run_rebalance_domains\"\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ - "# Execute all the configured test\n", - "executor.run()" + "We're using an FtraceCollector so might as well record some basic events to get a meaningful trace" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "events = [\n", + " \"sched_switch\",\n", + " \"sched_wakeup\",\n", + " \"sched_wakeup_new\"\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running the experiment" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, "outputs": [], "source": [ - "res_dir = \"/home/derkling/Code/lisa/results/KernelFunctionsProfilingExample\"\n", - "out_dir = \"/home/derkling/Code/lisa/results/KernelFunctionsProfilingExample/rtapp:eas:rta/2/trace.dat\"\n", - "out_dir.replace(res_dir, \"\")\n", - "print executor.te.res_dir" + "from devlib.trace.ftrace import FtraceCollector" ] }, { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false, - "scrolled": false - }, + "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "01:56:21 INFO : Content of the output folder /home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\n" + "2018-12-06 12:07:54,600 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/profiling_wload.json 2>&1\n", + "2018-12-06 12:07:55,786 INFO : lisa.wlgen.rta.RTA : Execution complete\n" ] }, + { + "data": { + "text/plain": [ + "{0: {'run_rebalance_domains': {'avg': 28.565,\n", + " 'hits': 129,\n", + " 's_2': 838.923,\n", + " 'time': 3684.901},\n", + " 'scheduler_tick': {'avg': 17.795,\n", + " 'hits': 179,\n", + " 's_2': 199.158,\n", + " 'time': 3185.424}},\n", + " 1: {'run_rebalance_domains': {'avg': 15.449,\n", + " 'hits': 83,\n", + " 's_2': 53.21,\n", + " 'time': 1282.29},\n", + " 'scheduler_tick': {'avg': 20.458,\n", + " 'hits': 210,\n", + " 's_2': 205.694,\n", + " 'time': 4296.366}},\n", + " 2: {'run_rebalance_domains': {'avg': 26.185,\n", + " 'hits': 315,\n", + " 's_2': 625.211,\n", + " 'time': 8248.431},\n", + " 'scheduler_tick': {'avg': 8.81, 'hits': 372, 's_2': 92.7, 'time': 3277.608}},\n", + " 3: {'run_rebalance_domains': {'avg': 15.117,\n", + " 'hits': 38,\n", + " 's_2': 48.512,\n", + " 'time': 574.479},\n", + " 'scheduler_tick': {'avg': 16.695,\n", + " 'hits': 182,\n", + " 's_2': 144.725,\n", + " 'time': 3038.539}},\n", + " 4: {'run_rebalance_domains': {'avg': 10.529,\n", + " 'hits': 69,\n", + " 's_2': 69.795,\n", + " 'time': 726.567},\n", + " 'scheduler_tick': {'avg': 8.895,\n", + " 'hits': 203,\n", + " 's_2': 23.236,\n", + " 'time': 1805.732}},\n", + " 5: {'run_rebalance_domains': {'avg': 13.387,\n", + " 'hits': 645,\n", + " 's_2': 78.221,\n", + " 'time': 8634.903},\n", + " 'scheduler_tick': {'avg': 4.333,\n", + " 'hits': 1094,\n", + " 's_2': 16.143,\n", + " 'time': 4740.621}},\n", + " 6: {'run_rebalance_domains': {'avg': 11.078,\n", + " 'hits': 70,\n", + " 's_2': 52.65,\n", + " 'time': 775.514},\n", + " 'scheduler_tick': {'avg': 8.917,\n", + " 'hits': 198,\n", + " 's_2': 22.484,\n", + " 'time': 1765.634}},\n", + " 7: {'run_rebalance_domains': {'avg': 10.356,\n", + " 'hits': 69,\n", + " 's_2': 33.649,\n", + " 'time': 714.585},\n", + " 'scheduler_tick': {'avg': 8.709,\n", + " 'hits': 176,\n", + " 's_2': 23.114,\n", + " 'time': 1532.814}}}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ftrace = FtraceCollector(target, functions=functions, buffer_size=10240)\n", + "\n", + "with ftrace:\n", + " wload.run()\n", + "\n", + "# Save the trace\n", + "ftrace.get_trace(os.path.join(wload.res_dir, \"trace.dat\"))\n", + "# Save the profiling stats\n", + "ftrace.get_stats(os.path.join(wload.res_dir, \"stats.json\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[01;34m/home/bjackman/sources/lisa/results/KernelFunctionsProfilingExample\u001b[00m\r\n", - "├── \u001b[01;34mrtapp:base:rta\u001b[00m\r\n", - "│   ├── \u001b[01;34m1\u001b[00m\r\n", - "│   │   ├── output.log\r\n", - "│   │   ├── rta_00.json\r\n", - "│   │   ├── rt-app-task_p200-0.log\r\n", - "│   │   ├── rt-app-task_p201-1.log\r\n", - "│   │   ├── rt-app-task_p202-2.log\r\n", - "│   │   ├── rt-app-task_p203-3.log\r\n", - "│   │   ├── rt-app-task_p204-4.log\r\n", - "│   │   ├── rt-app-task_p205-5.log\r\n", - "│   │   ├── trace.dat\r\n", - "│   │   └── trace_stat.json\r\n", - "│   ├── \u001b[01;34m2\u001b[00m\r\n", - "│   │   ├── output.log\r\n", - "│   │   ├── rta_00.json\r\n", - "│   │   ├── rt-app-task_p200-0.log\r\n", - "│   │   ├── rt-app-task_p201-1.log\r\n", - "│   │   ├── rt-app-task_p202-2.log\r\n", - "│   │   ├── rt-app-task_p203-3.log\r\n", - "│   │   ├── rt-app-task_p204-4.log\r\n", - "│   │   ├── rt-app-task_p205-5.log\r\n", - "│   │   ├── trace.dat\r\n", - "│   │   └── trace_stat.json\r\n", - "│   ├── \u001b[01;34m3\u001b[00m\r\n", - "│   │   ├── output.log\r\n", - "│   │   ├── rta_00.json\r\n", - "│   │   ├── rt-app-task_p200-0.log\r\n", - "│   │   ├── rt-app-task_p201-1.log\r\n", - "│   │   ├── rt-app-task_p202-2.log\r\n", - "│   │   ├── rt-app-task_p203-3.log\r\n", - "│   │   ├── rt-app-task_p204-4.log\r\n", - "│   │   ├── rt-app-task_p205-5.log\r\n", - "│   │   ├── trace.dat\r\n", - "│   │   └── trace_stat.json\r\n", - "│   ├── kernel.config\r\n", - "│   ├── kernel.version\r\n", - "│   └── platform.json\r\n", - "└── \u001b[01;34mrtapp:eas:rta\u001b[00m\r\n", - " ├── \u001b[01;34m1\u001b[00m\r\n", - " │   ├── output.log\r\n", - " │   ├── rta_00.json\r\n", - " │   ├── rt-app-task_p200-0.log\r\n", - " │   ├── rt-app-task_p201-1.log\r\n", - " │   ├── rt-app-task_p202-2.log\r\n", - " │   ├── rt-app-task_p203-3.log\r\n", - " │   ├── rt-app-task_p204-4.log\r\n", - " │   ├── rt-app-task_p205-5.log\r\n", - " │   ├── trace.dat\r\n", - " │   └── trace_stat.json\r\n", - " ├── \u001b[01;34m2\u001b[00m\r\n", - " │   ├── output.log\r\n", - " │   ├── rta_00.json\r\n", - " │   ├── rt-app-task_p200-0.log\r\n", - " │   ├── rt-app-task_p201-1.log\r\n", - " │   ├── rt-app-task_p202-2.log\r\n", - " │   ├── rt-app-task_p203-3.log\r\n", - " │   ├── rt-app-task_p204-4.log\r\n", - " │   ├── rt-app-task_p205-5.log\r\n", - " │   ├── trace.dat\r\n", - " │   └── trace_stat.json\r\n", - " ├── \u001b[01;34m3\u001b[00m\r\n", - " │   ├── output.log\r\n", - " │   ├── rta_00.json\r\n", - " │   ├── rt-app-task_p200-0.log\r\n", - " │   ├── rt-app-task_p201-1.log\r\n", - " │   ├── rt-app-task_p202-2.log\r\n", - " │   ├── rt-app-task_p203-3.log\r\n", - " │   ├── rt-app-task_p204-4.log\r\n", - " │   ├── rt-app-task_p205-5.log\r\n", - " │   ├── trace.dat\r\n", - " │   └── trace_stat.json\r\n", - " ├── kernel.config\r\n", - " ├── kernel.version\r\n", - " └── platform.json\r\n", + "\u001b[01;34m/data/work/lisa/results/hikey960-20181206_120607.215627/profiling_wload-20181206_120626.282417\u001b[00m\r\n", + "├── output.log\r\n", + "├── profiling_wload.json\r\n", + "├── rt-app-cpu0_task0-6.log\r\n", + "├── rt-app-cpu0_task0-9.log\r\n", + "├── rt-app-cpu0_task1-17.log\r\n", + "├── rt-app-cpu0_task1-9.log\r\n", + "├── rt-app-cpu0_task2-21.log\r\n", + "├── rt-app-cpu0_task2-4.log\r\n", + "├── rt-app-cpu1_task0-14.log\r\n", + "├── rt-app-cpu1_task0-2.log\r\n", + "├── rt-app-cpu1_task1-4.log\r\n", + "├── rt-app-cpu1_task1-7.log\r\n", + "├── rt-app-cpu1_task2-10.log\r\n", + "├── rt-app-cpu1_task2-15.log\r\n", + "├── rt-app-cpu2_task0-19.log\r\n", + "├── rt-app-cpu2_task0-20.log\r\n", + "├── rt-app-cpu2_task1-10.log\r\n", + "├── rt-app-cpu2_task1-21.log\r\n", + "├── rt-app-cpu2_task2-11.log\r\n", + "├── rt-app-cpu2_task2-12.log\r\n", + "├── rt-app-cpu3_task0-23.log\r\n", + "├── rt-app-cpu3_task0-2.log\r\n", + "├── rt-app-cpu3_task1-17.log\r\n", + "├── rt-app-cpu3_task1-3.log\r\n", + "├── rt-app-cpu3_task2-0.log\r\n", + "├── rt-app-cpu3_task2-13.log\r\n", + "├── rt-app-cpu4_task0-16.log\r\n", + "├── rt-app-cpu4_task0-5.log\r\n", + "├── rt-app-cpu4_task1-11.log\r\n", + "├── rt-app-cpu4_task1-14.log\r\n", + "├── rt-app-cpu4_task2-22.log\r\n", + "├── rt-app-cpu4_task2-7.log\r\n", + "├── rt-app-cpu5_task0-12.log\r\n", + "├── rt-app-cpu5_task0-13.log\r\n", + "├── rt-app-cpu5_task1-18.log\r\n", + "├── rt-app-cpu5_task1-19.log\r\n", + "├── rt-app-cpu5_task2-1.log\r\n", + "├── rt-app-cpu5_task2-6.log\r\n", + "├── rt-app-cpu6_task0-16.log\r\n", + "├── rt-app-cpu6_task0-5.log\r\n", + "├── rt-app-cpu6_task1-0.log\r\n", + "├── rt-app-cpu6_task1-3.log\r\n", + "├── rt-app-cpu6_task2-15.log\r\n", + "├── rt-app-cpu6_task2-20.log\r\n", + "├── rt-app-cpu7_task0-1.log\r\n", + "├── rt-app-cpu7_task0-23.log\r\n", + "├── rt-app-cpu7_task1-8.log\r\n", + "├── rt-app-cpu7_task2-18.log\r\n", + "├── rt-app-cpu7_task2-22.log\r\n", + "├── rt-app-task0-4.log\r\n", + "├── rt-app-task1-0.log\r\n", + "├── rt-app-task2-1.log\r\n", + "├── rt-app-task3-5.log\r\n", + "├── rt-app-task4-6.log\r\n", + "├── rt-app-task5-2.log\r\n", + "├── rt-app-task6-7.log\r\n", + "├── rt-app-task7-3.log\r\n", + "├── stats.json\r\n", + "├── trace.dat\r\n", + "└── trace.txt\r\n", "\r\n", - "8 directories, 66 files\r\n" + "0 directories, 60 files\r\n" ] } ], "source": [ - "# Check content of the output folder\n", - "res_dir = executor.te.res_dir\n", - "logging.info('Content of the output folder %s', res_dir)\n", - "!tree {res_dir}" + "!tree {wload.res_dir}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Load function profiling data" + "## Loading the trace" ] }, { "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false, - "scrolled": false - }, + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.trace import Trace" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, "outputs": [], "source": [ - "def autodict():\n", - " return collections.defaultdict(autodict)\n", + "trace = Trace(wload.res_dir, te.plat_info, events=events)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can have a look at the trace of the workload we just ran" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "from trappy.plotter import plot_trace" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_trace(trace.ftrace)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the function profiling" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The profiling stats are JSON so let's load it up into a dict" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "import json" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "stats_path = os.path.join(wload.res_dir, \"stats.json\")\n", "\n", - "def parse_perf_stat(res_dir):\n", - " TEST_DIR_RE = re.compile(r'.*/([^:]*):([^:]*):([^:]*)')\n", - " profiling_data = autodict()\n", + "with open(stats_path, \"r\") as fh:\n", + " # That ';' is just there to prevent Jupyter from dumping the dict in stdout\n", + " stats = json.load(fh);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The data in the file is arranged like so:\n", "\n", - " for test_idx in sorted(os.listdir(res_dir)):\n", - " test_dir = os.path.join(res_dir, test_idx)\n", - " if not os.path.isdir(test_dir):\n", - " continue\n", - " match = TEST_DIR_RE.search(test_dir)\n", - " if not match:\n", - " continue\n", - " wtype = match.group(1)\n", - " tconf = match.group(2)\n", - " wload = match.group(3)\n", + "- For each CPU\n", + " - For each function\n", + " - time (µs)\n", + " - hits (#)\n", + " - s_2, AKA variance - apply sqrt() to get standard deviation\n", + " - avg (µs)\n", + " \n", + "To make it a bit simpler to manipulate, we're going to turn this data into a pandas DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", "\n", - " #logging.info('Processing %s:%s:%s', wtype, tconf, wload)\n", - " trace_stat_file = os.path.join(test_dir, '1', 'trace_stat.json')\n", - " if not os.path.isfile(trace_stat_file):\n", - " continue\n", - " with open(trace_stat_file, 'r') as fh:\n", - " data = json.load(fh)\n", - " for cpu_id, cpu_stats in sorted(data.items()):\n", - " for fname in cpu_stats:\n", - " profiling_data[cpu_id][tconf][fname] = cpu_stats[fname]\n", + "def stats_to_df(stats_dict):\n", + " \"\"\"\n", + " Turn Ftrace function profiling stats into a pandas DataFtrame\n", + " \n", + " :param stats_dict: The stats dictionnary generated by FtraceCollector\n", + " :type stats_dict: dict\n", + " \"\"\"\n", + " data = []\n", + " index = []\n", + " \n", + " for cpu, functions in stats_dict.items():\n", + " index.append(int(cpu))\n", + " columns = []\n", + " line = []\n", + " \n", + " for function, stats in functions.items():\n", + " \n", + " for name, stat in stats.items():\n", + " columns.append((function, name))\n", + " line.append(stat)\n", "\n", - " return profiling_data\n", - " \n", - "profiling_data = parse_perf_stat(res_dir)\n", - "#logging.info(\"Profiling data:\\n%s\", json.dumps(profiling_data, indent=4))\n", - "#profiling_data" + " data.append(line)\n", + " \n", + " df = pd.DataFrame(data, index=index, columns=columns)\n", + " df.columns = pd.MultiIndex.from_tuples(df.columns, names=[\"function\", \"cpu\"])\n", + " df = df.sort_index()\n", + " return df" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "df = stats_to_df(stats)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Build Pandas DataFrame from profiling data" + "Here's how the Dataframe looks like:" ] }, { "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
functionscheduler_tickrun_rebalance_domains
cpuavgtimehitss_2avgtimehitss_2
017.7953185.424179199.15828.5653684.901129838.923
120.4584296.366210205.69415.4491282.2908353.210
28.8103277.60837292.70026.1858248.431315625.211
316.6953038.539182144.72515.117574.4793848.512
48.8951805.73220323.23610.529726.5676969.795
54.3334740.621109416.14313.3878634.90364578.221
68.9171765.63419822.48411.078775.5147052.650
78.7091532.81417623.11410.356714.5856933.649
\n", + "
" + ], + "text/plain": [ + "function scheduler_tick run_rebalance_domains \\\n", + "cpu avg time hits s_2 avg \n", + "0 17.795 3185.424 179 199.158 28.565 \n", + "1 20.458 4296.366 210 205.694 15.449 \n", + "2 8.810 3277.608 372 92.700 26.185 \n", + "3 16.695 3038.539 182 144.725 15.117 \n", + "4 8.895 1805.732 203 23.236 10.529 \n", + "5 4.333 4740.621 1094 16.143 13.387 \n", + "6 8.917 1765.634 198 22.484 11.078 \n", + "7 8.709 1532.814 176 23.114 10.356 \n", + "\n", + "function \n", + "cpu time hits s_2 \n", + "0 3684.901 129 838.923 \n", + "1 1282.290 83 53.210 \n", + "2 8248.431 315 625.211 \n", + "3 574.479 38 48.512 \n", + "4 726.567 69 69.795 \n", + "5 8634.903 645 78.221 \n", + "6 775.514 70 52.650 \n", + "7 714.585 69 33.649 " + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "def get_df(profiling_data):\n", - " cpu_ids = []\n", - " cpu_frames = []\n", - " for cpu_id, cpu_data in sorted(profiling_data.items()):\n", - " cpu_ids.append(cpu_id)\n", - " conf_ids = []\n", - " conf_frames = []\n", - " for conf_id, conf_data in cpu_data.iteritems():\n", - " conf_ids.append(conf_id)\n", - " function_data = pandas.DataFrame.from_dict(conf_data, orient='index')\n", - " conf_frames.append(function_data)\n", - " df = pandas.concat(conf_frames, keys=conf_ids)\n", - " cpu_frames.append(df)\n", - " df = pandas.concat(cpu_frames, keys=cpu_ids)\n", - " #df.head()\n", - " return df\n", - "\n", - "stats_df = get_df(profiling_data)\n", - "#stats_df" + "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Plot profiling data per function and CPU" + "We can easily have a look at a specific function:" ] }, { "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cpuavgtimehitss_2
028.5653684.901129838.923
115.4491282.2908353.210
226.1858248.431315625.211
315.117574.4793848.512
410.529726.5676969.795
513.3878634.90364578.221
611.078775.5147052.650
710.356714.5856933.649
\n", + "
" + ], + "text/plain": [ + "cpu avg time hits s_2\n", + "0 28.565 3684.901 129 838.923\n", + "1 15.449 1282.290 83 53.210\n", + "2 26.185 8248.431 315 625.211\n", + "3 15.117 574.479 38 48.512\n", + "4 10.529 726.567 69 69.795\n", + "5 13.387 8634.903 645 78.221\n", + "6 11.078 775.514 70 52.650\n", + "7 10.356 714.585 69 33.649" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.run_rebalance_domains" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It's also easy to get overall stats for one function. For instance, if we want the total number of hits for a function (summing up the number of hits over all CPUs), that can be done like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1418" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.run_rebalance_domains.hits.sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also get stats recorded on a single CPU like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cpu\n", + "avg 26.185\n", + "time 8248.431\n", + "hits 315.000\n", + "s_2 625.211\n", + "Name: 2, dtype: float64" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.run_rebalance_domains.loc[2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visual profiling" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have all of the relevant data in Dataframe format, it's very easy to make plots out of it" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, "outputs": [], "source": [ - "def plot_stats(df, fname, axes=None):\n", - " func_data = df.xs(fname, level=2)\n", - " func_stats = func_data.xs(['avg', 's_2'], axis=1)\n", - " #func_stats\n", - " func_avg = func_stats.unstack(level=1)['avg']\n", - " func_std = func_stats.unstack(level=1)['s_2'].apply(numpy.sqrt)\n", - " func_avg.plot(kind='bar', title=fname, yerr=func_std, ax=axes);\n", - "\n", - "#plot_stats(stats_df, 'select_task_rq_fair')" + "import matplotlib.pyplot as plt\n", + "import numpy as np" ] }, { "cell_type": "code", - "execution_count": 15, - "metadata": { - "collapsed": false, - "scrolled": false - }, + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_hits(df, function):\n", + " fig, ax = plt.subplots(figsize=(16, 5))\n", + " \n", + " df[function].hits.plot.bar(ax=ax) \n", + " ax.set_title(\"Per-CPU hits of \\\"{}\\\"\".format(function))\n", + " ax.set_xlabel(\"CPU\")\n", + " ax.set_ylabel(\"# of hits\")\n", + " ax.grid(True)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_time_avg(df, function):\n", + " fig, ax = plt.subplots(figsize=(16, 5))\n", + " \n", + " # Let's compute the standard deviation to plot error bars\n", + " stddev = df[function].s_2.apply(np.sqrt)\n", + " \n", + " df[function].avg.plot.bar(ax=ax, yerr=stddev, capsize=10) \n", + " ax.set_title(\"Per-CPU average time of \\\"{}\\\"\".format(function))\n", + " ax.set_xlabel(\"CPU\")\n", + " ax.set_ylabel(\"Average time (µs)\")\n", + " ax.grid(True)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "01:56:33 INFO : Plotting stats for [dequeue_task_fair] function\n", - "01:56:33 INFO : Plotting stats for [enqueue_task_fair] function\n", - "01:56:33 INFO : Plotting stats for [select_task_rq_fair] function\n", - "/usr/lib/pymodules/python2.7/matplotlib/collections.py:548: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n", - " if self._edgecolors == 'face':\n" - ] + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" }, { "data": { - "image/png": "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\n5I477siaNWvyyU9+Mknyta99LbfffnseeeSRjIyM5JZbbslhhx027fUKmwAAAD3gzjvvzJNPPplL\nL7008+bNy+LFi/POd74zn/nMZ3LKKafktNNOy5w5c3LcccdlxYoVWbt2bZLkgAMOyOjoaL7zne9k\n+/btOeGEE3LUUUdNe73zpv0KAAAAtG3Dhg3ZtGlTBgYGxvY9//zzOf300/PII4/koosuyt13351n\nnnkmP/vZz3LqqacmSc4888ysXLky73nPe7Jhw4a8/vWvz1VXXZW+vr5prVfPJgAAQA849thjs3jx\n4gwPD489tmzZkttuuy3nn39+li5dmu9973sZGRnJ5Zdfnu3bt4+de8EFF+Suu+7KQw89lPXr1+fK\nK6+c9nqFTQAAgB5w2mmnpa+vLx/96Eezbdu2PP/883nggQdy55135umnn05fX1/mz5+fhx9+ONdd\nd92OWWJz11135dvf/naee+65zJ8/PwceeGDmzp077fUKmwAAALvR1zeQamWP6XlU7e/ZnDlzcttt\nt+Xee+/NkiVL8tKXvjQrVqzI6OhorrrqqqxatSr9/f1ZsWJFli9fPnbeli1bsmLFigwODmbRokU5\n/PDDc/HFF7f9fdkT62wCALvVaDTSaDTGtuv1epKkXq+PbQPMFpOtJcner7MpbAIAU+aPMGC283tu\ncnsbNg2jBQAAoDhhEwAAgOKETQAAAIoTNgEAAChO2AQAAKA4YRMAAIDihE0AAACKEzYBAAB6wKJF\ni7JmzZpOlzFlwiYAAMBu9B/an1qtNm2P/kP7p1THjuN7xbxOFwAAANDNRkdGk6FpbH9odPoa7yA9\nmwAAAD1i3bp1ecUrXpHBwcG8/e1vz7PPPpvh4eGcffbZOeKIIzI4OJhzzjknjz/++Ng5N910U44/\n/vj09/dnyZIlWbVq1dhzN954Y5YuXZrBwcGcddZZ2bhxY7FahU0AAIAe0Gw2s2rVqqxevTrf//73\ns379+nz4wx9Os9nMO97xjmzcuDEbN27MQQcdlJUrVyZJtm7dmgsvvDBf/epXs2XLltxxxx151ate\nlSS59dZb85GPfCRf/OIX8+STT+a1r31tzjvvvGL1CpsAAAA9oFarZeXKlTn66KMzMDCQD33oQ7n5\n5pszODiY173udTnwwANzyCGH5IMf/GDWrl07dt6cOXNy//33Z9u2bTnyyCOzdOnSJMn111+fSy65\n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\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAABCtpXKAAAgAElEQVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMB1uSvJf9/Kc\ng5J8JclTST47heMfSHL6Xl4DAHZpXqcLAIBZrJ7kfyY5pkBbzdZjb/xmkiOSDCbZPoXjf35viwKA\nyczpdAEAwJTV9vL445Ksz9SC5p7MLdAGAADAtFuY5PNJfpTk75Jc0No/lOTPk/yPJFtSDe38F+PO\nOznJ37Se+0zrsWN46VuT3D7hOtuTLGlt/5MkVyXZkOSJJNclObDAubtycJJtSZ5PMtqq96gkpyW5\nI8lwkk1Jrk1ywLjzrk7ywyQjSf42ydLW/k+Ne519Sb6V5JrdXP+yJM8m+Wnr+m9rvZZvJnkyyY+T\n/GmSBePOeTTJma3toSSfS9UzO5Lk7bu5FgDsRM8mAJ0wJ9W9hPekCp2/kuR9SZa1nj8nyc2pgtCX\nk/xRa/9LknwpVRAdSHJLktdn6sNL/+8k/yzJSa1/j07yB9N07tYkZ6UKlH1J+lOF1J8luTDJYUle\nk+q1/4fWOf8myWuT/PNUr/2NSTaPa7PZOm9NqmD8vt1c/z8nuSJVGO9LFVZrSS5P8nNJXp5qeO/Q\nhPbH+41U3+MFSVbt5loAAABd4ZdS9RCOd0mSG1OFpNXj9i9N8kxr+/Qkj08476+S/JfW9lszee9k\nLcnTeaGnMqnC3t8VOHcy9SSP7eGY9yX5Qmv7zCTfTfX9mfgfwp9K8idJ7k/yH/fQ5g5DqXomJ3Nu\nql7iHX6QF/dsNqZ4HQDYiQmCAOiE41L1aA6P2zc3yf+XKoT+cNz+Z1INV53TOmdi2JwYWifz0iTz\nk9w9bl8tUxvl0865E70syR+mGho8P9Vn8V2t576Zqhf3E6m+R19I8vuphsHWkvx6a/u/7cN1k+TI\nJB9P8supejvn5MU9pxP9/T5eBwAMowWgIzam6kUbGPfoT3L2Hs77h1TDV8c7btz21lQBboejxm0/\nmeoeyqXjrnlo67rtnjuZXQ3vvS7JQ6mG4i5I8qG8+PP42iSntq71siQXj2vrj5N8LclfTqh1qte/\nItU9pD/fuvbvZvd/C+zt7LcAMEbYBKAT1qXqofs/U60FOTdVADp1D+fdkeqex/emmlTn9Ul+cdzz\n9yV5Rar7Kg/Mi+9H3J4qrF2TqqcyqYLrsgLnTuaHqe6xHB9KD0n12p9JcmKS38sLoe7UVENoD2g9\n/4+pwmHywky0K1MNtf1Kdj9B0fhzxl97a6rJio7OC0EWAIoTNgHohO2pejFfleq+xx8nuSEvzIw6\nsUdtx9c/TRUw35rkJ0l+K9VQ0x2han2q+ze/kSqQ3T6hrQ8k+V6S/5VqhtWvp+o9bPfcyTycaqKj\nv0s1XPWoVMNi35Qq8N2QagKfHfpb+zanmhn2ySRXjvse7KhnRaohrl9KNUvuZCauzXlZklNa9X8l\n1WzAk/Ve7su6ngBQ1IWpJit4oLUNADNp/JIgAECXaLdn8+eTvDPVEKaTUv0v9fHtFgUAe2HiUFEA\noAu0GzZPTPLtvHBPydpUw5sAYKZ0erjnB1Pdgznx8RczdP0HJ7n+eTN0fQCYFiemuq9lMNWseHek\nmlIdAACA/Vi762w+nOT/SbX49tYk96Sa9GHMSSed1LzvvvvavAwAAABd6r5Uk/69SOn7XK5ItXba\n9eP2NZtNk9ntydDQUIaGhjpdBrOI9xSleU9RmvcUpXlPUZL309TVarVkF9my3Z7NJDkiyY+SHJvk\ndanWBwMAAGA/ViJsfi7VgtXPJfkPqdYNAwAAYD9WImyeXqCN/V69Xu90Ccwy3lOU5j1Fad5TlOY9\nRUneT+2bibXJ3LMJAAAwS03nPZsAAACzwuDgYIaHhztdRlcaGBjI5s2bp3y8nk0AAICWWq0W+WXX\nJvveTNazOWcGagIAAGA/I2wCAABQnLAJAABAccImAAAAxQmbAAAAu9HfP5harTZtj/7+wU6/xGlh\nNloAAICWXc24Ws22Op2ZpjdmwDUbLQAAAB0nbAIAAPSITZs25Q1veEOOOOKILFmyJNdee22SZN26\ndXnNa16TgYGBLFy4MBdccEGee+65sfMuuuiiHHnkkVmwYEFe+cpX5sEHH5z2WoVNAACAHrB9+/ac\nc845Ofnkk7Np06asWbMm11xzTVavXp158+bl4x//eH7yk5/kjjvuyJo1a/LJT34ySfK1r30tt99+\nex555JGMjIzklltuyWGHHTbt9QqbAAAAPeDOO+/Mk08+mUsvvTTz5s3L4sWL8853vjOf+cxncsop\np+S0007LnDlzctxxx2XFihVZu3ZtkuSAAw7I6OhovvOd72T79u054YQTctRRR017vfOm/QoAAAC0\nbcOGDdm0aVMGBgbG9j3//PM5/fTT88gjj+Siiy7K3XffnWeeeSY/+9nPcuqppyZJzjzzzKxcuTLv\nec97smHDhrz+9a/PVVddlb6+vmmtV88mAABADzj22GOzePHiDA8Pjz22bNmS2267Leeff36WLl2a\n733vexkZGcnll1+e7du3j517wQUX5K677spDDz2U9evX58orr5z2eoVNAACAHnDaaaelr68vH/3o\nR7Nt27Y8//zzeeCBB3LnnXfm6aefTl9fX+bPn5+HH34411133Y4lSXLXXXfl29/+dp577rnMnz8/\nBx54YObOnTvt9QqbAAAAu9HXN5BqGcnpeVTt79mcOXNy22235d57782SJUvy0pe+NCtWrMjo6Giu\nuuqqrFq1Kv39/VmxYkWWL18+dt6WLVuyYsWKDA4OZtGiRTn88MNz8cUXt/192ZOdFt6cBs1eWKB0\nbzQajTQajbHter2eJKnX62PbAABA76nVaplt+aWUyb43rR7UnbKlsNkmb0YAAJg9/H0/ub0Nm2aj\nnSX0tgIAAN1Ez2abuvF/PrqxJgAA6AX+lp7c3vZsmiAIAACA4oRNAAAAihM2AQAAKE7YBAAAoDhh\nEwAAgOKETQAAgN3oP7Q/tVpt2h79h/ZPqY5FixZlzZo10/xqy7HOJgAAwG6MjowmQ9PY/tDolI7b\nEU57hZ5NAAAAihM2AQAAesS6devyile8IoODg3n729+eZ599NsPDwzn77LNzxBFHZHBwMOecc04e\nf/zxsXNuuummHH/88env78+SJUuyatWqseduvPHGLF26NIODgznrrLOycePGYrUKmwAAAD2g2Wxm\n1apVWb16db7//e9n/fr1+fCHP5xms5l3vOMd2bhxYzZu3JiDDjooK1euTJJs3bo1F154Yb761a9m\ny5YtueOOO/KqV70qSXLrrbfmIx/5SL74xS/mySefzGtf+9qcd955xeoVNgEAAHpArVbLypUrc/TR\nR2dgYCAf+tCHcvPNN2dwcDCve93rcuCBB+aQQw7JBz/4waxdu3bsvDlz5uT+++/Ptm3bcuSRR2bp\n0qVJkuuvvz6XXHJJTjjhhMyZMyeXXHJJ7r333jz22GNF6hU2AQAAesQxxxwztn3sscdm06ZN2bZt\n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\nHJz7bAIAADB1wiYAAADlhE0AAADKCZsAAACUEzYBAAAoJ2wCAABQTtgEAACgnLAJAABAOWETAABg\nBmzfvj3XXHPNtNsYm7AJAABwCPMnzKfX663aY/6E+bH62Lf+rNg87QYAAAC6bLhnmAxWsf5guHrF\np8iZTQAAgBlxww035OlPf3q2bduWn//5n893v/vd7N69OxdccEGe8IQnZNu2bXn+85+fr33ta0vv\n+b3f+708+clPzvz8fM4444xcddVVS//33ve+N2eeeWa2bduW888/P3fffXdZr8ImAADADFhcXMxV\nV12Vq6++Ol/5yldy22235Zd/+ZezuLiYV7ziFbn77rtz991357GPfWwuvfTSJMn999+fyy+/PB//\n+MezsLCQT33qUznrrLOSJB/+8Ifz5je/OR/84AfzrW99K895znPyohe9qKxfYRMAAGAG9Hq9XHrp\npTnllFOydevW/NIv/VLe9773Zdu2bXnBC16QY445Jscff3ze8IY35Lrrrlt636ZNm3LzzTfngQce\nyEknnZQzzzwzSfKud70rV1xxRZ7ylKdk06ZNueKKK3LTTTflnnvuKelX2AQAAJgRp5566tLyaaed\nlnvvvTcPPPBAfvEXfzHbt2/Pli1bcu6552bPnj1ZXFzMcccdlz/+4z/Ou971rpx88sm54IIL8qUv\nfSlJctddd+Xyyy/P1q1bs3Xr1jzucY9LkkcMwZ2EsAkAADAjll9Teffdd+fkk0/OW9/61tx22225\n4YYbsmfPnlx33XVZXFzM4uJikuS8887L1VdfnW984xt56lOfmosvvjhJG1bf/e53Z/fu3UuP+++/\nP8961rNKehU2AQAAZsDi4mJ+67d+K1/72teya9euvOlNb8pFF12U4XCYxz72sdmyZUt27dqVnTt3\nLr3nr//6r/PhD384999/f44++ugcd9xxOeqoo5Ikr3zlK/Mrv/IrueWWW5Ike/bsyQc+8IGyft36\nBAAA4BDmtsyt6u1J5rbMjbVer9fLS17ykpx33nm59957c+GFF+aNb3xjdu/enRe/+MU58cQTc8op\np+Q1r3lNPvKRjyRJ9u7dm7e97W152ctell6vl7PPPjvvfOc7kyQXXnhhvv3tb+eiiy7KXXfdlS1b\ntuS8887Lz/zMz5R8XWtxR9DFfadvAYDZ1uv10rXP9S72BMwuP1MO7mDfm16vl6yQLQ2jBQAAoJyw\n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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], "source": [ - "def plot_all_functions(df):\n", - " functions = df.index.get_level_values(2).unique()\n", - " fcount = len(functions)\n", - "\n", - " fig, pltaxes = plt.subplots(fcount, 1, figsize=(16, 8*fcount))\n", - "\n", - " fig_id = 0\n", - " for fname in functions:\n", - " logging.info(\"Plotting stats for [%s] function\", fname)\n", - " if fcount > 1:\n", - " axes = pltaxes[fig_id]\n", - " else:\n", - " axes = pltaxes\n", - " plot_stats(df, fname, axes)\n", - " fig_id = fig_id + 1\n", - " \n", - "plot_all_functions(stats_df)" + "for function in functions:\n", + " plot_hits(df, function)\n", + " plot_time_avg(df, function)" ] } ], @@ -800,16 +1363,16 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.5.2" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/ipynb/tests/synthetics_example.ipynb b/ipynb/tests/synthetics_example.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..deba7df7a6938b6fa74e76e264e953c2b7dd6e7c --- /dev/null +++ b/ipynb/tests/synthetics_example.ipynb @@ -0,0 +1,686 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Synthetic test example" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:38:18,902 INFO : root : Using LISA logging configuration:\n", + "2018-12-12 18:38:18,903 INFO : root : /data/work/lisa/logging.conf\n" + ] + } + ], + "source": [ + "import logging\n", + "from lisa.utils import setup_logging\n", + "setup_logging()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Target configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:38:18,924 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/Grammar.txt\n", + "2018-12-12 18:38:18,948 INFO : root : Generating grammar tables from /usr/lib/python3.5/lib2to3/PatternGrammar.txt\n" + ] + } + ], + "source": [ + "from lisa.env import TestEnv, TargetConf" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# This is information only relevant to create a\n", + "# connection between the host and the target\n", + "target_conf = TargetConf({\n", + " \"kind\" : \"linux\",\n", + " \"name\" : \"hikey960\",\n", + " \"host\": \"192.168.0.1\",\n", + " \"username\" : \"root\",\n", + " \"password\" : \"root\",\n", + "})" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:38:19,652 INFO : lisa.env.TestEnv : Target configuration:\n", + "|- username from user (str): root\n", + "|- host from user (str): 192.168.0.1\n", + "|- password from user (str): root\n", + "|- name from user (str): hikey960\n", + "|- kind from user (str): linux\n", + "+- devlib:\n", + " +- platform:\n", + " |- class from default (str): devlib.platform.Platform\n", + "+- ftrace:\n", + " |- buffsize from default (int): 10240\n", + "2018-12-12 18:38:19,725 INFO : lisa.env.TestEnv : User-defined platform information:\n", + "|- name from target-conf (str): hikey960\n", + "2018-12-12 18:38:19,760 INFO : lisa.env.TestEnv : linux hikey960 target connection settings:\n", + "2018-12-12 18:38:19,761 INFO : lisa.env.TestEnv : username : root\n", + "2018-12-12 18:38:19,763 INFO : lisa.env.TestEnv : host : 192.168.0.1\n", + "2018-12-12 18:38:19,764 INFO : lisa.env.TestEnv : password : root\n", + "2018-12-12 18:38:19,765 INFO : lisa.env.TestEnv : port : 22\n", + "2018-12-12 18:38:19,785 INFO : lisa.env.TestEnv : Devlib modules to load: bl, cgroups, cpufreq, cpuidle, devfreq, fastboot, gem5stats, gpufreq, hotplug, hwmon, mbed-fan, odroidxu3-fan, sched, thermal\n", + "2018-12-12 18:38:24,499 WARNING : LinuxTarget : Module devfreq is not supported by the target\n", + "2018-12-12 18:38:24,501 WARNING : LinuxTarget : Module fastboot is not supported by the target\n", + "2018-12-12 18:38:24,502 WARNING : LinuxTarget : Module gem5stats is not supported by the target\n", + "2018-12-12 18:38:24,670 WARNING : LinuxTarget : Module gpufreq is not supported by the target\n", + "2018-12-12 18:38:25,355 WARNING : LinuxTarget : Module odroidxu3-fan is not supported by the target\n", + "2018-12-12 18:38:27,334 INFO : CGroups : Available controllers:\n", + "2018-12-12 18:38:27,860 INFO : CGroups : cpuset : /root/devlib-target/cgroups/devlib_cgh6\n", + "2018-12-12 18:38:28,379 INFO : CGroups : cpu : /root/devlib-target/cgroups/devlib_cgh4\n", + "2018-12-12 18:38:28,904 INFO : CGroups : cpuacct : /root/devlib-target/cgroups/devlib_cgh4\n", + "2018-12-12 18:38:29,423 INFO : CGroups : blkio : /root/devlib-target/cgroups/devlib_cgh9\n", + "2018-12-12 18:38:29,950 INFO : CGroups : memory : /root/devlib-target/cgroups/devlib_cgh2\n", + "2018-12-12 18:38:30,472 INFO : CGroups : devices : /root/devlib-target/cgroups/devlib_cgh7\n", + "2018-12-12 18:38:30,994 INFO : CGroups : freezer : /root/devlib-target/cgroups/devlib_cgh3\n", + "2018-12-12 18:38:31,518 INFO : CGroups : perf_event : /root/devlib-target/cgroups/devlib_cgh5\n", + "2018-12-12 18:38:32,036 INFO : CGroups : hugetlb : /root/devlib-target/cgroups/devlib_cgh10\n", + "2018-12-12 18:38:32,559 INFO : CGroups : pids : /root/devlib-target/cgroups/devlib_cgh8\n", + "2018-12-12 18:38:32,731 WARNING : lisa.env.TestEnv : Failed to initialized \"devfreq\" devlib Module\n", + "2018-12-12 18:38:32,733 WARNING : lisa.env.TestEnv : Failed to initialized \"fastboot\" devlib Module\n", + "2018-12-12 18:38:32,734 WARNING : lisa.env.TestEnv : Failed to initialized \"gem5stats\" devlib Module\n", + "2018-12-12 18:38:32,735 WARNING : lisa.env.TestEnv : Failed to initialized \"gpufreq\" devlib Module\n", + "2018-12-12 18:38:32,736 WARNING : lisa.env.TestEnv : Failed to initialized \"mbed-fan\" devlib Module\n", + "2018-12-12 18:38:32,737 WARNING : lisa.env.TestEnv : Failed to initialized \"odroidxu3-fan\" devlib Module\n", + "2018-12-12 18:38:32,739 INFO : lisa.platforms.platinfo.PlatformInfo : Attempting to read energy model from target\n", + "2018-12-12 18:38:33,244 INFO : lisa.energy_model.EnergyModel.EMReader : Attempting to load EM using from_simplifiedEM_target\n", + "2018-12-12 18:38:38,566 INFO : lisa.env.TestEnv : Effective platform information:\n", + "|- nrg-model from target (EnergyModel): \n", + "|- freq-domains from target (list): [[0, 1, 2, 3], [4, 5, 6, 7]]\n", + "|- os from target (str): linux\n", + "|- cpus-count from target (int): 8\n", + "|- name from target-conf (str): hikey960\n", + "|- cpu-capacities from target (dict): {0: 462, 1: 462, 2: 462, 3: 462, 4: 1024, 5: 1024, 6: 1024, 7: 1024}\n", + "|- freqs from target (dict): {0: [533000, 999000, 1402000, 1709000, 1844000], 1: [533000, 999000, 1402000, 1709000, 1844000], 2: [533000, 999000, 1402000, 1709000, 1844000], 3: [533000, 999000, 1402000, 1709000, 1844000], 4: [903000, 1421000, 1805000, 2112000, 2362000], 5: [903000, 1421000, 1805000, 2112000, 2362000], 6: [903000, 1421000, 1805000, 2112000, 2362000], 7: [903000, 1421000, 1805000, 2112000, 2362000]}\n", + "|- kernel-version from target (KernelVersion): 4.19.0-rc5-00347-ga58f958 7 SMP PREEMPT Tue Dec 11 14:03:35 GMT 2018\n", + "|- abi from target (str): arm64\n", + "+- rtapp:\n", + " |- calib from target (DeferredValue): \n" + ] + } + ], + "source": [ + "te = TestEnv(target_conf)\n", + "target = te.target" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Live target experimentation" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from lisa.tests.kernel.scheduler.eas_behaviour import EnergyModelWakeMigration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We want to create a TestBundle from a live target, so we can use the **from_testenv** alternative constructor:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:38:39,051 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181212_183819.652020/EnergyModelWakeMigration-20181212_183839.050944\n", + "2018-12-12 18:38:56,399 INFO : lisa.env.TestEnv : Creating result directory: /data/work/lisa/results/hikey960-20181212_183819.652020/rta_calib-20181212_183856.399063\n", + "2018-12-12 18:38:56,561 INFO : lisa.wlgen.rta.RTA : CPU0 calibration...\n", + "2018-12-12 18:38:56,881 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU0\n", + "2018-12-12 18:38:56,883 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:38:56,884 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:38:56,885 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:38:56,886 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:38:56,887 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:38:56,888 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:38:56,889 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:38:57,112 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu0.json 2>&1\n", + "2018-12-12 18:39:03,628 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:03,879 INFO : lisa.wlgen.rta.RTA : CPU1 calibration...\n", + "2018-12-12 18:39:04,200 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU1\n", + "2018-12-12 18:39:04,202 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:04,203 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:04,204 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:04,205 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:04,206 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:04,207 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:04,208 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:04,420 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu1.json 2>&1\n", + "2018-12-12 18:39:10,932 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:11,191 INFO : lisa.wlgen.rta.RTA : CPU2 calibration...\n", + "2018-12-12 18:39:11,513 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU2\n", + "2018-12-12 18:39:11,514 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:11,515 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:11,517 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:11,518 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:11,518 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:11,519 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:11,520 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:11,732 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu2.json 2>&1\n", + "2018-12-12 18:39:18,244 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:18,495 INFO : lisa.wlgen.rta.RTA : CPU3 calibration...\n", + "2018-12-12 18:39:18,817 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU3\n", + "2018-12-12 18:39:18,819 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:18,820 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:18,821 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:18,822 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:18,823 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:18,824 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:18,825 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:19,037 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu3.json 2>&1\n", + "2018-12-12 18:39:25,549 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:25,801 INFO : lisa.wlgen.rta.RTA : CPU4 calibration...\n", + "2018-12-12 18:39:26,124 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU4\n", + "2018-12-12 18:39:26,125 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:26,126 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:26,127 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:26,129 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:26,130 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:26,131 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:26,132 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:26,360 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu4.json 2>&1\n", + "2018-12-12 18:39:32,705 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:32,963 INFO : lisa.wlgen.rta.RTA : CPU5 calibration...\n", + "2018-12-12 18:39:33,285 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU5\n", + "2018-12-12 18:39:33,287 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:33,289 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:33,290 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:33,291 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:33,293 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:33,293 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:33,295 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:33,512 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu5.json 2>&1\n", + "2018-12-12 18:39:39,859 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:40,120 INFO : lisa.wlgen.rta.RTA : CPU6 calibration...\n", + "2018-12-12 18:39:40,442 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU6\n", + "2018-12-12 18:39:40,444 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:40,446 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:40,447 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:40,449 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:40,450 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:40,452 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:40,453 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:40,668 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu6.json 2>&1\n", + "2018-12-12 18:39:47,015 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:47,269 INFO : lisa.wlgen.rta.RTA : CPU7 calibration...\n", + "2018-12-12 18:39:47,592 INFO : lisa.wlgen.rta.RTA : Calibration value: CPU7\n", + "2018-12-12 18:39:47,593 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n", + "2018-12-12 18:39:47,595 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:47,596 INFO : lisa.wlgen.rta.RTA : task [task1], sched: using default policy\n", + "2018-12-12 18:39:47,597 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:47,598 INFO : lisa.wlgen.rta.RTA : | loops count: 1\n", + "2018-12-12 18:39:47,599 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:47,600 INFO : lisa.wlgen.rta.Phase : | batch 0.001000 [s]\n", + "2018-12-12 18:39:47,832 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_calib_cpu7.json 2>&1\n", + "2018-12-12 18:39:54,178 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:39:54,430 INFO : lisa.wlgen.rta.RTA : Target RT-App calibration: {0: 307, 1: 302, 2: 302, 3: 302, 4: 155, 5: 155, 6: 155, 7: 155}\n", + "2018-12-12 18:39:57,430 INFO : lisa.wlgen.rta.RTA : Calibration value: 155\n", + "2018-12-12 18:39:57,431 INFO : lisa.wlgen.rta.RTA : Default policy: SCHED_OTHER\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2018-12-12 18:39:57,432 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:57,433 INFO : lisa.wlgen.rta.RTA : task [emwm_2], sched: using default policy\n", + "2018-12-12 18:39:57,435 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:57,436 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", + "2018-12-12 18:39:57,437 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:57,438 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,439 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", + "2018-12-12 18:39:57,441 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", + "2018-12-12 18:39:57,441 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", + "2018-12-12 18:39:57,443 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,444 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", + "2018-12-12 18:39:57,445 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", + "2018-12-12 18:39:57,446 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:57,447 INFO : lisa.wlgen.rta.RTA : task [emwm_0], sched: using default policy\n", + "2018-12-12 18:39:57,449 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:57,450 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", + "2018-12-12 18:39:57,450 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:57,451 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,452 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", + "2018-12-12 18:39:57,452 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", + "2018-12-12 18:39:57,453 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", + "2018-12-12 18:39:57,453 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,454 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", + "2018-12-12 18:39:57,459 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", + "2018-12-12 18:39:57,460 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:57,461 INFO : lisa.wlgen.rta.RTA : task [emwm_3], sched: using default policy\n", + "2018-12-12 18:39:57,462 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:57,462 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", + "2018-12-12 18:39:57,463 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:57,464 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,464 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", + "2018-12-12 18:39:57,465 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", + "2018-12-12 18:39:57,465 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", + "2018-12-12 18:39:57,466 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,467 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", + "2018-12-12 18:39:57,467 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", + "2018-12-12 18:39:57,468 INFO : lisa.wlgen.rta.RTA : ------------------------\n", + "2018-12-12 18:39:57,468 INFO : lisa.wlgen.rta.RTA : task [emwm_1], sched: using default policy\n", + "2018-12-12 18:39:57,469 INFO : lisa.wlgen.rta.RTA : | start delay: 0.000000 [s]\n", + "2018-12-12 18:39:57,469 INFO : lisa.wlgen.rta.RTA : | loops count: 2\n", + "2018-12-12 18:39:57,470 INFO : lisa.wlgen.rta.RTA : + phase_000001\n", + "2018-12-12 18:39:57,470 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,471 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 9 %\n", + "2018-12-12 18:39:57,471 INFO : lisa.wlgen.rta.Phase : | run_time 1440 [us], sleep_time 14560 [us]\n", + "2018-12-12 18:39:57,472 INFO : lisa.wlgen.rta.RTA : + phase_000002\n", + "2018-12-12 18:39:57,473 INFO : lisa.wlgen.rta.Phase : | duration 2.000000 [s] (125 loops)\n", + "2018-12-12 18:39:57,473 INFO : lisa.wlgen.rta.Phase : | period 16000 [us], duty_cycle 70 %\n", + "2018-12-12 18:39:57,474 INFO : lisa.wlgen.rta.Phase : | run_time 11200 [us], sleep_time 4800 [us]\n", + "2018-12-12 18:40:04,049 INFO : lisa.env.TestEnv : Freezing all tasks except: init,systemd,dbus,sh,ssh,rsyslogd,jbd2\n", + "2018-12-12 18:40:05,939 INFO : lisa.wlgen.rta.RTA : Execution start: /root/devlib-target/bin/rt-app /root/devlib-target/rta_energymodelwakemigration.json 2>&1\n", + "2018-12-12 18:40:14,445 INFO : lisa.wlgen.rta.RTA : Execution complete\n", + "2018-12-12 18:40:16,009 INFO : lisa.env.TestEnv : Un-freezing userspace tasks\n" + ] + } + ], + "source": [ + "bundle = EnergyModelWakeMigration.from_testenv(te)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now have a **TestBundle** instance. We're free to play around with its data, more specifically to execute some tests related to this data:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PASSED: emwm_0 slack=2.8 %, emwm_2 slack=6.8 %, emwm_1 slack=2.8 %, emwm_3 slack=1.0 %\n" + ] + } + ], + "source": [ + "print(bundle.test_slack())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whenever possible, we want to expose test margins to the end user. Here, we can change the failure threshold, and for the sake of demonstration we'll set it way too low (and expect a failure)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "FAILED: emwm_0 slack=2.8 %, emwm_2 slack=6.8 %, emwm_1 slack=2.8 %, emwm_3 slack=1.0 %\n" + ] + } + ], + "source": [ + "print(bundle.test_slack(negative_slack_allowed_pct=1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This test also produces a plot, let's run it and have a look" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PASSED: estimated energy=10123.446619136426 bogo-joules, energy threshold=12697.384476751002 bogo-joules\n" + ] + } + ], + "source": [ + "print(bundle.test_task_placement())" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "from trappy.plotter import plot_trace" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "\n", + "\n", + "\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_trace(bundle.trace.ftrace, execnames=list(bundle.rtapp_profile.keys()))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from IPython.display import Image" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "image_path = os.path.join(bundle.res_dir, \"expected_placement.png\")\n", + "Image(image_path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Offline replaying" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Say someone executed some tests, and ran into some issues. They can create an archive of the results directory and send it your way, and you'll be able to reload it automagically. This also works if you are working on the test code itself, and don't want to re-execute the workload every single time you change the code." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's just reuse what was generated in the previous run\n", + "archive_dir = bundle.res_dir" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "reloaded_bundle = EnergyModelWakeMigration.from_dir(archive_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Just to prove we're not cheating!\n", + "reloaded_bundle == bundle" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PASSED: estimated energy=10123.446619136426 bogo-joules, energy threshold=12697.384476751002 bogo-joules\n" + ] + } + ], + "source": [ + "print(reloaded_bundle.test_task_placement())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}