faultspaceplot as analysis tool
This change adds the faultspace-plotting scripts into FAIL*'s tools/analysis/ folder and makes it CMake-configurable. Change-Id: I9364a448a33853520629291721a6ed6d4e82eb32
This commit is contained in:
committed by
Horst Schirmeier
parent
fe5ccdf425
commit
52baab2d76
@ -33,6 +33,7 @@ Required for Fail*:
|
|||||||
* a MySQL 5.0+ or MariaDB 5.1+ (MariaDB 5.5 recommended) server
|
* a MySQL 5.0+ or MariaDB 5.1+ (MariaDB 5.5 recommended) server
|
||||||
* doxygen
|
* doxygen
|
||||||
* cmake-curses-gui
|
* cmake-curses-gui
|
||||||
|
* python-numpy and python-matplotlib for the faultspaceplot tool
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,8 @@ option(BUILD_CONVERT_TRACE "Build the trace converter tool?" OFF)
|
|||||||
option(BUILD_COMPUTE_HOPS "Build the compute hops tool?" OFF)
|
option(BUILD_COMPUTE_HOPS "Build the compute hops tool?" OFF)
|
||||||
option(BUILD_DUMP_HOPS "Build the hops dump tool?" OFF)
|
option(BUILD_DUMP_HOPS "Build the hops dump tool?" OFF)
|
||||||
|
|
||||||
|
option(BUILD_FAULTSPACEPLOT "Build the faultspace plotting tool?" OFF)
|
||||||
|
|
||||||
### Setup search paths for headers ##
|
### Setup search paths for headers ##
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src/core)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src/core)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src/core)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src/core)
|
||||||
@ -33,3 +35,7 @@ endif(BUILD_COMPUTE_HOPS)
|
|||||||
if(BUILD_DUMP_HOPS)
|
if(BUILD_DUMP_HOPS)
|
||||||
add_subdirectory(dump-hops)
|
add_subdirectory(dump-hops)
|
||||||
endif(BUILD_DUMP_HOPS)
|
endif(BUILD_DUMP_HOPS)
|
||||||
|
|
||||||
|
if(BUILD_FAULTSPACEPLOT)
|
||||||
|
add_subdirectory(analysis/faultspaceplot)
|
||||||
|
endif(BUILD_FAULTSPACEPLOT)
|
||||||
|
|||||||
1
tools/analysis/faultspaceplot/CMakeLists.txt
Normal file
1
tools/analysis/faultspaceplot/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
install(PROGRAMS faultspaceplot.sh fsp.compact-horizontal.sh fsp.compact.sh fsp.compact-vertical.sh fsp.plot.py DESTINATION bin)
|
||||||
51
tools/analysis/faultspaceplot/faultspaceplot.sh
Executable file
51
tools/analysis/faultspaceplot/faultspaceplot.sh
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ ! $# -eq 3 ]; then
|
||||||
|
echo "usage: $0 DATABASE VARIANT BENCHMARK" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DATABASE=$1
|
||||||
|
VARIANT=$2
|
||||||
|
BENCHMARK=$3
|
||||||
|
# add "-t" for more readable output
|
||||||
|
MYSQL="mysql -B --quick $DATABASE"
|
||||||
|
|
||||||
|
# get data
|
||||||
|
echo "getting faultspace data.."
|
||||||
|
$MYSQL <<EOT > "$VARIANT"_"$BENCHMARK"-raw.csv
|
||||||
|
SELECT t.time1 - (SELECT MIN(t2.time1) FROM trace t2 WHERE t.variant_id = t2.variant_id) AS time1,
|
||||||
|
t.time2 - (SELECT MIN(t2.time1) FROM trace t2 WHERE t.variant_id = t2.variant_id) AS time2,
|
||||||
|
t.data_address, r.bitoffset, 1,
|
||||||
|
CASE
|
||||||
|
WHEN r.resulttype = 'OK_MARKER' THEN '#FFFFFF'
|
||||||
|
WHEN r.resulttype = 'FAIL_MARKER' THEN '#EE0000'
|
||||||
|
WHEN r.resulttype = 'DETECTED_MARKER' THEN '#00FF00'
|
||||||
|
WHEN r.resulttype = 'GROUP0_MARKER' THEN '#EAEAEA'
|
||||||
|
WHEN r.resulttype = 'GROUP1_MARKER' THEN '#EBEBEB'
|
||||||
|
WHEN r.resulttype = 'GROUP2_MARKER' THEN '#ECECEC'
|
||||||
|
WHEN r.resulttype = 'GROUP3_MARKER' THEN '#EDEDED'
|
||||||
|
WHEN r.resulttype = 'TIMEOUT' THEN '#00EE00'
|
||||||
|
WHEN r.resulttype = 'TRAP' THEN '#00DD00'
|
||||||
|
WHEN r.resulttype = 'WRITE_TEXTSEGMENT' THEN '#0000AA'
|
||||||
|
WHEN r.resulttype = 'WRITE_OUTERSPACE' THEN '#0000BB'
|
||||||
|
WHEN r.resulttype = 'SDC' THEN '#FF0000'
|
||||||
|
WHEN r.resulttype = 'UNKNOWN' THEN '#000000'
|
||||||
|
END AS color
|
||||||
|
FROM trace t
|
||||||
|
JOIN fspgroup g ON t.variant_id = g.variant_id AND t.data_address = g.data_address AND t.instr2 = g.instr2
|
||||||
|
JOIN variant v ON v.id = t.variant_id
|
||||||
|
JOIN result_GenericExperimentMessage r ON r.pilot_id=g.pilot_id
|
||||||
|
WHERE
|
||||||
|
v.variant = '$VARIANT' AND v.benchmark = '$BENCHMARK'
|
||||||
|
AND t.accesstype = 'R';
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# compact data
|
||||||
|
echo "compacting data.."
|
||||||
|
fsp.compact.sh "$VARIANT"_"$BENCHMARK"-raw.csv "$VARIANT"_"$BENCHMARK"-plot.csv
|
||||||
|
|
||||||
|
# plot data
|
||||||
|
echo "plotting.."
|
||||||
|
fsp.plot.py "$VARIANT"_"$BENCHMARK"-plot.csv
|
||||||
52
tools/analysis/faultspaceplot/fsp.compact-horizontal.sh
Executable file
52
tools/analysis/faultspaceplot/fsp.compact-horizontal.sh
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMP=$(mktemp)
|
||||||
|
|
||||||
|
read HEADER
|
||||||
|
echo "$HEADER"
|
||||||
|
|
||||||
|
BASE=''
|
||||||
|
LAST=''
|
||||||
|
sort -snk 1 | sort -snk 4 | sort -snk 3 > $TMP
|
||||||
|
|
||||||
|
while read CUR
|
||||||
|
do
|
||||||
|
a=($CUR)
|
||||||
|
C_I1=${a[0]}
|
||||||
|
C_I2=${a[1]}
|
||||||
|
C_ADDR=${a[2]}
|
||||||
|
C_BIT=${a[3]}
|
||||||
|
C_BW=${a[4]}
|
||||||
|
C_COL=${a[5]}
|
||||||
|
|
||||||
|
if [ -z "$BASE" ]
|
||||||
|
then
|
||||||
|
BASE=$CUR
|
||||||
|
LAST=$CUR
|
||||||
|
elif (($C_I1 != $L_I2 + 1 || $L_ADDR != $C_ADDR || $L_BIT != $C_BIT || $L_BW != $C_BW)) || \
|
||||||
|
[ "$C_COL" != "$L_COL" ]
|
||||||
|
then
|
||||||
|
a=($BASE)
|
||||||
|
B_I1=${a[0]}
|
||||||
|
|
||||||
|
echo -e "$B_I1\t$L_I2\t$L_ADDR\t$L_BIT\t$L_BW\t$L_COL"
|
||||||
|
|
||||||
|
BASE=$CUR
|
||||||
|
fi
|
||||||
|
|
||||||
|
LAST="$CUR"
|
||||||
|
L_I1=$C_I1
|
||||||
|
L_I2=$C_I2
|
||||||
|
L_ADDR=$C_ADDR
|
||||||
|
L_BIT=$C_BIT
|
||||||
|
L_BW=$C_BW
|
||||||
|
L_COL=$C_COL
|
||||||
|
done < $TMP
|
||||||
|
|
||||||
|
a=($BASE)
|
||||||
|
B_I1=${a[0]}
|
||||||
|
|
||||||
|
echo -e "$B_I1\t$L_I2\t$L_ADDR\t$L_BIT\t$L_BW\t$L_COL"
|
||||||
|
|
||||||
|
rm $TMP
|
||||||
63
tools/analysis/faultspaceplot/fsp.compact-vertical.sh
Executable file
63
tools/analysis/faultspaceplot/fsp.compact-vertical.sh
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMP=$(mktemp)
|
||||||
|
|
||||||
|
read HEADER
|
||||||
|
echo "$HEADER"
|
||||||
|
|
||||||
|
BASE=''
|
||||||
|
LAST=''
|
||||||
|
sort -snk 4 | sort -snk 3 | sort -snk 1 > $TMP
|
||||||
|
|
||||||
|
while read CUR
|
||||||
|
do
|
||||||
|
a=($CUR)
|
||||||
|
C_I1=${a[0]}
|
||||||
|
C_I2=${a[1]}
|
||||||
|
C_ADDR=${a[2]}
|
||||||
|
C_BIT=${a[3]}
|
||||||
|
C_BW=${a[4]}
|
||||||
|
C_COL=${a[5]}
|
||||||
|
C_N=$(($C_ADDR*8 + $C_BIT))
|
||||||
|
|
||||||
|
if [ -z "$BASE" ]
|
||||||
|
then
|
||||||
|
BASE=$CUR
|
||||||
|
LAST=$CUR
|
||||||
|
elif (($C_I1 != $L_I1 || $C_I2 != $L_I2 || \
|
||||||
|
$L_N + $L_BW != $C_N)) || \
|
||||||
|
[ "$C_COL" != "$L_COL" ]
|
||||||
|
then
|
||||||
|
a=($BASE)
|
||||||
|
B_ADDR=${a[2]}
|
||||||
|
B_BIT=${a[3]}
|
||||||
|
B_N=$(($B_ADDR*8 + $B_BIT))
|
||||||
|
|
||||||
|
BW=$(($L_N + $L_BW - $B_N))
|
||||||
|
|
||||||
|
echo -e "$L_I1\t$L_I2\t$B_ADDR\t$B_BIT\t$BW\t$L_COL"
|
||||||
|
|
||||||
|
BASE=$CUR
|
||||||
|
fi
|
||||||
|
|
||||||
|
LAST="$CUR"
|
||||||
|
L_I1=$C_I1
|
||||||
|
L_I2=$C_I2
|
||||||
|
L_ADDR=$C_ADDR
|
||||||
|
L_BIT=$C_BIT
|
||||||
|
L_BW=$C_BW
|
||||||
|
L_COL=$C_COL
|
||||||
|
L_N=$C_N
|
||||||
|
done < $TMP
|
||||||
|
|
||||||
|
a=($BASE)
|
||||||
|
B_ADDR=${a[2]}
|
||||||
|
B_BIT=${a[3]}
|
||||||
|
B_N=$(($B_ADDR*8 + $B_BIT))
|
||||||
|
|
||||||
|
BW=$(($L_N + $L_BW - $B_N))
|
||||||
|
|
||||||
|
echo -e "$L_I1\t$L_I2\t$B_ADDR\t$B_BIT\t$BW\t$L_COL"
|
||||||
|
|
||||||
|
rm $TMP
|
||||||
43
tools/analysis/faultspaceplot/fsp.compact.sh
Executable file
43
tools/analysis/faultspaceplot/fsp.compact.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
FIRST=vertical
|
||||||
|
|
||||||
|
[ $# -lt 2 -o $# -gt 3 ] && echo "usage: $0 input.csv output.csv [vertical|horizontal]" >&2 && exit 1
|
||||||
|
|
||||||
|
if [ -z $3 ]; then
|
||||||
|
FIRST=vertical
|
||||||
|
else
|
||||||
|
FIRST=$3
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP1=$(mktemp)
|
||||||
|
TMP2=$(mktemp)
|
||||||
|
|
||||||
|
cp $1 $TMP1
|
||||||
|
COUNT=$(wc -l <$TMP1)
|
||||||
|
|
||||||
|
NEXT=$FIRST
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
echo "at $COUNT, $NEXT ..."
|
||||||
|
fsp.compact-$NEXT.sh < $TMP1 > $TMP2
|
||||||
|
|
||||||
|
PREVCOUNT=$COUNT
|
||||||
|
COUNT=$(wc -l <$TMP2)
|
||||||
|
|
||||||
|
if (($COUNT >= $PREVCOUNT))
|
||||||
|
then
|
||||||
|
echo "no improvement (now $COUNT), stop."
|
||||||
|
cp $TMP1 $2
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv $TMP2 $TMP1
|
||||||
|
if [ $NEXT = vertical ]; then
|
||||||
|
NEXT=horizontal
|
||||||
|
else
|
||||||
|
NEXT=vertical
|
||||||
|
fi
|
||||||
|
done
|
||||||
110
tools/analysis/faultspaceplot/fsp.plot.py
Executable file
110
tools/analysis/faultspaceplot/fsp.plot.py
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Import modules
|
||||||
|
import csv, sys
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.patches as mpatches
|
||||||
|
import matplotlib.pylab as pylab
|
||||||
|
|
||||||
|
ENTRY_COUNT_PER_LINE = 6
|
||||||
|
RESULT_RECT_HEIGHT = 1.0/8
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Basic drawing class
|
||||||
|
class Rectangle:
|
||||||
|
def __init__(self, x, y, w, h, color):
|
||||||
|
# w
|
||||||
|
self.xpos = x # |-------------------|
|
||||||
|
self.ypos = y # | | h
|
||||||
|
self.width = w # | |
|
||||||
|
self.height = h # (x,y)---------------|
|
||||||
|
self.color = color # fill color
|
||||||
|
self.alpha = None # transparency level [0,1]
|
||||||
|
def draw(self):
|
||||||
|
""" Draw the rectangle. """
|
||||||
|
if self.color == (1,1,1):
|
||||||
|
return
|
||||||
|
tmp = self.xpos, self.ypos,
|
||||||
|
p = mpatches.Rectangle(tmp, self.width, self.height, color=self.color, \
|
||||||
|
alpha=self.alpha)
|
||||||
|
plt.gca().add_patch(p)
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Check provided arguments:
|
||||||
|
if len(sys.argv) <= 1:
|
||||||
|
print "ERROR: Not enough arguments provided! See -h for more infos."
|
||||||
|
exit(1)
|
||||||
|
if sys.argv[1] == '-h':
|
||||||
|
print "Displays experiment results for the weather-monitor-experiment."
|
||||||
|
print " CALL-SYNTAX: fsp.plot.py DATA_FILE [USER_TAG_FILE]"
|
||||||
|
print "DATA_FILE is a CSV-file, storing the tab-separated values"
|
||||||
|
print "retrieved by the experiment run. USER_TAG_FILE is an optional"
|
||||||
|
print "CSV-file which can be used to add user-specific marks to the"
|
||||||
|
print "plot (not implemented yet)." # TODO: be more precise here
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
print "WARNING: This script needs a newer version of Matplotlib for axis label rotation; run this on Ubuntu 12.10 or alike."
|
||||||
|
|
||||||
|
print "Opening and processing \"" + sys.argv[1] + "\"..."
|
||||||
|
file = open(sys.argv[1], "r")
|
||||||
|
dialect = csv.Sniffer().sniff(file.read(1024))
|
||||||
|
file.seek(0)
|
||||||
|
reader = csv.reader(file, dialect)
|
||||||
|
reader.next() # Move down a line to skip the header
|
||||||
|
|
||||||
|
fig = plt.figure()
|
||||||
|
|
||||||
|
xmin = 99999999
|
||||||
|
xmax = 0
|
||||||
|
ymin = 99999999
|
||||||
|
ymax = 0
|
||||||
|
|
||||||
|
line_counter = 1
|
||||||
|
for row in reader:
|
||||||
|
line_counter += 1
|
||||||
|
# Check if there are at least ENTRY_COUNT_PER_LINE entries per line:
|
||||||
|
if len(row) != ENTRY_COUNT_PER_LINE:
|
||||||
|
print "ERROR: Line " + str(line_counter) + " is invalid (" +\
|
||||||
|
str(ENTRY_COUNT_PER_LINE) + " entries expected)"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Some constants to access the row-entries much easier:
|
||||||
|
IDX_INSTR1 = 0; IDX_INSTR2 = 1; IDX_DATA_ADDRESS = 2;
|
||||||
|
IDX_BITNR = 3; IDX_BITWIDTH = 4; IDX_COLOR = 5;
|
||||||
|
|
||||||
|
# Update xmin/xmax/ymin/ymax
|
||||||
|
x1 = int(row[IDX_INSTR1])
|
||||||
|
x2 = int(row[IDX_INSTR2]) + 1 # inclusive
|
||||||
|
width = x2 - x1
|
||||||
|
if xmin > x1:
|
||||||
|
xmin = x1
|
||||||
|
if xmax < x2:
|
||||||
|
xmax = x2
|
||||||
|
|
||||||
|
y1 = float(row[IDX_DATA_ADDRESS]) + float(row[IDX_BITNR]) / 8.0
|
||||||
|
height = float(row[IDX_BITWIDTH]) / 8.0
|
||||||
|
y2 = y1 + height
|
||||||
|
|
||||||
|
if ymin > y1:
|
||||||
|
ymin = y1
|
||||||
|
if ymax < y2:
|
||||||
|
ymax = y2
|
||||||
|
|
||||||
|
Rectangle(x1, y1, width, height, row[IDX_COLOR]).draw()
|
||||||
|
if line_counter == 50000: # debug stuff
|
||||||
|
pass
|
||||||
|
#break
|
||||||
|
|
||||||
|
ymin = int(ymin / 1000) * 1000
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
plt.xlim(xmin, xmax)
|
||||||
|
plt.ylim(ymin, ymax)
|
||||||
|
|
||||||
|
plt.ylabel('Data Memory (RAM)')
|
||||||
|
plt.xlabel('Time (Cycles)')
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
#pylab.savefig('baseline.pdf', bbox_inches='tight')
|
||||||
Reference in New Issue
Block a user