ipynb: add thermal section for thermal-related notebooks
Signed-off-by: Michele Di Giorgio <michele.digiorgio@arm.com>
diff --git a/ipynb/thermal/ThermalSensorCharacterisation.ipynb b/ipynb/thermal/ThermalSensorCharacterisation.ipynb
new file mode 100644
index 0000000..30e2a0f
--- /dev/null
+++ b/ipynb/thermal/ThermalSensorCharacterisation.ipynb
@@ -0,0 +1,377 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Thermal Sensor Measurements"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The goal of this experiment is to measure temperature on Juno R2 board using the available sensors. In order to do that we will run a busy-loop workload of about 5 minutes and collect traces for the `thermal_temperature` event.\n",
+ "\n",
+ "Measurements must be done **with** and **without** fan."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "import logging\n",
+ "reload(logging)\n",
+ "log_fmt = '%(asctime)-9s %(levelname)-8s: %(message)s'\n",
+ "logging.basicConfig(format=log_fmt)\n",
+ "\n",
+ "# Change to info once the notebook runs ok\n",
+ "logging.getLogger().setLevel(logging.DEBUG)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "%pylab inline\n",
+ "\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, Periodic\n",
+ "\n",
+ "# Support for trace events analysis\n",
+ "from trace import Trace\n",
+ "from trace_analysis import TraceAnalysis\n",
+ "\n",
+ "# Suport for FTrace events parsing and visualization\n",
+ "import trappy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Target Configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Our target is a Juno R2 development board running Linux."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Setup a target configuration\n",
+ "my_target_conf = {\n",
+ " \n",
+ " # Target platform and board\n",
+ " \"platform\" : 'linux',\n",
+ " \"board\" : 'juno',\n",
+ " \n",
+ " # Target board IP/MAC address\n",
+ " \"host\" : '10.1.205.135',\n",
+ " \n",
+ " # Login credentials\n",
+ " \"username\" : 'root',\n",
+ " \"password\" : '',\n",
+ " \n",
+ " # RTApp calibration values (comment to let LISA do a calibration run)\n",
+ " \"rtapp-calib\" : {\n",
+ " \"0\": 318, \"1\": 125, \"2\": 124, \"3\": 318, \"4\": 318, \"5\": 319\n",
+ " },\n",
+ " \n",
+ " # Tools required by the experiments\n",
+ " \"tools\" : [ 'rt-app', 'trace-cmd' ], \n",
+ " \"exclude_modules\" : ['hwmon'],\n",
+ " \n",
+ " # FTrace events to collect for all the tests configuration which have\n",
+ " # the \"ftrace\" flag enabled\n",
+ " \"ftrace\" : {\n",
+ " \"events\" : [\n",
+ " \"thermal_temperature\",\n",
+ " # Use sched_switch event to recognize tasks on kernelshark\n",
+ " \"sched_switch\",\n",
+ " # cdev_update has been used to show that \"step_wise\" thermal governor introduces noise\n",
+ " # because it keeps changing the state of the cooling devices and therefore\n",
+ " # the available OPPs\n",
+ " #\"cdev_update\",\n",
+ " ],\n",
+ " \"buffsize\" : 80 * 1024,\n",
+ " },\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Tests execution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "# Initialize a test environment using:\n",
+ "# the provided target configuration (my_target_conf)\n",
+ "te = TestEnv(target_conf=my_target_conf)\n",
+ "target = te.target"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Workloads configuration"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "# Create a new RTApp workload generator using the calibration values\n",
+ "# reported by the TestEnv module\n",
+ "rtapp_big = RTA(target, 'big', calibration=te.calibration())\n",
+ "\n",
+ "big_tasks = dict()\n",
+ "for cpu in target.bl.bigs:\n",
+ " big_tasks['busy_big'+str(cpu)] = Periodic(duty_cycle_pct=100,\n",
+ " duration_s=360, # 6 minutes\n",
+ " cpus=str(cpu) # pinned to a given cpu\n",
+ " ).get()\n",
+ "\n",
+ "# Configure this RTApp instance to:\n",
+ "rtapp_big.conf(\n",
+ " # 1. generate a \"profile based\" set of tasks\n",
+ " kind='profile',\n",
+ " \n",
+ " # 2. define the \"profile\" of each task\n",
+ " params=big_tasks,\n",
+ " \n",
+ " # 3. Set load reference for task calibration\n",
+ " loadref='big',\n",
+ " \n",
+ " # 4. use this folder for task logfiles\n",
+ " run_dir=target.working_directory\n",
+ ");"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "rtapp_little = RTA(target, 'little', calibration=te.calibration())\n",
+ "\n",
+ "little_tasks = dict()\n",
+ "for cpu in target.bl.littles:\n",
+ " little_tasks['busy_little'+str(cpu)] = Periodic(duty_cycle_pct=100,\n",
+ " duration_s=360,\n",
+ " cpus=str(cpu)).get()\n",
+ "\n",
+ "rtapp_little.conf(\n",
+ " kind='profile',\n",
+ " params=little_tasks,\n",
+ " # Allow the task duration to be calibrated for the littles (default is for big)\n",
+ " loadref='little',\n",
+ " run_dir=target.working_directory\n",
+ ");"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Workload execution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "logging.info('#### Setup FTrace')\n",
+ "te.ftrace.start()\n",
+ "\n",
+ "logging.info('#### Start RTApp execution')\n",
+ "# Run tasks on the bigs in background to allow execution of following instruction\n",
+ "rtapp_big.run(out_dir=te.res_dir, background=True)\n",
+ "# Run tasks on the littles and then wait 2 minutes for device to cool down\n",
+ "rtapp_little.run(out_dir=te.res_dir, end_pause_s=120.0)\n",
+ "\n",
+ "logging.info('#### Stop FTrace')\n",
+ "te.ftrace.stop()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": false
+ },
+ "source": [
+ "# Trace Analysis"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": false
+ },
+ "source": [
+ "In order to analyze the trace we will plot it using `TRAPpy`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Collect the trace\n",
+ "trace_file = os.path.join(te.res_dir, 'trace.dat')\n",
+ "logging.info('#### Save FTrace: %s', trace_file)\n",
+ "te.ftrace.get_trace(trace_file)\n",
+ "# Parse trace\n",
+ "therm_trace = trappy.FTrace(trace_file)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "therm_trace.thermal.data_frame.tail(10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Plot the data\n",
+ "therm_plot = trappy.ILinePlot(therm_trace,\n",
+ " signals=['thermal:temp'],\n",
+ " filters={'thermal_zone': [\"soc\"]},\n",
+ " title='Juno R2 SoC Temperature w/o fans')\n",
+ "therm_plot.view()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": false
+ },
+ "source": [
+ "The `pmic` sensor if off-chip and therefore it is not useful to get its temperature."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# Extract a data frame for each zone\n",
+ "df = therm_trace.thermal.data_frame\n",
+ "soc_df = df[df.thermal_zone == \"soc\"]\n",
+ "big_df = df[df.thermal_zone == \"big_cluster\"]\n",
+ "little_df = df[df.thermal_zone == \"little_cluster\"]\n",
+ "gpu0_df = df[df.thermal_zone == \"gpu0\"]\n",
+ "gpu1_df = df[df.thermal_zone == \"gpu1\"]\n",
+ "# Build new trace\n",
+ "juno_trace = trappy.BareTrace(name = \"Juno_R2\")\n",
+ "juno_trace.add_parsed_event(\"SoC\", soc_df)\n",
+ "juno_trace.add_parsed_event(\"big_Cluster\", big_df)\n",
+ "juno_trace.add_parsed_event(\"LITTLE_Cluster\", little_df)\n",
+ "juno_trace.add_parsed_event(\"gpu0\", gpu0_df)\n",
+ "juno_trace.add_parsed_event(\"gpu1\", gpu1_df)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# Plot the data for all sensors\n",
+ "juno_signals = ['SoC:temp', 'big_Cluster:temp', 'LITTLE_Cluster:temp', 'gpu0:temp', 'gpu1:temp']\n",
+ "therm_plot = trappy.ILinePlot([juno_trace],\n",
+ " signals=juno_signals,\n",
+ " title='Juno R2 Temperature all traces')\n",
+ "therm_plot.view()"
+ ]
+ }
+ ],
+ "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.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}