1 { 2 "metadata": { 3 "kernelspec": { 4 "display_name": "Python 2", 5 "language": "python", 6 "name": "python2" 7 }, 8 "language_info": { 9 "codemirror_mode": { 10 "name": "ipython", 11 "version": 2 12 }, 13 "file_extension": ".py", 14 "mimetype": "text/x-python", 15 "name": "python", 16 "nbconvert_exporter": "python", 17 "pygments_lexer": "ipython2", 18 "version": "2.7.6" 19 }, 20 "name": "", 21 "signature": "sha256:59ef0b9fe2847e77f9df55deeb6df1f94f4fe2a3a0f99e13cba99854e8bf66ed" 22 }, 23 "nbformat": 3, 24 "nbformat_minor": 0, 25 "worksheets": [ 26 { 27 "cells": [ 28 { 29 "cell_type": "heading", 30 "level": 1, 31 "metadata": {}, 32 "source": [ 33 "Configuration" 34 ] 35 }, 36 { 37 "cell_type": "code", 38 "collapsed": false, 39 "input": [ 40 "import trappy\n", 41 "import numpy\n", 42 "\n", 43 "config = {}\n", 44 "\n", 45 "# TRAPpy Events\n", 46 "config[\"THERMAL\"] = trappy.thermal.Thermal\n", 47 "config[\"OUT\"] = trappy.cpu_power.CpuOutPower\n", 48 "config[\"IN\"] = trappy.cpu_power.CpuInPower\n", 49 "config[\"PID\"] = trappy.pid_controller.PIDController\n", 50 "config[\"GOVERNOR\"] = trappy.thermal.ThermalGovernor\n", 51 "\n", 52 "# Control Temperature\n", 53 "config[\"CONTROL_TEMP\"] = 77000\n", 54 "\n", 55 "# A temperature margin of 2.5 degrees Celsius\n", 56 "config[\"TEMP_MARGIN\"] = 2500\n", 57 "\n", 58 "# The Sustainable power at the control Temperature\n", 59 "config[\"SUSTAINABLE_POWER\"] = 2500\n", 60 "\n", 61 "# Expected percentile of CONTROL_TEMP + TEMP_MARGIN\n", 62 "config[\"EXPECTED_TEMP_QRT\"] = 95\n", 63 "\n", 64 "# Maximum expected Standard Deviation as a percentage\n", 65 "# of mean temperature\n", 66 "config[\"EXPECTED_STD_PCT\"] = 5\n" 67 ], 68 "language": "python", 69 "metadata": {}, 70 "outputs": [], 71 "prompt_number": 1 72 }, 73 { 74 "cell_type": "heading", 75 "level": 1, 76 "metadata": {}, 77 "source": [ 78 "Get the Trace" 79 ] 80 }, 81 { 82 "cell_type": "code", 83 "collapsed": false, 84 "input": [ 85 "import urllib\n", 86 "import os\n", 87 "\n", 88 "TRACE_DIR = \"example_trace_dat_thermal\"\n", 89 "TRACE_FILE = os.path.join(TRACE_DIR, 'bart_thermal_trace.dat')\n", 90 "TRACE_URL = 'http://cdn.rawgit.com/sinkap/4e0a69cbff732b57e36f/raw/7dd0ed74bfc17a34a3bd5ea6b9eb3a75a42ddbae/bart_thermal_trace.dat'\n", 91 "\n", 92 "if not os.path.isdir(TRACE_DIR):\n", 93 " os.mkdir(TRACE_DIR)\n", 94 "\n", 95 "if not os.path.isfile(TRACE_FILE):\n", 96 " print \"Fetching trace file..\"\n", 97 " urllib.urlretrieve(TRACE_URL, filename=TRACE_FILE)" 98 ], 99 "language": "python", 100 "metadata": {}, 101 "outputs": [], 102 "prompt_number": 2 103 }, 104 { 105 "cell_type": "heading", 106 "level": 1, 107 "metadata": {}, 108 "source": [ 109 "FTrace Object" 110 ] 111 }, 112 { 113 "cell_type": "code", 114 "collapsed": false, 115 "input": [ 116 "# Create a Trace object\n", 117 "\n", 118 "ftrace = trappy.FTrace(TRACE_FILE, \"SomeBenchMark\")" 119 ], 120 "language": "python", 121 "metadata": {}, 122 "outputs": [], 123 "prompt_number": 3 124 }, 125 { 126 "cell_type": "heading", 127 "level": 1, 128 "metadata": {}, 129 "source": [ 130 "Assertions" 131 ] 132 }, 133 { 134 "cell_type": "code", 135 "collapsed": false, 136 "input": [ 137 "# Create an Assertion Object\n", 138 "\n", 139 "from bart.common.Analyzer import Analyzer\n", 140 "t = Analyzer(ftrace, config)\n", 141 "\n", 142 "BIG = '000000f0'\n", 143 "LITTLE = '0000000f'" 144 ], 145 "language": "python", 146 "metadata": {}, 147 "outputs": [], 148 "prompt_number": 4 149 }, 150 { 151 "cell_type": "heading", 152 "level": 2, 153 "metadata": {}, 154 "source": [ 155 "Assertion: Load and Dynamic Power" 156 ] 157 }, 158 { 159 "cell_type": "markdown", 160 "metadata": {}, 161 "source": [ 162 "<html>\n", 163 "This assertion makes sure that the dynamic power for the each cluster is zero when the sum of the \"loads\" of each CPU is 0\n", 164 "\n", 165 " $$\\forall\\ t\\ |\\ Load(t) = \\sum\\limits_{i=0}^{cpus} Load_i(t) = 0 \\implies dynamic\\ power(t)=0 $$\n", 166 " \n", 167 "</html>" 168 ] 169 }, 170 { 171 "cell_type": "code", 172 "collapsed": false, 173 "input": [ 174 "result = t.getStatement(\"((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \\\n", 175 " & (IN:dynamic_power > 0)\",reference=True, select=BIG)\n", 176 "if len(result):\n", 177 " print \"FAIL: Dynamic Power is NOT Zero when load is Zero for the BIG cluster\"\n", 178 "else:\n", 179 " print \"PASS: Dynamic Power is Zero when load is Zero for the BIG cluster\"\n", 180 "\n", 181 " \n", 182 "result = t.getStatement(\"((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \\\n", 183 " & (IN:dynamic_power > 0)\",reference=True, select=LITTLE)\n", 184 "if len(result):\n", 185 " print \"FAIL: Dynamic Power is NOT Zero when load is Zero for the LITTLE cluster\"\n", 186 "else:\n", 187 " print \"PASS: Dynamic Power is Zero when load is Zero for the LITTLE cluster\"" 188 ], 189 "language": "python", 190 "metadata": {}, 191 "outputs": [ 192 { 193 "output_type": "stream", 194 "stream": "stdout", 195 "text": [ 196 "PASS: Dynamic Power is Zero when load is Zero for the BIG cluster\n", 197 "PASS: Dynamic Power is Zero when load is Zero for the LITTLE cluster\n" 198 ] 199 } 200 ], 201 "prompt_number": 5 202 }, 203 { 204 "cell_type": "heading", 205 "level": 2, 206 "metadata": {}, 207 "source": [ 208 "Assertion: Control Temperature and Sustainable Power" 209 ] 210 }, 211 { 212 "cell_type": "markdown", 213 "metadata": {}, 214 "source": [ 215 "<html>\n", 216 "\n", 217 "When the temperature is greater than the control temperature, the total power granted to all cooling devices should be less than sustainable_power\n", 218 "\n", 219 "$$\\forall\\ t\\ |\\ Temperature(t) > control\\_temp \\implies Total\\ Granted\\ Power(t) < sustainable\\_power$$\n", 220 "\n", 221 "<html/>" 222 ] 223 }, 224 { 225 "cell_type": "code", 226 "collapsed": false, 227 "input": [ 228 "result = t.getStatement(\"(GOVERNOR:current_temperature > CONTROL_TEMP) &\\\n", 229 " (PID:output > SUSTAINABLE_POWER)\", reference=True, select=0)\n", 230 "\n", 231 "if len(result):\n", 232 " print \"FAIL: The Governor is allocating power > sustainable when T > CONTROL_TEMP\"\n", 233 "else:\n", 234 " print \"PASS: The Governor is allocating power <= sustainable when T > CONTROL_TEMP\" " 235 ], 236 "language": "python", 237 "metadata": {}, 238 "outputs": [ 239 { 240 "output_type": "stream", 241 "stream": "stdout", 242 "text": [ 243 "PASS: The Governor is allocating power <= sustainable when T > CONTROL_TEMP\n" 244 ] 245 } 246 ], 247 "prompt_number": 6 248 }, 249 { 250 "cell_type": "heading", 251 "level": 1, 252 "metadata": {}, 253 "source": [ 254 "Statistics" 255 ] 256 }, 257 { 258 "cell_type": "markdown", 259 "metadata": {}, 260 "source": [ 261 "Check if 95% of the temperature readings are below CONTROL_TEMP + MARGIN" 262 ] 263 }, 264 { 265 "cell_type": "code", 266 "collapsed": false, 267 "input": [ 268 "t.assertStatement(\"numpy.percentile(THERMAL:temp, 95) < (CONTROL_TEMP + TEMP_MARGIN)\")" 269 ], 270 "language": "python", 271 "metadata": {}, 272 "outputs": [ 273 { 274 "metadata": {}, 275 "output_type": "pyout", 276 "prompt_number": 7, 277 "text": [ 278 "True" 279 ] 280 } 281 ], 282 "prompt_number": 7 283 }, 284 { 285 "cell_type": "markdown", 286 "metadata": {}, 287 "source": [ 288 "Check if the mean temperauture is less than CONTROL_TEMP" 289 ] 290 }, 291 { 292 "cell_type": "code", 293 "collapsed": false, 294 "input": [ 295 "t.assertStatement(\"numpy.mean(THERMAL:temp) <= CONTROL_TEMP\", select=0)" 296 ], 297 "language": "python", 298 "metadata": {}, 299 "outputs": [ 300 { 301 "metadata": {}, 302 "output_type": "pyout", 303 "prompt_number": 8, 304 "text": [ 305 "True" 306 ] 307 } 308 ], 309 "prompt_number": 8 310 }, 311 { 312 "cell_type": "markdown", 313 "metadata": {}, 314 "source": [ 315 "We can also use getStatement to get the absolute values. Here we are getting the standard deviation expressed as a percentage of the mean" 316 ] 317 }, 318 { 319 "cell_type": "code", 320 "collapsed": false, 321 "input": [ 322 "t.getStatement(\"(numpy.std(THERMAL:temp) * 100.0) / numpy.mean(THERMAL:temp)\", select=0)" 323 ], 324 "language": "python", 325 "metadata": {}, 326 "outputs": [ 327 { 328 "metadata": {}, 329 "output_type": "pyout", 330 "prompt_number": 9, 331 "text": [ 332 "2.2390646863105119" 333 ] 334 } 335 ], 336 "prompt_number": 9 337 }, 338 { 339 "cell_type": "heading", 340 "level": 1, 341 "metadata": {}, 342 "source": [ 343 "Thermal Residency" 344 ] 345 }, 346 { 347 "cell_type": "code", 348 "collapsed": false, 349 "input": [ 350 "from bart.thermal.ThermalAssert import ThermalAssert\n", 351 "\n", 352 "t_assert = ThermalAssert(ftrace)\n", 353 "end = ftrace.get_duration()\n", 354 "\n", 355 "LOW = 0\n", 356 "HIGH = 78000\n", 357 "\n", 358 "# The thermal residency gives the percentage (or absolute time) spent in the\n", 359 "# specified temperature range. \n", 360 "\n", 361 "result = t_assert.getThermalResidency(temp_range=(0, 78000),\n", 362 " window=(0, end),\n", 363 " percent=True)\n", 364 "\n", 365 "for tz_id in result:\n", 366 " print \"Thermal Zone: {} spends {:.2f}% time in the temperature range [{}, {}]\".format(tz_id, \n", 367 " result[tz_id],\n", 368 " LOW/1000,\n", 369 " HIGH/1000)\n", 370 " pct_temp = numpy.percentile(t.getStatement(\"THERMAL:temp\")[tz_id], result[tz_id])\n", 371 " \n", 372 " print \"The {:.2f}th percentile temperature is {:.2f}\".format(result[tz_id], pct_temp / 1000.0)\n", 373 " " 374 ], 375 "language": "python", 376 "metadata": {}, 377 "outputs": [ 378 { 379 "output_type": "stream", 380 "stream": "stdout", 381 "text": [ 382 "Thermal Zone: 0 spends 86.58% time in the temperature range [0, 78]\n", 383 "The 86.58th percentile temperature is 78.28\n" 384 ] 385 } 386 ], 387 "prompt_number": 10 388 } 389 ], 390 "metadata": {} 391 } 392 ] 393 }