Add tracegen scripts inc. bugfix from @mwachs5
A step towards moving the tracegen scripts from rocket-chip to groundtest. I will raise an issue requesting that the scripts are now removed from rocket-chip by someone with write access. I have updated the README to account for the move. This commit includes a bugfix from @mwachs5 (with slight mods by me) relating to potential division by zero in toaxe.py.
This commit is contained in:
parent
7285f5e6bf
commit
b2eabf4a9f
@ -51,8 +51,9 @@ Putting the generator and the checker together, we can automatically search for
|
|||||||
|
|
||||||
The [tracegen+check.sh](https://github.com/ucb-bar/rocket-chip/blob/master/scripts/tracegen%2Bcheck.sh) script (included in rocket-chip/scripts) provides an automated way to run a number of randomized tests. The number of tests, initial seed, and other parameters can be set via environment variables or the command line, see the script for more details.
|
The [tracegen+check.sh](https://github.com/ucb-bar/rocket-chip/blob/master/scripts/tracegen%2Bcheck.sh) script (included in rocket-chip/scripts) provides an automated way to run a number of randomized tests. The number of tests, initial seed, and other parameters can be set via environment variables or the command line, see the script for more details.
|
||||||
|
|
||||||
The examples that follow assume that the rocket-chip/scripts directory is
|
The examples that follow assume that the `groundtest/scripts`
|
||||||
in your PATH and that rocket-chip is your current working directory.
|
directory is in your `PATH` and that `rocket-chip/emulator` is your
|
||||||
|
current working directory.
|
||||||
|
|
||||||
```
|
```
|
||||||
> make CONFIG=TraceGenConfig
|
> make CONFIG=TraceGenConfig
|
||||||
@ -72,7 +73,6 @@ Load-external rate: 47%
|
|||||||
To run a single test with a specified random seed:
|
To run a single test with a specified random seed:
|
||||||
|
|
||||||
```
|
```
|
||||||
> cd emulator
|
|
||||||
> make CONFIG=TraceGenConfig
|
> make CONFIG=TraceGenConfig
|
||||||
> tracegen.py ./emulator-Top-TraceGenConfig 1 > trace.log
|
> tracegen.py ./emulator-Top-TraceGenConfig 1 > trace.log
|
||||||
> toaxe.py trace.log > trace.axe
|
> toaxe.py trace.log > trace.axe
|
||||||
|
210
groundtest/scripts/toaxe.py
Executable file
210
groundtest/scripts/toaxe.py
Executable file
@ -0,0 +1,210 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# This file was originally written by Matthew Naylor, University of
|
||||||
|
# Cambridge.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
|
||||||
|
# ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||||
|
# ("MRC2"), as part of the DARPA MRC research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory as part of the Rigorous Engineering of
|
||||||
|
# Mainstream Systems (REMS) project, funded by EPSRC grant
|
||||||
|
# EP/K008528/1.
|
||||||
|
|
||||||
|
# -------
|
||||||
|
# Outline
|
||||||
|
# -------
|
||||||
|
|
||||||
|
# This script takes memory-subsystem traces produced by the groundtest
|
||||||
|
# trace generator (see tracegen.scala) and puts them into a format
|
||||||
|
# that can be validated by the axe tool (see
|
||||||
|
# https://github.com/CTSRD-CHERI/axe).
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import sets
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
sys.stderr.write("Usage: toaxe.py TRACE-FILE [STATS-OUT-FILE]\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if sys.argv[1] == "-":
|
||||||
|
f = sys.stdin
|
||||||
|
else:
|
||||||
|
f = open(sys.argv[1], 'r')
|
||||||
|
if f == None:
|
||||||
|
sys.stderr.write("File not found: " + sys.argv[1] + "\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
statsFile = None
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
statsFile = open(sys.argv[2], 'a')
|
||||||
|
|
||||||
|
lineCount = 0
|
||||||
|
def error(msg):
|
||||||
|
sys.stderr.write("Error at line " + str(lineCount) + ": " + msg + "\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Mapping from address to axe address
|
||||||
|
addrMap = {}
|
||||||
|
nextAddr = 0
|
||||||
|
|
||||||
|
# Mapping from (thread id, tag id) to axe operation id
|
||||||
|
tagMap = {}
|
||||||
|
|
||||||
|
# Mapping from thread id to operation id
|
||||||
|
fenceReq = {}
|
||||||
|
|
||||||
|
# Mapping from thread id to operation id
|
||||||
|
loadReserve = {}
|
||||||
|
|
||||||
|
# Array of axe operations
|
||||||
|
ops = []
|
||||||
|
|
||||||
|
# Statistics
|
||||||
|
scCount = 0 # Number of store-conditionals
|
||||||
|
scSuccessCount = 0 # Number of store-conditionals that succeeded
|
||||||
|
loadCount = 0 # Number of loads
|
||||||
|
loadExtCount = 0 # Number of loads of value written by another core
|
||||||
|
|
||||||
|
# The previous write to each address by each thread
|
||||||
|
prevWrite = {}
|
||||||
|
|
||||||
|
for line in f:
|
||||||
|
# Parse thread id and command
|
||||||
|
m = re.search(' *([0-9]+) *: *([^ ]*) (.*)', line)
|
||||||
|
if m == None: error("Expected: <thread-id> ':' <command>")
|
||||||
|
tid, cmd, line = m.group(1), m.group(2), m.group(3)
|
||||||
|
|
||||||
|
if cmd == 'fence-req':
|
||||||
|
# Parse time
|
||||||
|
m = re.search(' *@ *([0-9]+)', line)
|
||||||
|
if m == None: error ("expected timestamp")
|
||||||
|
# Insert placeholder containing request time
|
||||||
|
ops.append(str(m.group(1)))
|
||||||
|
fenceReq[tid] = len(ops)-1
|
||||||
|
elif cmd == 'fence-resp':
|
||||||
|
# Insert 'sync' operation
|
||||||
|
if not (tid in fenceReq) or fenceReq[tid] == None:
|
||||||
|
error("fence-resp without fence-req on thread " + tid)
|
||||||
|
startTime = ops[fenceReq[tid]]
|
||||||
|
op = str(tid) + ": sync @ " + startTime
|
||||||
|
# Add end-time
|
||||||
|
m = re.search(' *@ *([0-9]+)', line)
|
||||||
|
if m != None: op = op + ":" + str(m.group(1))
|
||||||
|
ops[fenceReq[tid]] = (op,)
|
||||||
|
fenceReq[tid] = None
|
||||||
|
elif cmd == 'load-req' or cmd == 'load-reserve-req':
|
||||||
|
# Parse address, tag, and time
|
||||||
|
m = re.search(' *([0-9a-fx]+) *# *([0-9]+) *@ *([0-9]+)', line)
|
||||||
|
if m == None: error("expected <address> #<tag> @<timestamp>")
|
||||||
|
# Update address map
|
||||||
|
if not (m.group(1) in addrMap):
|
||||||
|
addrMap[m.group(1)] = nextAddr
|
||||||
|
nextAddr = nextAddr+1
|
||||||
|
# Insert place-holder
|
||||||
|
ops.append((cmd, None, addrMap[m.group(1)], m.group(3), None))
|
||||||
|
tagMap[(tid, m.group(2))] = len(ops)-1
|
||||||
|
if cmd == 'load-reserve-req':
|
||||||
|
loadReserve[tid] = len(ops)-1
|
||||||
|
elif cmd == 'store-req' or cmd == 'store-cond-req' or cmd == 'swap-req':
|
||||||
|
# Parse value, address, tag, and time
|
||||||
|
m = re.search(' *([0-9]+) *([0-9a-fx]+) *# *([0-9]+) *@ *([0-9]+)', line)
|
||||||
|
if m == None: error("expected <value> <address> #<tag> @<timestamp>")
|
||||||
|
# Update address map
|
||||||
|
if not (m.group(2) in addrMap):
|
||||||
|
addrMap[m.group(2)] = nextAddr
|
||||||
|
nextAddr = nextAddr+1
|
||||||
|
# Insert place-holder
|
||||||
|
lr = loadReserve[tid] if tid in loadReserve else None
|
||||||
|
ops.append((cmd, m.group(1), addrMap[m.group(2)], m.group(4), lr))
|
||||||
|
tagMap[(tid, m.group(3))] = len(ops)-1
|
||||||
|
if cmd == 'store-cond-req': loadReserve[tid] = None
|
||||||
|
prevWrite[(tid, addrMap[m.group(2)])] = m.group(1)
|
||||||
|
elif cmd == 'resp':
|
||||||
|
# Parse value and timestamp
|
||||||
|
m = re.search(' *([0-9]+) *# *([0-9]+) *@ *([0-9]+)', line)
|
||||||
|
if m == None: error("expected <value> #<tag> @<timestamp>")
|
||||||
|
# Find corresponding response
|
||||||
|
tag = m.group(2)
|
||||||
|
if not ((tid, tag) in tagMap) or tagMap[(tid, tag)] == None:
|
||||||
|
error("resp without associated req with tag " + tag +
|
||||||
|
" on thread " + tid)
|
||||||
|
opId = tagMap[(tid, tag)]
|
||||||
|
(c, val, addr, start, lr) = ops[opId]
|
||||||
|
if c == 'load-req' or c == 'load-reserve-req':
|
||||||
|
loadCount = loadCount+1
|
||||||
|
if prevWrite.get((tid, addr), None) != m.group(1):
|
||||||
|
loadExtCount = loadExtCount+1
|
||||||
|
if c == 'load-req':
|
||||||
|
op = tid + ": M[" + str(addr) + '] == ' + m.group(1) + ' @ '
|
||||||
|
op += start + ':' + m.group(3)
|
||||||
|
ops[opId] = (op,)
|
||||||
|
elif c == 'store-req':
|
||||||
|
op = tid + ": M[" + str(addr) + '] := ' + val + ' @ '
|
||||||
|
op += start + ':' # + m.group(3)
|
||||||
|
ops[opId] = (op,)
|
||||||
|
elif c == 'load-reserve-req':
|
||||||
|
ops[opId] = (m.group(1), start, m.group(3))
|
||||||
|
elif c == 'store-cond-req':
|
||||||
|
if lr == None: error("store conditional without load-reserve")
|
||||||
|
(loadVal, loadStart, loadFin) = ops[lr]
|
||||||
|
scCount = scCount + 1
|
||||||
|
if int(m.group(1)) != 0:
|
||||||
|
# SC fail
|
||||||
|
op = tid + ": M[" + str(addr) + "] == " + loadVal
|
||||||
|
op += " @ " + loadStart + ":" + loadFin
|
||||||
|
else:
|
||||||
|
# SC success
|
||||||
|
scSuccessCount = scSuccessCount + 1
|
||||||
|
op = tid + ": { M[" + str(addr) + "] == " + loadVal + "; "
|
||||||
|
op += "M[" + str(addr) + "] := " + val + "} @ "
|
||||||
|
op += loadStart + ":" + loadFin
|
||||||
|
ops[lr] = (op,)
|
||||||
|
ops[opId] = None
|
||||||
|
elif c == 'swap-req':
|
||||||
|
op = tid + ": { M[" + str(addr) + '] == ' + m.group(1)
|
||||||
|
op += '; M[' + str(addr) + '] := ' + val
|
||||||
|
op += '} @ ' + start + ':' # + m.group(3)
|
||||||
|
ops[opId] = (op,)
|
||||||
|
else:
|
||||||
|
error("Unknown command '" + cmd + "'")
|
||||||
|
|
||||||
|
lineCount = lineCount+1
|
||||||
|
|
||||||
|
# Print statistics
|
||||||
|
if (scCount > 0):
|
||||||
|
scSuccessRate = str(scSuccessCount/float(scCount))[0:6]
|
||||||
|
print("# LRSC_Success_Rate=" + scSuccessRate)
|
||||||
|
if statsFile != None:
|
||||||
|
statsFile.write("LRSC_Success_Rate=" + scSuccessRate + "\n")
|
||||||
|
|
||||||
|
if (loadCount > 0):
|
||||||
|
loadExtRate = str(loadExtCount/float(loadCount))[0:6]
|
||||||
|
print("# Load_External_Rate=" + loadExtRate)
|
||||||
|
if statsFile != None:
|
||||||
|
statsFile.write("Load_External_Rate=" + loadExtRate + "\n")
|
||||||
|
|
||||||
|
if statsFile != None:
|
||||||
|
statsFile.close()
|
||||||
|
|
||||||
|
# Print address map in comments
|
||||||
|
for addr in addrMap:
|
||||||
|
print ("# &M[" + str(addrMap[addr]) + "] == " + addr)
|
||||||
|
|
||||||
|
# Print axe trace
|
||||||
|
for op in ops:
|
||||||
|
if op != None and isinstance(op, tuple) and len(op) == 1:
|
||||||
|
print op[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(-1)
|
148
groundtest/scripts/tracegen+check.sh
Executable file
148
groundtest/scripts/tracegen+check.sh
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This file was originally written by Matthew Naylor, University of
|
||||||
|
# Cambridge.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
|
||||||
|
# ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||||
|
# ("MRC2"), as part of the DARPA MRC research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory as part of the Rigorous Engineering of
|
||||||
|
# Mainstream Systems (REMS) project, funded by EPSRC grant
|
||||||
|
# EP/K008528/1.
|
||||||
|
|
||||||
|
# This script can be used to test the memory consistency of rocket
|
||||||
|
# chip in simulation when compiled with the 'TraceGenConfig'
|
||||||
|
# configuation.
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
# ==========
|
||||||
|
|
||||||
|
# Arguments are taken from environment variables where available.
|
||||||
|
# Elsewhere, defaults values are chosen.
|
||||||
|
|
||||||
|
START_SEED=${START_SEED-0}
|
||||||
|
NUM_TESTS=${NUM_TESTS-100}
|
||||||
|
EMU=${EMU-emulator-Top-TraceGenConfig}
|
||||||
|
TRACE_GEN=${TRACE_GEN-tracegen.py}
|
||||||
|
TO_AXE=${TO_AXE-toaxe.py}
|
||||||
|
AXE=${AXE-axe}
|
||||||
|
MODEL=${MODEL-WMO}
|
||||||
|
LOG_DIR=${LOG_DIR-tracegen-log}
|
||||||
|
TRACE_STATS=${TRACE_STATS-tracestats.py}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Inferred parameters
|
||||||
|
# ===================
|
||||||
|
|
||||||
|
END_SEED=`expr \( $START_SEED + $NUM_TESTS \) - 1`
|
||||||
|
LOG=$LOG_DIR
|
||||||
|
PATH=$PATH:.
|
||||||
|
|
||||||
|
# Sanity check
|
||||||
|
# ============
|
||||||
|
|
||||||
|
if [ ! `command -v $EMU` ]; then
|
||||||
|
echo Can\'t find emulator: \'$EMU\'
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! `command -v $TO_AXE` ]; then
|
||||||
|
echo Please add \'toaxe.py\' to your PATH
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! `command -v $TRACE_GEN` ]; then
|
||||||
|
echo Please add \'tracegen.py\' to your PATH
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! `command -v $AXE` ]; then
|
||||||
|
echo Please add \'axe\' to your PATH
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! `command -v $TRACE_STATS` ]; then
|
||||||
|
echo Please add \'tracestats.py\' to your PATH
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$MODEL" != SC -a \
|
||||||
|
"$MODEL" != TSO -a \
|
||||||
|
"$MODEL" != PSO -a \
|
||||||
|
"$MODEL" != WMO -a \
|
||||||
|
"$MODEL" != POW ]; then
|
||||||
|
echo Unknown consistency model \'$MODEL\'
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup log directory
|
||||||
|
# ===================
|
||||||
|
|
||||||
|
if [ ! -d $LOG ]; then
|
||||||
|
echo Creating log directory: $LOG
|
||||||
|
mkdir $LOG
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f $LOG/errors.txt
|
||||||
|
rm -f $LOG/stats.txt
|
||||||
|
|
||||||
|
# Test loop
|
||||||
|
# =========
|
||||||
|
|
||||||
|
echo Testing against $MODEL model:
|
||||||
|
|
||||||
|
for (( I = $START_SEED; I <= $END_SEED; I++ )); do
|
||||||
|
SPACE=`expr $I \% 10`
|
||||||
|
if [ $SPACE -eq 0 ]; then
|
||||||
|
echo -n " "
|
||||||
|
fi
|
||||||
|
|
||||||
|
NEWLINE=`expr $I \% 50`
|
||||||
|
if [ $NEWLINE -eq 0 ]; then
|
||||||
|
printf "\n%8i: " $I
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate trace
|
||||||
|
$TRACE_GEN $EMU $I > $LOG/trace.txt
|
||||||
|
if [ ! $? -eq 0 ]; then
|
||||||
|
echo -e "\n\nError: emulator returned non-zero exit code"
|
||||||
|
echo See $LOG/trace.txt for details
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert to axe format
|
||||||
|
$TO_AXE $LOG/trace.txt $LOG/stats.txt 2>> $LOG/errors.txt > $LOG/trace.axe
|
||||||
|
if [ ! $? -eq 0 ]; then
|
||||||
|
echo -e "\n\nError during trace generation with seed $I"
|
||||||
|
echo "See $LOG/errors.txt"
|
||||||
|
exit -1
|
||||||
|
else
|
||||||
|
# Check trace
|
||||||
|
OUTCOME=`$AXE check $MODEL $LOG/trace.axe 2>> $LOG/errors.txt`
|
||||||
|
if [ "$OUTCOME" == "OK" ]; then
|
||||||
|
echo -n .
|
||||||
|
else
|
||||||
|
if [ "$OUTCOME" == "NO" ]; then
|
||||||
|
echo -e "\n\nFailed $MODEL with seed $I"
|
||||||
|
echo "See $LOG/trace.txt and $LOG/trace.axe for counterexample"
|
||||||
|
exit -1
|
||||||
|
else
|
||||||
|
echo -e "\n\nError during trace generation with seed $I"
|
||||||
|
echo "See $LOG/errors.txt for details"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\n\nOK, passed $NUM_TESTS tests"
|
||||||
|
$TRACE_STATS $LOG/stats.txt
|
62
groundtest/scripts/tracegen.py
Executable file
62
groundtest/scripts/tracegen.py
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# This file was originally written by Matthew Naylor, University of
|
||||||
|
# Cambridge.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
|
||||||
|
# ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||||
|
# ("MRC2"), as part of the DARPA MRC research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory as part of the Rigorous Engineering of
|
||||||
|
# Mainstream Systems (REMS) project, funded by EPSRC grant
|
||||||
|
# EP/K008528/1.
|
||||||
|
|
||||||
|
# -------
|
||||||
|
# Outline
|
||||||
|
# -------
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# tracegen.py EMULATOR SEED
|
||||||
|
#
|
||||||
|
# This script generates a trace using the given emulator (built
|
||||||
|
# with CONFIG=TraceGenConfig). It waits until all cores have
|
||||||
|
# completed trace generation before terminating the emulator.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
sys.stderr.write("Usage: tracegen.py EMULATOR SEED\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
p = subprocess.Popen([sys.argv[1], "+verbose", "-s" + sys.argv[2]],
|
||||||
|
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
|
if p == None:
|
||||||
|
sys.stderr.write("File not found: " + sys.argv[1] + "\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
numFinished = 0
|
||||||
|
while True:
|
||||||
|
line = p.stderr.readline()
|
||||||
|
if line[0:9] == "FINISHED ":
|
||||||
|
total = int(line[9:-1])
|
||||||
|
numFinished = numFinished + 1
|
||||||
|
if numFinished == total:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print line,
|
||||||
|
|
||||||
|
p.terminate()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(-1)
|
76
groundtest/scripts/tracestats.py
Executable file
76
groundtest/scripts/tracestats.py
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# This file was originally written by Matthew Naylor, University of
|
||||||
|
# Cambridge.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
|
||||||
|
# ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||||
|
# ("MRC2"), as part of the DARPA MRC research programme.
|
||||||
|
#
|
||||||
|
# This software was partly developed by the University of Cambridge
|
||||||
|
# Computer Laboratory as part of the Rigorous Engineering of
|
||||||
|
# Mainstream Systems (REMS) project, funded by EPSRC grant
|
||||||
|
# EP/K008528/1.
|
||||||
|
|
||||||
|
# -------
|
||||||
|
# Outline
|
||||||
|
# -------
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# tracegen-stats.py STATS-FILE
|
||||||
|
#
|
||||||
|
# This script produces some statistics about the traces generated
|
||||||
|
# using tracegen.py.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.stderr.write("Usage: tracegen-stats.py STATS-FILE\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
f = open(sys.argv[1], 'r')
|
||||||
|
if f == None:
|
||||||
|
sys.stderr.write("File not found: " + sys.argv[1] + "\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
lrscSuccessSum = 0.0
|
||||||
|
lrscSuccessCount = 0
|
||||||
|
loadExtRateSum = 0.0
|
||||||
|
loadExtRateCount = 0
|
||||||
|
for line in f:
|
||||||
|
if line[0:18] == "LRSC_Success_Rate=":
|
||||||
|
val = float(line[18:-1])
|
||||||
|
lrscSuccessSum = lrscSuccessSum + val
|
||||||
|
lrscSuccessCount = lrscSuccessCount + 1
|
||||||
|
|
||||||
|
if line[0:19] == "Load_External_Rate=":
|
||||||
|
val = float(line[19:-1])
|
||||||
|
loadExtRateSum = loadExtRateSum + val
|
||||||
|
loadExtRateCount = loadExtRateCount + 1
|
||||||
|
|
||||||
|
if lrscSuccessCount > 0:
|
||||||
|
lrscSuccessAvg = lrscSuccessSum / float(lrscSuccessCount)
|
||||||
|
lrscSuccessRate = str(int(100.0*lrscSuccessAvg)) + "%"
|
||||||
|
print "LR/SC success rate:", lrscSuccessRate
|
||||||
|
else:
|
||||||
|
print "LR/SC success rate: none performed"
|
||||||
|
|
||||||
|
if loadExtRateCount > 0:
|
||||||
|
loadExtRateAvg = loadExtRateSum / float(loadExtRateCount)
|
||||||
|
loadExtRate = str(int(100.0*loadExtRateAvg)) + "%"
|
||||||
|
print "Load-external rate:", loadExtRate
|
||||||
|
else:
|
||||||
|
print "Load-external rate: none performed"
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(-1)
|
Loading…
Reference in New Issue
Block a user