| { |
| "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" |
| }, |
| "name": "", |
| "signature": "sha256:59ef0b9fe2847e77f9df55deeb6df1f94f4fe2a3a0f99e13cba99854e8bf66ed" |
| }, |
| "nbformat": 3, |
| "nbformat_minor": 0, |
| "worksheets": [ |
| { |
| "cells": [ |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "Configuration" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "import trappy\n", |
| "import numpy\n", |
| "\n", |
| "config = {}\n", |
| "\n", |
| "# TRAPpy Events\n", |
| "config[\"THERMAL\"] = trappy.thermal.Thermal\n", |
| "config[\"OUT\"] = trappy.cpu_power.CpuOutPower\n", |
| "config[\"IN\"] = trappy.cpu_power.CpuInPower\n", |
| "config[\"PID\"] = trappy.pid_controller.PIDController\n", |
| "config[\"GOVERNOR\"] = trappy.thermal.ThermalGovernor\n", |
| "\n", |
| "# Control Temperature\n", |
| "config[\"CONTROL_TEMP\"] = 77000\n", |
| "\n", |
| "# A temperature margin of 2.5 degrees Celsius\n", |
| "config[\"TEMP_MARGIN\"] = 2500\n", |
| "\n", |
| "# The Sustainable power at the control Temperature\n", |
| "config[\"SUSTAINABLE_POWER\"] = 2500\n", |
| "\n", |
| "# Expected percentile of CONTROL_TEMP + TEMP_MARGIN\n", |
| "config[\"EXPECTED_TEMP_QRT\"] = 95\n", |
| "\n", |
| "# Maximum expected Standard Deviation as a percentage\n", |
| "# of mean temperature\n", |
| "config[\"EXPECTED_STD_PCT\"] = 5\n" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [], |
| "prompt_number": 1 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "Get the Trace" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "import urllib\n", |
| "import os\n", |
| "\n", |
| "TRACE_DIR = \"example_trace_dat_thermal\"\n", |
| "TRACE_FILE = os.path.join(TRACE_DIR, 'bart_thermal_trace.dat')\n", |
| "TRACE_URL = 'http://cdn.rawgit.com/sinkap/4e0a69cbff732b57e36f/raw/7dd0ed74bfc17a34a3bd5ea6b9eb3a75a42ddbae/bart_thermal_trace.dat'\n", |
| "\n", |
| "if not os.path.isdir(TRACE_DIR):\n", |
| " os.mkdir(TRACE_DIR)\n", |
| "\n", |
| "if not os.path.isfile(TRACE_FILE):\n", |
| " print \"Fetching trace file..\"\n", |
| " urllib.urlretrieve(TRACE_URL, filename=TRACE_FILE)" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [], |
| "prompt_number": 2 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "FTrace Object" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "# Create a Trace object\n", |
| "\n", |
| "ftrace = trappy.FTrace(TRACE_FILE, \"SomeBenchMark\")" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [], |
| "prompt_number": 3 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "Assertions" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "# Create an Assertion Object\n", |
| "\n", |
| "from bart.common.Analyzer import Analyzer\n", |
| "t = Analyzer(ftrace, config)\n", |
| "\n", |
| "BIG = '000000f0'\n", |
| "LITTLE = '0000000f'" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [], |
| "prompt_number": 4 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 2, |
| "metadata": {}, |
| "source": [ |
| "Assertion: Load and Dynamic Power" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<html>\n", |
| "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", |
| "\n", |
| " $$\\forall\\ t\\ |\\ Load(t) = \\sum\\limits_{i=0}^{cpus} Load_i(t) = 0 \\implies dynamic\\ power(t)=0 $$\n", |
| " \n", |
| "</html>" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "result = t.getStatement(\"((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \\\n", |
| " & (IN:dynamic_power > 0)\",reference=True, select=BIG)\n", |
| "if len(result):\n", |
| " print \"FAIL: Dynamic Power is NOT Zero when load is Zero for the BIG cluster\"\n", |
| "else:\n", |
| " print \"PASS: Dynamic Power is Zero when load is Zero for the BIG cluster\"\n", |
| "\n", |
| " \n", |
| "result = t.getStatement(\"((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \\\n", |
| " & (IN:dynamic_power > 0)\",reference=True, select=LITTLE)\n", |
| "if len(result):\n", |
| " print \"FAIL: Dynamic Power is NOT Zero when load is Zero for the LITTLE cluster\"\n", |
| "else:\n", |
| " print \"PASS: Dynamic Power is Zero when load is Zero for the LITTLE cluster\"" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "output_type": "stream", |
| "stream": "stdout", |
| "text": [ |
| "PASS: Dynamic Power is Zero when load is Zero for the BIG cluster\n", |
| "PASS: Dynamic Power is Zero when load is Zero for the LITTLE cluster\n" |
| ] |
| } |
| ], |
| "prompt_number": 5 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 2, |
| "metadata": {}, |
| "source": [ |
| "Assertion: Control Temperature and Sustainable Power" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<html>\n", |
| "\n", |
| "When the temperature is greater than the control temperature, the total power granted to all cooling devices should be less than sustainable_power\n", |
| "\n", |
| "$$\\forall\\ t\\ |\\ Temperature(t) > control\\_temp \\implies Total\\ Granted\\ Power(t) < sustainable\\_power$$\n", |
| "\n", |
| "<html/>" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "result = t.getStatement(\"(GOVERNOR:current_temperature > CONTROL_TEMP) &\\\n", |
| " (PID:output > SUSTAINABLE_POWER)\", reference=True, select=0)\n", |
| "\n", |
| "if len(result):\n", |
| " print \"FAIL: The Governor is allocating power > sustainable when T > CONTROL_TEMP\"\n", |
| "else:\n", |
| " print \"PASS: The Governor is allocating power <= sustainable when T > CONTROL_TEMP\" " |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "output_type": "stream", |
| "stream": "stdout", |
| "text": [ |
| "PASS: The Governor is allocating power <= sustainable when T > CONTROL_TEMP\n" |
| ] |
| } |
| ], |
| "prompt_number": 6 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "Statistics" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "Check if 95% of the temperature readings are below CONTROL_TEMP + MARGIN" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "t.assertStatement(\"numpy.percentile(THERMAL:temp, 95) < (CONTROL_TEMP + TEMP_MARGIN)\")" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "metadata": {}, |
| "output_type": "pyout", |
| "prompt_number": 7, |
| "text": [ |
| "True" |
| ] |
| } |
| ], |
| "prompt_number": 7 |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "Check if the mean temperauture is less than CONTROL_TEMP" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "t.assertStatement(\"numpy.mean(THERMAL:temp) <= CONTROL_TEMP\", select=0)" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "metadata": {}, |
| "output_type": "pyout", |
| "prompt_number": 8, |
| "text": [ |
| "True" |
| ] |
| } |
| ], |
| "prompt_number": 8 |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "We can also use getStatement to get the absolute values. Here we are getting the standard deviation expressed as a percentage of the mean" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "t.getStatement(\"(numpy.std(THERMAL:temp) * 100.0) / numpy.mean(THERMAL:temp)\", select=0)" |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "metadata": {}, |
| "output_type": "pyout", |
| "prompt_number": 9, |
| "text": [ |
| "2.2390646863105119" |
| ] |
| } |
| ], |
| "prompt_number": 9 |
| }, |
| { |
| "cell_type": "heading", |
| "level": 1, |
| "metadata": {}, |
| "source": [ |
| "Thermal Residency" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "collapsed": false, |
| "input": [ |
| "from bart.thermal.ThermalAssert import ThermalAssert\n", |
| "\n", |
| "t_assert = ThermalAssert(ftrace)\n", |
| "end = ftrace.get_duration()\n", |
| "\n", |
| "LOW = 0\n", |
| "HIGH = 78000\n", |
| "\n", |
| "# The thermal residency gives the percentage (or absolute time) spent in the\n", |
| "# specified temperature range. \n", |
| "\n", |
| "result = t_assert.getThermalResidency(temp_range=(0, 78000),\n", |
| " window=(0, end),\n", |
| " percent=True)\n", |
| "\n", |
| "for tz_id in result:\n", |
| " print \"Thermal Zone: {} spends {:.2f}% time in the temperature range [{}, {}]\".format(tz_id, \n", |
| " result[tz_id],\n", |
| " LOW/1000,\n", |
| " HIGH/1000)\n", |
| " pct_temp = numpy.percentile(t.getStatement(\"THERMAL:temp\")[tz_id], result[tz_id])\n", |
| " \n", |
| " print \"The {:.2f}th percentile temperature is {:.2f}\".format(result[tz_id], pct_temp / 1000.0)\n", |
| " " |
| ], |
| "language": "python", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "output_type": "stream", |
| "stream": "stdout", |
| "text": [ |
| "Thermal Zone: 0 spends 86.58% time in the temperature range [0, 78]\n", |
| "The 86.58th percentile temperature is 78.28\n" |
| ] |
| } |
| ], |
| "prompt_number": 10 |
| } |
| ], |
| "metadata": {} |
| } |
| ] |
| } |