393 lines
No EOL
11 KiB
Text
393 lines
No EOL
11 KiB
Text
{
|
|
"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": {}
|
|
}
|
|
]
|
|
} |