| { |
| "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", |
| "from conf import LisaLogging\n", |
| "LisaLogging.setup()" |
| ] |
| }, |
| { |
| "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", |
| "\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\" : '192.168.0.1',\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 |
| } |