ipynb: rtapp: add another example of workload generation
This notebook provides some more example of workloads generation
using the wlgen::RTA "profile" based API.
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
diff --git a/ipynb/wlgen/rtapp_examples.ipynb b/ipynb/wlgen/rtapp_examples.ipynb
new file mode 100644
index 0000000..ac321aa
--- /dev/null
+++ b/ipynb/wlgen/rtapp_examples.ipynb
@@ -0,0 +1,632 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import logging\n",
+ "reload(logging)\n",
+ "logging.basicConfig(\n",
+ " format='%(asctime)-9s %(levelname)-8s: %(message)s',\n",
+ " datefmt='%I:%M:%S')\n",
+ "\n",
+ "# Enable logging at INFO level\n",
+ "logging.getLogger().setLevel(logging.INFO)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Populating the interactive namespace from numpy and matplotlib\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Generate plots inline\n",
+ "%pylab inline\n",
+ "\n",
+ "import json\n",
+ "import os\n",
+ "\n",
+ "# Support to access the remote target\n",
+ "import devlib\n",
+ "from env import TestEnv\n",
+ "\n",
+ "# Support to configure and run RTApp based workloads\n",
+ "from wlgen import RTA"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Test environment setup"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "03:34:27 INFO : Target - Using base path: /home/derkling/Code/schedtest\n",
+ "03:34:27 INFO : Target - Loading custom (inline) target configuration\n",
+ "03:34:27 INFO : Target - Connecing host target with: {'username': 'derkling', 'password': ''}\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sudo password:········\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "03:34:31 INFO : Target - Initializing target workdir [/tmp]\n",
+ "03:34:31 INFO : Target topology: [[0, 1, 2, 3, 4, 5, 6, 7]]\n",
+ "03:34:31 WARNING : Target - Unable to identify cluster frequencies\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Let's use the local host as a target\n",
+ "te = TestEnv(\n",
+ " target_conf={\n",
+ " \"platform\": 'host',\n",
+ " \"username\": 'put_here_your_username'\n",
+ " })"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Create a new RTA workload generator object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The wlgen::RTA class is a workload generator which exposes an API to configure\n",
+ "RTApp based workload as well as to execute them on a target."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "03:34:31 INFO : Setup new workload example\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Create a new RTApp workload generator\n",
+ "rtapp = RTA(\n",
+ " \n",
+ " target=te.target, # Target execution on the local machine\n",
+ " \n",
+ " name='example', # This is the name of the JSON configuration file reporting\n",
+ " # the generated RTApp configuration\n",
+ " \n",
+ " calibration={0: 10, 1: 11, 2: 12, 3: 13} # These are a set of fake\n",
+ " # calibration values\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Workload Generation Examples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Single periodic task"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "An RTApp workload is defined by specifying a **kind**, which represents the way\n",
+ "we want to defined the behavior of each task.<br>\n",
+ "The most common kind is **profile**, which allows to define each task using one\n",
+ "of the predefined **profile** supported by the RTA base class.<br>\n",
+ "<br>\n",
+ "The following example shows how to generate a \"periodic\" task<br>"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "code_folding": [],
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "03:34:31 INFO : Workload duration defined by longest task\n",
+ "03:34:31 INFO : Default policy: SCHED_OTHER\n",
+ "03:34:31 INFO : ------------------------\n",
+ "03:34:31 INFO : task [task_per20], sched: {'policy': 'FIFO'}\n",
+ "03:34:31 INFO : | calibration CPU: 0\n",
+ "03:34:31 INFO : | loops count: 1\n",
+ "03:34:31 INFO : + phase_000001: duration 5.000000 [s] (50 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 20 %\n",
+ "03:34:31 INFO : | run_time 20000 [us], sleep_time 80000 [us]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Configure this RTApp instance to:\n",
+ "rtapp.conf(\n",
+ " \n",
+ " # 1. generate a \"profile based\" set of tasks\n",
+ " kind='profile',\n",
+ " \n",
+ " # 2. define the \"profile\" of each task\n",
+ " params={\n",
+ " \n",
+ " # 3. PERIODIC task\n",
+ " # \n",
+ " # This class defines a task which load is periodic with a configured\n",
+ " # period and duty-cycle.\n",
+ " # \n",
+ " # This class is a specialization of the 'pulse' class since a periodic\n",
+ " # load is generated as a sequence of pulse loads.\n",
+ " # \n",
+ " # Args:\n",
+ " # cuty_cycle_pct (int, [0-100]): the pulses load [%]\n",
+ " # default: 50[%]\n",
+ " # duration_s (float): the duration in [s] of the entire workload\n",
+ " # default: 1.0[s]\n",
+ " # period_ms (float): the period used to define the load in [ms]\n",
+ " # default: 100.0[ms]\n",
+ " # delay_s (float): the delay in [s] before ramp start\n",
+ " # default: 0[s]\n",
+ " # sched (dict): the scheduler configuration for this task\n",
+ " 'task_per20': RTA.periodic(\n",
+ " period_ms=100, # period\n",
+ " duty_cycle_pct=20, # duty cycle\n",
+ " duration_s=5, # duration\n",
+ " cpus=None, # run on all CPUS\n",
+ " sched={\n",
+ " \"policy\": \"FIFO\", # Run this task as a SCHED_FIFO task\n",
+ " },\n",
+ " delay_s=0 # start at the start of RTApp\n",
+ " ),\n",
+ " \n",
+ " },\n",
+ " \n",
+ " # 4. use this folder for task logfiles\n",
+ " run_dir='/tmp'\n",
+ " \n",
+ ");"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The output of the previous cell reports the main properties of the generated\n",
+ "tasks. Thus for example we see that the first task is configure to be:\n",
+ "1. named **task_per20**\n",
+ "2. will be executed as a **SCHED_FIFO** task\n",
+ "3. generating a load which is **calibrated** with respect to the **CPU 0**\n",
+ "3. with one single \"phase\" which defines a peripodic load for the **duration** of **5[s]**\n",
+ "4. that periodic load consistes of **50 cycles**\n",
+ "5. each cycle has a **period** of **100[ms]** and a **duty-cycle** of **20%**\n",
+ "6. which means that the task, for every cycle, will **run** for **20[ms]** and then sleep for **20[ms]** \n",
+ "\n",
+ "All these properties are translated into a JSON configuration file for RTApp.<br>\n",
+ "Let see what it looks like the generated configuration file:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{\n",
+ " \"tasks\": {\n",
+ " \"task_per20\": {\n",
+ " \"policy\": \"SCHED_FIFO\", \n",
+ " \"phases\": {\n",
+ " \"p000001\": {\n",
+ " \"run\": 20000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_per20\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 50\n",
+ " }\n",
+ " }, \n",
+ " \"loop\": 1\n",
+ " }\n",
+ " }, \n",
+ " \"global\": {\n",
+ " \"duration\": -1, \n",
+ " \"logdir\": \"/tmp\", \n",
+ " \"default_policy\": \"SCHED_OTHER\", \n",
+ " \"calibration\": 10\n",
+ " }\n",
+ "}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Dump the configured JSON file for that task\n",
+ "with open(\"./example_00.json\") as fh:\n",
+ " rtapp_config = json.load(fh)\n",
+ "print json.dumps(rtapp_config, indent=4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Workload mix"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Using the wlgen::RTA workload generator we can easily create multiple tasks, each one with different \"profiles\", which are executed once the rtapp application is started in the target.<br>\n",
+ "<br>\n",
+ "In the following example we configure a workload mix composed by a RAMP task, a STEP task and a PULSE task:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "code_folding": [],
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "03:34:31 INFO : Workload duration defined by longest task\n",
+ "03:34:31 INFO : Default policy: SCHED_OTHER\n",
+ "03:34:31 INFO : ------------------------\n",
+ "03:34:31 INFO : task [task_pls5-80], sched: using default policy\n",
+ "03:34:31 INFO : | start delay: 0.500000 [s]\n",
+ "03:34:31 INFO : | calibration CPU: 0\n",
+ "03:34:31 INFO : | loops count: 1\n",
+ "03:34:31 INFO : + phase_000001: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 65 %\n",
+ "03:34:31 INFO : | run_time 65000 [us], sleep_time 35000 [us]\n",
+ "03:34:31 INFO : + phase_000002: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 5 %\n",
+ "03:34:31 INFO : | run_time 5000 [us], sleep_time 95000 [us]\n",
+ "03:34:31 INFO : ------------------------\n",
+ "03:34:31 INFO : task [task_rmp20_5-60], sched: using default policy\n",
+ "03:34:31 INFO : | calibration CPU: 0\n",
+ "03:34:31 INFO : | loops count: 1\n",
+ "03:34:31 INFO : | CPUs affinity: 0\n",
+ "03:34:31 INFO : + phase_000001: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 5 %\n",
+ "03:34:31 INFO : | run_time 5000 [us], sleep_time 95000 [us]\n",
+ "03:34:31 INFO : + phase_000002: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 25 %\n",
+ "03:34:31 INFO : | run_time 25000 [us], sleep_time 75000 [us]\n",
+ "03:34:31 INFO : + phase_000003: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 45 %\n",
+ "03:34:31 INFO : | run_time 45000 [us], sleep_time 55000 [us]\n",
+ "03:34:31 INFO : + phase_000004: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 65 %\n",
+ "03:34:31 INFO : | run_time 65000 [us], sleep_time 35000 [us]\n",
+ "03:34:31 INFO : ------------------------\n",
+ "03:34:31 INFO : task [task_stp10-50], sched: using default policy\n",
+ "03:34:31 INFO : | start delay: 0.500000 [s]\n",
+ "03:34:31 INFO : | calibration CPU: 0\n",
+ "03:34:31 INFO : | loops count: 1\n",
+ "03:34:31 INFO : + phase_000001: sleep 1.000000 [s]\n",
+ "03:34:31 INFO : + phase_000002: duration 1.000000 [s] (10 loops)\n",
+ "03:34:31 INFO : | period 100000 [us], duty_cycle 50 %\n",
+ "03:34:31 INFO : | run_time 50000 [us], sleep_time 50000 [us]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Configure this RTApp instance to:\n",
+ "rtapp.conf(\n",
+ " # 1. generate a \"profile based\" set of tasks\n",
+ " kind='profile',\n",
+ " \n",
+ " # 2. define the \"profile\" of each task\n",
+ " params={\n",
+ " \n",
+ " # 3. RAMP task\n",
+ " #\n",
+ " # This class defines a task which load is a ramp with a configured number\n",
+ " # of steps according to the input parameters.\n",
+ " # \n",
+ " # Args:\n",
+ " # start_pct (int, [0-100]): the initial load [%], (default 0[%])\n",
+ " # end_pct (int, [0-100]): the final load [%], (default 100[%])\n",
+ " # delta_pct (int, [0-100]): the load increase/decrease [%],\n",
+ " # default: 10[%]\n",
+ " # increase if start_prc < end_prc\n",
+ " # decrease if start_prc > end_prc\n",
+ " # time_s (float): the duration in [s] of each load step\n",
+ " # default: 1.0[s]\n",
+ " # period_ms (float): the period used to define the load in [ms]\n",
+ " # default: 100.0[ms]\n",
+ " # delay_s (float): the delay in [s] before ramp start\n",
+ " # default: 0[s]\n",
+ " # loops (int): number of time to repeat the ramp, with the\n",
+ " # specified delay in between\n",
+ " # default: 0\n",
+ " # sched (dict): the scheduler configuration for this task\n",
+ " # cpus (list): the list of CPUs on which task can run\n",
+ " 'task_rmp20_5-60': RTA.ramp(\n",
+ " period_ms=100, # period\n",
+ " start_pct=5, # intial load\n",
+ " end_pct=65, # end load\n",
+ " delta_pct=20, # load % increase...\n",
+ " time_s=1, # ... every 1[s]\n",
+ " cpus=\"0\" # run just on first CPU\n",
+ " ),\n",
+ " \n",
+ " # 4. STEP task\n",
+ " # \n",
+ " # This class defines a task which load is a step with a configured\n",
+ " # initial and final load.\n",
+ " # \n",
+ " # Args:\n",
+ " # start_pct (int, [0-100]): the initial load [%]\n",
+ " # default 0[%])\n",
+ " # end_pct (int, [0-100]): the final load [%]\n",
+ " # default 100[%]\n",
+ " # time_s (float): the duration in [s] of the start and end load\n",
+ " # default: 1.0[s]\n",
+ " # period_ms (float): the period used to define the load in [ms]\n",
+ " # default 100.0[ms]\n",
+ " # delay_s (float): the delay in [s] before ramp start\n",
+ " # default 0[s]\n",
+ " # loops (int): number of time to repeat the ramp, with the\n",
+ " # specified delay in between\n",
+ " # default: 0\n",
+ " # sched (dict): the scheduler configuration for this task\n",
+ " # cpus (list): the list of CPUs on which task can run\n",
+ " 'task_stp10-50': RTA.step(\n",
+ " period_ms=100, # period\n",
+ " start_pct=0, # intial load\n",
+ " end_pct=50, # end load\n",
+ " time_s=1, # ... every 1[s]\n",
+ " delay_s=0.5 # start .5[s] after the start of RTApp\n",
+ " ),\n",
+ " \n",
+ " # 5. PULSE task\n",
+ " #\n",
+ " # This class defines a task which load is a pulse with a configured\n",
+ " # initial and final load.\n",
+ " # \n",
+ " # The main difference with the 'step' class is that a pulse workload is\n",
+ " # by definition a 'step down', i.e. the workload switch from an finial\n",
+ " # load to a final one which is always lower than the initial one.\n",
+ " # Moreover, a pulse load does not generate a sleep phase in case of 0[%]\n",
+ " # load, i.e. the task ends as soon as the non null initial load has\n",
+ " # completed.\n",
+ " # \n",
+ " # Args:\n",
+ " # start_pct (int, [0-100]): the initial load [%]\n",
+ " # default: 0[%]\n",
+ " # end_pct (int, [0-100]): the final load [%]\n",
+ " # default: 100[%]\n",
+ " # NOTE: must be lower than start_pct value\n",
+ " # time_s (float): the duration in [s] of the start and end load\n",
+ " # default: 1.0[s]\n",
+ " # NOTE: if end_pct is 0, the task end after the\n",
+ " # start_pct period completed\n",
+ " # period_ms (float): the period used to define the load in [ms]\n",
+ " # default: 100.0[ms]\n",
+ " # delay_s (float): the delay in [s] before ramp start\n",
+ " # default: 0[s]\n",
+ " # loops (int): number of time to repeat the ramp, with the\n",
+ " # specified delay in between\n",
+ " # default: 0\n",
+ " # sched (dict): the scheduler configuration for this task\n",
+ " # cpus (list): the list of CPUs on which task can run\n",
+ " 'task_pls5-80': RTA.pulse(\n",
+ " period_ms=100, # period\n",
+ " start_pct=65, # intial load\n",
+ " end_pct=5, # end load\n",
+ " time_s=1, # ... every 1[s]\n",
+ " delay_s=0.5 # start .5[s] after the start of RTApp\n",
+ " ),\n",
+ " \n",
+ " \n",
+ " },\n",
+ " \n",
+ " # 6. use this folder for task logfiles\n",
+ " run_dir='/tmp'\n",
+ " \n",
+ ");"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{\n",
+ " \"tasks\": {\n",
+ " \"task_rmp20_5-60\": {\n",
+ " \"policy\": \"SCHED_OTHER\", \n",
+ " \"phases\": {\n",
+ " \"p000004\": {\n",
+ " \"run\": 65000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_rmp20_5-60\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000003\": {\n",
+ " \"run\": 45000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_rmp20_5-60\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000002\": {\n",
+ " \"run\": 25000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_rmp20_5-60\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000001\": {\n",
+ " \"run\": 5000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_rmp20_5-60\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }\n",
+ " }, \n",
+ " \"cpus\": [\n",
+ " 0\n",
+ " ], \n",
+ " \"loop\": 1\n",
+ " }, \n",
+ " \"task_pls5-80\": {\n",
+ " \"policy\": \"SCHED_OTHER\", \n",
+ " \"phases\": {\n",
+ " \"p000002\": {\n",
+ " \"run\": 5000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_pls5-80\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000001\": {\n",
+ " \"run\": 65000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_pls5-80\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000000\": {\n",
+ " \"sleep\": 500000\n",
+ " }\n",
+ " }, \n",
+ " \"loop\": 1\n",
+ " }, \n",
+ " \"task_stp10-50\": {\n",
+ " \"policy\": \"SCHED_OTHER\", \n",
+ " \"phases\": {\n",
+ " \"p000002\": {\n",
+ " \"run\": 50000, \n",
+ " \"timer\": {\n",
+ " \"ref\": \"task_stp10-50\", \n",
+ " \"period\": 100000\n",
+ " }, \n",
+ " \"loop\": 10\n",
+ " }, \n",
+ " \"p000001\": {\n",
+ " \"sleep\": 1000000, \n",
+ " \"loop\": 1\n",
+ " }, \n",
+ " \"p000000\": {\n",
+ " \"sleep\": 500000\n",
+ " }\n",
+ " }, \n",
+ " \"loop\": 1\n",
+ " }\n",
+ " }, \n",
+ " \"global\": {\n",
+ " \"duration\": -1, \n",
+ " \"logdir\": \"/tmp\", \n",
+ " \"default_policy\": \"SCHED_OTHER\", \n",
+ " \"calibration\": 10\n",
+ " }\n",
+ "}\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Dump the configured JSON file for that task\n",
+ "with open(\"./example_00.json\") as fh:\n",
+ " rtapp_config = json.load(fh)\n",
+ "print json.dumps(rtapp_config, indent=4)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 2
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython2",
+ "version": "2.7.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}