In [1]:
import logging
from conf import LisaLogging
LisaLogging.setup()


2018-02-23 11:49:28,317 INFO    : root         : Using LISA logging configuration:
2018-02-23 11:49:28,319 INFO    : root         :   /home/vagrant/lisa/logging.conf

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

import json
import os

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

# Support for FTrace events parsing and visualization
import trappy

# Support to configure and run RTApp based workloads
from wlgen import RTA, Ramp, Step, Pulse, Periodic


Populating the interactive namespace from numpy and matplotlib

Test environment setup


In [3]:
# Setup a target configuration
my_conf = {
    # Define the kind of target platform to use for the experiments
    "platform"    : 'linux',  # Linux system, valid other options are:
                              # android - access via ADB
                              # linux   - access via SSH
                              # host    - direct access

    # Preload settings for a specific target
    "board"       : 'hikey960',   # load JUNO specific settings, e.g.
                              # - HWMON based energy sampling
                              # - Juno energy model
                              # valid options are:
                              # - juno  - JUNO Development Board
                              # - tc2   - TC2 Development Board
                              # - oak   - Mediatek MT63xx based target

    # Define devlib module to load
    "modules"     : [
        'bl',           # enable big.LITTLE support
        'cpufreq',       # enable CPUFreq support
        'hwmon'
    ],

    # Binary tools required to run this experiment
    # These tools must be present in the tools/ folder for the architecture
    "tools"   : ['rt-app', 'taskset', 'trace-cmd'],

    # FTrace events end buffer configuration
    "ftrace"  : {
         "events" : [
             "sched_switch",
             "cpu_frequency"
         ],
         "buffsize" : 10240
    },

    # Account to access the remote target
    "host"        : '192.168.0.1',
    "username"    : 'root',
    "password"    : 'root',

    # Comment the following line to force rt-app calibration on your target
    #"rtapp-calib" : {
    #    '0': 361, '1': 138, '2': 138, '3': 352, '4': 360, '5': 353
    #}
    "rtapp-calib" :  {
        "0": 302, "1": 302, "2": 302, "3": 302, "4": 136, "5": 136, "6": 136, "7": 136
     },
}

In [4]:
te = TestEnv(target_conf=my_conf)
target = te.target


2018-02-23 11:49:28,952 INFO    : TestEnv      : Using base path: /data/work/lisa
2018-02-23 11:49:28,953 INFO    : TestEnv      : Loading custom (inline) target configuration
2018-02-23 11:49:28,954 INFO    : TestEnv      : Devlib modules to load: ['bl', 'cpuidle', 'cpufreq', 'hwmon']
2018-02-23 11:49:28,955 INFO    : TestEnv      : Connecting linux target:
2018-02-23 11:49:28,956 INFO    : TestEnv      :   username : root
2018-02-23 11:49:28,956 INFO    : TestEnv      :       host : 192.168.0.1
2018-02-23 11:49:28,957 INFO    : TestEnv      :   password : root
2018-02-23 11:49:28,958 INFO    : TestEnv      : Connection settings:
2018-02-23 11:49:28,958 INFO    : TestEnv      :    {'username': 'root', 'host': '192.168.0.1', 'password': 'root'}
2018-02-23 11:49:32,580 INFO    : TestEnv      : Initializing target workdir:
2018-02-23 11:49:32,582 INFO    : TestEnv      :    /root/devlib-target
2018-02-23 11:49:35,880 INFO    : TestEnv      : Attempting to read energy model from target
2018-02-23 11:49:36,039 ERROR   : TestEnv      : Couldn't read target energy model: Energy Model not exposed in sysfs. Check CONFIG_SCHED_DEBUG is enabled.
2018-02-23 11:49:36,042 INFO    : TestEnv      : Topology:
2018-02-23 11:49:36,043 INFO    : TestEnv      :    [[0, 1, 2, 3], [4, 5, 6, 7]]
2018-02-23 11:49:36,661 INFO    : TestEnv      : Loading default EM:
2018-02-23 11:49:36,663 INFO    : TestEnv      :    /data/work/lisa/libs/utils/platforms/hikey960.json
2018-02-23 11:49:37,482 INFO    : TestEnv      : Enabled tracepoints:
2018-02-23 11:49:37,483 INFO    : TestEnv      :    sched_switch
2018-02-23 11:49:37,483 INFO    : TestEnv      :    cpu_frequency
2018-02-23 11:49:37,484 WARNING : TestEnv      : Using configuration provided RTApp calibration
2018-02-23 11:49:37,485 INFO    : TestEnv      : Using RT-App calibration values:
2018-02-23 11:49:37,485 INFO    : TestEnv      :    {"0": 302, "1": 302, "2": 302, "3": 302, "4": 136, "5": 136, "6": 136, "7": 136}
2018-02-23 11:49:37,486 INFO    : TestEnv      : Set results folder to:
2018-02-23 11:49:37,487 INFO    : TestEnv      :    /data/work/lisa/results/20180223_114928
2018-02-23 11:49:37,487 INFO    : TestEnv      : Experiment results available also in:
2018-02-23 11:49:37,488 INFO    : TestEnv      :    /data/work/lisa/results_latest

