Michele Di Giorgio | 068887b | 2016-03-04 15:17:50 +0000 | [diff] [blame] | 1 | { |
| 2 | "cells": [ |
| 3 | { |
| 4 | "cell_type": "markdown", |
| 5 | "metadata": {}, |
| 6 | "source": [ |
| 7 | "# Thermal Sensor Measurements" |
| 8 | ] |
| 9 | }, |
| 10 | { |
| 11 | "cell_type": "markdown", |
| 12 | "metadata": {}, |
| 13 | "source": [ |
| 14 | "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", |
| 15 | "\n", |
| 16 | "Measurements must be done **with** and **without** fan." |
| 17 | ] |
| 18 | }, |
| 19 | { |
| 20 | "cell_type": "code", |
| 21 | "execution_count": null, |
| 22 | "metadata": { |
| 23 | "collapsed": false |
| 24 | }, |
| 25 | "outputs": [], |
| 26 | "source": [ |
| 27 | "import logging\n", |
Patrick Bellasi | f17e608 | 2016-11-28 15:24:15 +0000 | [diff] [blame] | 28 | "from conf import LisaLogging\n", |
| 29 | "LisaLogging.setup()" |
Michele Di Giorgio | 068887b | 2016-03-04 15:17:50 +0000 | [diff] [blame] | 30 | ] |
| 31 | }, |
| 32 | { |
| 33 | "cell_type": "code", |
| 34 | "execution_count": null, |
| 35 | "metadata": { |
| 36 | "collapsed": false |
| 37 | }, |
| 38 | "outputs": [], |
| 39 | "source": [ |
| 40 | "%pylab inline\n", |
| 41 | "\n", |
| 42 | "import os\n", |
| 43 | "\n", |
| 44 | "# Support to access the remote target\n", |
| 45 | "import devlib\n", |
| 46 | "from env import TestEnv\n", |
| 47 | "\n", |
| 48 | "# Support to configure and run RTApp based workloads\n", |
| 49 | "from wlgen import RTA, Periodic\n", |
| 50 | "\n", |
| 51 | "# Support for trace events analysis\n", |
| 52 | "from trace import Trace\n", |
Michele Di Giorgio | 068887b | 2016-03-04 15:17:50 +0000 | [diff] [blame] | 53 | "\n", |
| 54 | "# Suport for FTrace events parsing and visualization\n", |
| 55 | "import trappy" |
| 56 | ] |
| 57 | }, |
| 58 | { |
| 59 | "cell_type": "markdown", |
| 60 | "metadata": {}, |
| 61 | "source": [ |
| 62 | "# Target Configuration" |
| 63 | ] |
| 64 | }, |
| 65 | { |
| 66 | "cell_type": "markdown", |
| 67 | "metadata": {}, |
| 68 | "source": [ |
| 69 | "Our target is a Juno R2 development board running Linux." |
| 70 | ] |
| 71 | }, |
| 72 | { |
| 73 | "cell_type": "code", |
| 74 | "execution_count": null, |
| 75 | "metadata": { |
| 76 | "collapsed": false |
| 77 | }, |
| 78 | "outputs": [], |
| 79 | "source": [ |
| 80 | "# Setup a target configuration\n", |
| 81 | "my_target_conf = {\n", |
| 82 | " \n", |
| 83 | " # Target platform and board\n", |
| 84 | " \"platform\" : 'linux',\n", |
| 85 | " \"board\" : 'juno',\n", |
| 86 | " \n", |
| 87 | " # Target board IP/MAC address\n", |
Michele Di Giorgio | d1ac554 | 2016-07-22 16:42:04 +0100 | [diff] [blame] | 88 | " \"host\" : '192.168.0.1',\n", |
Michele Di Giorgio | 068887b | 2016-03-04 15:17:50 +0000 | [diff] [blame] | 89 | " \n", |
| 90 | " # Login credentials\n", |
| 91 | " \"username\" : 'root',\n", |
| 92 | " \"password\" : '',\n", |
| 93 | " \n", |
| 94 | " # RTApp calibration values (comment to let LISA do a calibration run)\n", |
| 95 | " \"rtapp-calib\" : {\n", |
| 96 | " \"0\": 318, \"1\": 125, \"2\": 124, \"3\": 318, \"4\": 318, \"5\": 319\n", |
| 97 | " },\n", |
| 98 | " \n", |
| 99 | " # Tools required by the experiments\n", |
| 100 | " \"tools\" : [ 'rt-app', 'trace-cmd' ], \n", |
| 101 | " \"exclude_modules\" : ['hwmon'],\n", |
| 102 | " \n", |
| 103 | " # FTrace events to collect for all the tests configuration which have\n", |
| 104 | " # the \"ftrace\" flag enabled\n", |
| 105 | " \"ftrace\" : {\n", |
| 106 | " \"events\" : [\n", |
| 107 | " \"thermal_temperature\",\n", |
| 108 | " # Use sched_switch event to recognize tasks on kernelshark\n", |
| 109 | " \"sched_switch\",\n", |
| 110 | " # cdev_update has been used to show that \"step_wise\" thermal governor introduces noise\n", |
| 111 | " # because it keeps changing the state of the cooling devices and therefore\n", |
| 112 | " # the available OPPs\n", |
| 113 | " #\"cdev_update\",\n", |
| 114 | " ],\n", |
| 115 | " \"buffsize\" : 80 * 1024,\n", |
| 116 | " },\n", |
| 117 | "}" |
| 118 | ] |
| 119 | }, |
| 120 | { |
| 121 | "cell_type": "markdown", |
| 122 | "metadata": {}, |
| 123 | "source": [ |
| 124 | "# Tests execution" |
| 125 | ] |
| 126 | }, |
| 127 | { |
| 128 | "cell_type": "code", |
| 129 | "execution_count": null, |
| 130 | "metadata": { |
| 131 | "collapsed": false, |
| 132 | "scrolled": true |
| 133 | }, |
| 134 | "outputs": [], |
| 135 | "source": [ |
| 136 | "# Initialize a test environment using:\n", |
| 137 | "# the provided target configuration (my_target_conf)\n", |
| 138 | "te = TestEnv(target_conf=my_target_conf)\n", |
| 139 | "target = te.target" |
| 140 | ] |
| 141 | }, |
| 142 | { |
| 143 | "cell_type": "markdown", |
| 144 | "metadata": {}, |
| 145 | "source": [ |
| 146 | "# Workloads configuration" |
| 147 | ] |
| 148 | }, |
| 149 | { |
| 150 | "cell_type": "code", |
| 151 | "execution_count": null, |
| 152 | "metadata": { |
| 153 | "collapsed": false, |
| 154 | "scrolled": true |
| 155 | }, |
| 156 | "outputs": [], |
| 157 | "source": [ |
| 158 | "# Create a new RTApp workload generator using the calibration values\n", |
| 159 | "# reported by the TestEnv module\n", |
| 160 | "rtapp_big = RTA(target, 'big', calibration=te.calibration())\n", |
| 161 | "\n", |
| 162 | "big_tasks = dict()\n", |
| 163 | "for cpu in target.bl.bigs:\n", |
| 164 | " big_tasks['busy_big'+str(cpu)] = Periodic(duty_cycle_pct=100,\n", |
| 165 | " duration_s=360, # 6 minutes\n", |
| 166 | " cpus=str(cpu) # pinned to a given cpu\n", |
| 167 | " ).get()\n", |
| 168 | "\n", |
| 169 | "# Configure this RTApp instance to:\n", |
| 170 | "rtapp_big.conf(\n", |
| 171 | " # 1. generate a \"profile based\" set of tasks\n", |
| 172 | " kind='profile',\n", |
| 173 | " \n", |
| 174 | " # 2. define the \"profile\" of each task\n", |
| 175 | " params=big_tasks,\n", |
| 176 | " \n", |
| 177 | " # 3. Set load reference for task calibration\n", |
| 178 | " loadref='big',\n", |
| 179 | " \n", |
| 180 | " # 4. use this folder for task logfiles\n", |
| 181 | " run_dir=target.working_directory\n", |
| 182 | ");" |
| 183 | ] |
| 184 | }, |
| 185 | { |
| 186 | "cell_type": "code", |
| 187 | "execution_count": null, |
| 188 | "metadata": { |
| 189 | "collapsed": false, |
| 190 | "scrolled": true |
| 191 | }, |
| 192 | "outputs": [], |
| 193 | "source": [ |
| 194 | "rtapp_little = RTA(target, 'little', calibration=te.calibration())\n", |
| 195 | "\n", |
| 196 | "little_tasks = dict()\n", |
| 197 | "for cpu in target.bl.littles:\n", |
| 198 | " little_tasks['busy_little'+str(cpu)] = Periodic(duty_cycle_pct=100,\n", |
| 199 | " duration_s=360,\n", |
| 200 | " cpus=str(cpu)).get()\n", |
| 201 | "\n", |
| 202 | "rtapp_little.conf(\n", |
| 203 | " kind='profile',\n", |
| 204 | " params=little_tasks,\n", |
| 205 | " # Allow the task duration to be calibrated for the littles (default is for big)\n", |
| 206 | " loadref='little',\n", |
| 207 | " run_dir=target.working_directory\n", |
| 208 | ");" |
| 209 | ] |
| 210 | }, |
| 211 | { |
| 212 | "cell_type": "markdown", |
| 213 | "metadata": {}, |
| 214 | "source": [ |
| 215 | "# Workload execution" |
| 216 | ] |
| 217 | }, |
| 218 | { |
| 219 | "cell_type": "code", |
| 220 | "execution_count": null, |
| 221 | "metadata": { |
| 222 | "collapsed": false, |
| 223 | "scrolled": true |
| 224 | }, |
| 225 | "outputs": [], |
| 226 | "source": [ |
| 227 | "logging.info('#### Setup FTrace')\n", |
| 228 | "te.ftrace.start()\n", |
| 229 | "\n", |
| 230 | "logging.info('#### Start RTApp execution')\n", |
| 231 | "# Run tasks on the bigs in background to allow execution of following instruction\n", |
| 232 | "rtapp_big.run(out_dir=te.res_dir, background=True)\n", |
| 233 | "# Run tasks on the littles and then wait 2 minutes for device to cool down\n", |
| 234 | "rtapp_little.run(out_dir=te.res_dir, end_pause_s=120.0)\n", |
| 235 | "\n", |
| 236 | "logging.info('#### Stop FTrace')\n", |
| 237 | "te.ftrace.stop()" |
| 238 | ] |
| 239 | }, |
| 240 | { |
| 241 | "cell_type": "markdown", |
| 242 | "metadata": { |
| 243 | "collapsed": false |
| 244 | }, |
| 245 | "source": [ |
| 246 | "# Trace Analysis" |
| 247 | ] |
| 248 | }, |
| 249 | { |
| 250 | "cell_type": "markdown", |
| 251 | "metadata": { |
| 252 | "collapsed": false |
| 253 | }, |
| 254 | "source": [ |
| 255 | "In order to analyze the trace we will plot it using `TRAPpy`." |
| 256 | ] |
| 257 | }, |
| 258 | { |
| 259 | "cell_type": "code", |
| 260 | "execution_count": null, |
| 261 | "metadata": { |
| 262 | "collapsed": false |
| 263 | }, |
| 264 | "outputs": [], |
| 265 | "source": [ |
| 266 | "# Collect the trace\n", |
| 267 | "trace_file = os.path.join(te.res_dir, 'trace.dat')\n", |
| 268 | "logging.info('#### Save FTrace: %s', trace_file)\n", |
| 269 | "te.ftrace.get_trace(trace_file)\n", |
| 270 | "# Parse trace\n", |
| 271 | "therm_trace = trappy.FTrace(trace_file)" |
| 272 | ] |
| 273 | }, |
| 274 | { |
| 275 | "cell_type": "code", |
| 276 | "execution_count": null, |
| 277 | "metadata": { |
| 278 | "collapsed": false |
| 279 | }, |
| 280 | "outputs": [], |
| 281 | "source": [ |
| 282 | "therm_trace.thermal.data_frame.tail(10)" |
| 283 | ] |
| 284 | }, |
| 285 | { |
| 286 | "cell_type": "code", |
| 287 | "execution_count": null, |
| 288 | "metadata": { |
| 289 | "collapsed": false |
| 290 | }, |
| 291 | "outputs": [], |
| 292 | "source": [ |
| 293 | "# Plot the data\n", |
| 294 | "therm_plot = trappy.ILinePlot(therm_trace,\n", |
| 295 | " signals=['thermal:temp'],\n", |
| 296 | " filters={'thermal_zone': [\"soc\"]},\n", |
| 297 | " title='Juno R2 SoC Temperature w/o fans')\n", |
| 298 | "therm_plot.view()" |
| 299 | ] |
| 300 | }, |
| 301 | { |
| 302 | "cell_type": "markdown", |
| 303 | "metadata": { |
| 304 | "collapsed": false |
| 305 | }, |
| 306 | "source": [ |
| 307 | "The `pmic` sensor if off-chip and therefore it is not useful to get its temperature." |
| 308 | ] |
| 309 | }, |
| 310 | { |
| 311 | "cell_type": "code", |
| 312 | "execution_count": null, |
| 313 | "metadata": { |
| 314 | "collapsed": true |
| 315 | }, |
| 316 | "outputs": [], |
| 317 | "source": [ |
| 318 | "# Extract a data frame for each zone\n", |
| 319 | "df = therm_trace.thermal.data_frame\n", |
| 320 | "soc_df = df[df.thermal_zone == \"soc\"]\n", |
| 321 | "big_df = df[df.thermal_zone == \"big_cluster\"]\n", |
| 322 | "little_df = df[df.thermal_zone == \"little_cluster\"]\n", |
| 323 | "gpu0_df = df[df.thermal_zone == \"gpu0\"]\n", |
| 324 | "gpu1_df = df[df.thermal_zone == \"gpu1\"]\n", |
| 325 | "# Build new trace\n", |
| 326 | "juno_trace = trappy.BareTrace(name = \"Juno_R2\")\n", |
| 327 | "juno_trace.add_parsed_event(\"SoC\", soc_df)\n", |
| 328 | "juno_trace.add_parsed_event(\"big_Cluster\", big_df)\n", |
| 329 | "juno_trace.add_parsed_event(\"LITTLE_Cluster\", little_df)\n", |
| 330 | "juno_trace.add_parsed_event(\"gpu0\", gpu0_df)\n", |
| 331 | "juno_trace.add_parsed_event(\"gpu1\", gpu1_df)" |
| 332 | ] |
| 333 | }, |
| 334 | { |
| 335 | "cell_type": "code", |
| 336 | "execution_count": null, |
| 337 | "metadata": { |
| 338 | "collapsed": false |
| 339 | }, |
| 340 | "outputs": [], |
| 341 | "source": [ |
| 342 | "# Plot the data for all sensors\n", |
| 343 | "juno_signals = ['SoC:temp', 'big_Cluster:temp', 'LITTLE_Cluster:temp', 'gpu0:temp', 'gpu1:temp']\n", |
| 344 | "therm_plot = trappy.ILinePlot([juno_trace],\n", |
| 345 | " signals=juno_signals,\n", |
| 346 | " title='Juno R2 Temperature all traces')\n", |
| 347 | "therm_plot.view()" |
| 348 | ] |
| 349 | } |
| 350 | ], |
| 351 | "metadata": { |
| 352 | "kernelspec": { |
| 353 | "display_name": "Python 2", |
| 354 | "language": "python", |
| 355 | "name": "python2" |
| 356 | }, |
| 357 | "language_info": { |
| 358 | "codemirror_mode": { |
| 359 | "name": "ipython", |
| 360 | "version": 2 |
| 361 | }, |
| 362 | "file_extension": ".py", |
| 363 | "mimetype": "text/x-python", |
| 364 | "name": "python", |
| 365 | "nbconvert_exporter": "python", |
| 366 | "pygments_lexer": "ipython2", |
| 367 | "version": "2.7.6" |
| 368 | } |
| 369 | }, |
| 370 | "nbformat": 4, |
| 371 | "nbformat_minor": 0 |
| 372 | } |