Create a new RTA workload generator object

The wlgen::RTA class is a workload generator which exposes an API to configure RTApp based workload as well as to execute them on a target.


In [5]:
# Create a new RTApp workload generator
rtapp = RTA(
    
    target=te.target, # Target execution on the local machine
    
    name='example', # This is the name of the JSON configuration file reporting
                    # the generated RTApp configuration
    
    #calibration={0: 10, 1: 11, 2: 12, 3: 13} # These are a set of fake
    #                                         # calibration values
)


2018-02-23 11:49:37,493 INFO    : Workload     : Setup new workload example

The function here, build_perf_benchmark_rtapp, demonstrates how we can build an rt-app job description which uses a controller task to unblock a number of child tasks, which then each perform a set amount of work. This is intended to simulate performance benchmarks. Many aspects of the test can be configured via parameters.


In [6]:
def build_perf_benchmark_rtapp(run_duration_ms, calibration_cpu_name, num_tasks, iterations, logdir="/data/local/tmp", file_name="perfbench.json"):
    # static content
    json_content = { 
        'global': {
            'calibration': calibration_cpu_name,
            'default_policy': "SCHED_OTHER",
            'duration': -1,
            'logdir': logdir
        },
        'tasks': {
           'controller': {
                'loop': iterations+2, 
                'phases': {
                    'init_delay': {
                        'sleep': run_duration_ms*4
                    }
                }
            }
        }
    }
    # dynamic content (number of tasks)
    for cpu in range(0,num_tasks):
        bench_thread_name = "bench{}".format(cpu)
        # describe the worker thread
        json_content['tasks'][bench_thread_name] = {
                'loop': iterations, 
                'phases': {
                    'go': {
                        'run': run_duration_ms
                    }, 
                    'wait': {
                        'suspend': bench_thread_name
                    }
                }
            }
        # hook it to the controller
        json_content['tasks']['controller']['phases']["trigger{}".format(cpu)] = { 'resume': bench_thread_name }
    
    with open(file_name, 'w') as outfile:
            json.dump(json_content, outfile,
                    sort_keys=True, indent=4, separators=(',', ': '))
    return (file_name, json_content)

In [7]:
run_duration_ms = 500000
calibration = 'CPU4'
num_tasks = 8
iterations = 8

(filename, inline_config)=build_perf_benchmark_rtapp(run_duration_ms, calibration, num_tasks, iterations)

# Configure this RTApp instance to:
name=rtapp.conf(
    # 1. generate a "profile based" set of tasks
    #kind='profile',
    kind='custom',
    duration=-1,    
    # 2. define the "profile" of each task
    # to use inline job description:
    params=inline_config,
    # to use filename instead:
    #    params="{}".format(filename),

    # 3. use this folder for task logfiles
    run_dir='/data/local/tmp'
)

logging.info('Generated RTApp JSON:')
print json.dumps(inline_config, indent=4, sort_keys=True)


2018-02-23 11:49:37,703 INFO    : Workload     : Loading custom configuration:
2018-02-23 11:49:37,704 INFO    : Workload     :    {'tasks': {'bench0': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench0'}}, 'loop': 8}, 'bench1': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench1'}}, 'loop': 8}, 'bench2': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench2'}}, 'loop': 8}, 'bench3': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench3'}}, 'loop': 8}, 'bench4': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench4'}}, 'loop': 8}, 'bench5': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench5'}}, 'loop': 8}, 'bench6': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench6'}}, 'loop': 8}, 'bench7': {'phases': {'go': {'run': 500000}, 'wait': {'suspend': 'bench7'}}, 'loop': 8}, 'controller': {'phases': {'trigger4': {'resume': 'bench4'}, 'trigger5': {'resume': 'bench5'}, 'trigger6': {'resume': 'bench6'}, 'trigger7': {'resume': 'bench7'}, 'trigger0': {'resume': 'bench0'}, 'trigger1': {'resume': 'bench1'}, 'trigger2': {'resume': 'bench2'}, 'trigger3': {'resume': 'bench3'}, 'init_delay': {'sleep': 2000000}}, 'loop': 10}}, 'global': {'duration': -1, 'logdir': '/data/local/tmp', 'default_policy': 'SCHED_OTHER', 'calibration': 'CPU4'}}
2018-02-23 11:49:38,057 INFO    : root         : Generated RTApp JSON:
{
    "global": {
        "calibration": "CPU4", 
        "default_policy": "SCHED_OTHER", 
        "duration": -1, 
        "logdir": "/data/local/tmp"
    }, 
    "tasks": {
        "bench0": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench0"
                }
            }
        }, 
        "bench1": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench1"
                }
            }
        }, 
        "bench2": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench2"
                }
            }
        }, 
        "bench3": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench3"
                }
            }
        }, 
        "bench4": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench4"
                }
            }
        }, 
        "bench5": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench5"
                }
            }
        }, 
        "bench6": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench6"
                }
            }
        }, 
        "bench7": {
            "loop": 8, 
            "phases": {
                "go": {
                    "run": 500000
                }, 
                "wait": {
                    "suspend": "bench7"
                }
            }
        }, 
        "controller": {
            "loop": 10, 
            "phases": {
                "init_delay": {
                    "sleep": 2000000
                }, 
                "trigger0": {
                    "resume": "bench0"
                }, 
                "trigger1": {
                    "resume": "bench1"
                }, 
                "trigger2": {
                    "resume": "bench2"
                }, 
                "trigger3": {
                    "resume": "bench3"
                }, 
                "trigger4": {
                    "resume": "bench4"
                }, 
                "trigger5": {
                    "resume": "bench5"
                }, 
                "trigger6": {
                    "resume": "bench6"
                }, 
                "trigger7": {
                    "resume": "bench7"
                }
            }
        }
    }
}

In [10]:
te.ftrace.start()

logging.info('#### Start RTApp execution')
rtapp.run(cgroup="")

logging.info('#### Stop FTrace')
te.ftrace.stop()

trace_file = os.path.join(te.res_dir, 'trace.dat')
logging.info('#### Save FTrace: %s', trace_file)
te.ftrace.get_trace(trace_file)

logging.info('#### Save platform description: %s/platform.json', te.res_dir)
(plt, plt_file) = te.platform_dump(te.res_dir)

# NOTE: The interactive trace visualization is available only if you run
#       the workload to generate a new trace-file
trappy.plotter.plot_trace(te.res_dir)


2018-02-23 11:52:04,388 INFO    : root         : #### Start RTApp execution
2018-02-23 11:52:04,390 INFO    : Workload     : Workload execution START:
2018-02-23 11:52:04,391 INFO    : Workload     :    /root/devlib-target/bin/rt-app /data/local/tmp/example_00.json 2>&1
2018-02-23 11:52:32,764 INFO    : root         : #### Stop FTrace
2018-02-23 11:52:33,242 INFO    : root         : #### Save FTrace: /data/work/lisa/results/20180223_114928/trace.dat
2018-02-23 11:52:37,195 INFO    : root         : #### Save platform description: /data/work/lisa/results/20180223_114928/platform.json

In [ ]: