rt_benchs/communication_techniques/parsing.sh

503 lines
14 KiB
Bash
Executable File

#!/bin/sh
#
# Copyright (C) 2009-2012 Thomas Preud'homme <thomas.preud-homme@lip6.fr>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set -u
init_bench_vars ()
{
local ourBenchs onlyWBBenchs comList com -
ourBenchs="batch_queue"
onlyWBBenchs="jikes_barrier"
comList=`ls *.log | perl -ni -e '/-([^-]+)_comm/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'`
if [ -z "${barriereList:-}" ]
then
for com in $comList
do
if echo $com | grep "$ourBenchs" > /dev/null 2>&1
then
barriereList="${barriereList:-}${barriereList:+ }$com"
fi
if echo $com | grep "$onlyWBBenchs" > /dev/null 2>&1
then
barriereList="${barriereList:-}${barriereList:+ }$com"
fi
done
fi
if [ -z "${communicationList:-}" ]
then
for com in $comList
do
if echo $onlyWBBenchs | grep -v "$com" > /dev/null 2>&1
then
communicationList="${communicationList:-}${communicationList:+ }$com"
fi
done
fi
}
init_log_vars ()
{
local firstBarriereComm -
cacheList=`ls *log | perl -ni -e '/cache_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}' | sed -r "s/ +\$//"`
prodList=`ls *.log | perl -ni -e '/typeProd_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'`
metriqueList="cache_hits cache_miss cycles total_time"
nbIter=`ls -1 *.log | head -1 | sed -r "s/^.*nbIter_([[:digit:]]+).*$/\1/"`
valuePerCacheLine=$(grep "^buf size: " *.log | head -1 | sed -r "s/^.*:buf size: ([[:digit:]]+)[^[:digit:]+]$/\1/")
}
parse_args ()
{
local opt optNum -
logDir=$(pwd)
optNum=0
while [ $# -gt $optNum ]
do
optNum=$((optNum + 1))
eval opt=\$$optNum
case $opt in
"-e")
if [ $# -gt $optNum ]
then
optNum=$((optNum + 1))
eval opt=\$$optNum
eval "$opt"
else
echo "Missing argument after \"-e\""
return 1
fi ;;
*)
logDir="$opt" ;;
esac
done
return 0
}
use_histo ()
{
local prod bench -
prod="$1"
bench="$2"
[ "$prod" != "useless_loop" -a "$prod" != "line" ]
return $?
}
contains_zero()
{
local prod bench datFile lineNum commTechs nbCommTechs nbArg iMin iMax -
prod="$1"
bench="$2"
datFile="$3"
lineNum="$4"
numCacheConfigs="$5"
if use_histo "$prod" "$bench"
then
eval commTechs=\$${bench}List
# Count the number of spaces in the list + the line feed
nbCommTechs=$(echo $commTechs | sed -r "s/[^ ]//g" | wc -c)
iMin=$((lineNum + 4))
iMax=$((lineNum + 1 + nbCommTechs * 3))
for i in $(seq $iMin 3 $iMax)
do
if head -$i $datFile | tail -1 | grep -E "\.0+([^[:digit:]])?$" > /dev/null
then
return 0
fi
done
else
iMin=$((lineNum + numCacheConfigs * 4 + 1))
# Number of lines in the file
nbArg=$(wc -l $datFile | cut -d ' ' -f 1)
nbArg=$((nbArg + 1)) # Last line doesn't contain a newline
nbArg=$((nbArg - 4 * numCacheConfigs + 1))
nbArg=$((nbArg / numCacheConfigs / 4))
iMax=$((iMin + nbArg * numCacheConfigs * 4 - 4))
for i in $(seq $iMin 4 $iMax)
do
if head -$i $datFile | tail -1 | grep -E "\.0+([^[:digit:]])?$" > /dev/null
then
return 0
fi
done
fi
return 1
}
create_dat_header ()
{
local prod bench metrique numCacheConfigs -
prod="$1"
bench="$2"
metrique="$3"
numCacheConfigs="$4"
# Create file
> bench_$bench-prod_$prod-metrique_$metrique.dat
# Only one point per com and cache
if use_histo "$prod" "$bench"
then
for i in 1 2 3 # 1: total, 2: by loop, 3: by write
do
if [ $i -ne 1 ]
then
echo >> bench_$bench-prod_$prod-metrique_$metrique.dat
fi
echo -n "Method\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat
for cache in $cacheList
do
echo -n "\t$cache" >> bench_$bench-prod_$prod-metrique_$metrique.dat
done
done
# Several points per com and cache (one per calc argument)
else
for i in $(seq "$numCacheConfigs")
do
if [ $i -ne 1 ]
then
echo >> bench_$bench-prod_$prod-metrique_$metrique.dat
fi
for j in 1 2 3 # 1: total, 2: by loop, 3: by write
do
echo -n "argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat
for com in `eval echo \\\$\${bench}List`
do
echo -n "\t$com" >> bench_$bench-prod_$prod-metrique_$metrique.dat
done
echo >> bench_$bench-prod_$prod-metrique_$metrique.dat
done
done
fi
}
get_metric_values ()
{
local prod com cache argTypeProd logFile metricValues totalValue metricValue loopValue stepValue -
prod="$1"
com="$2"
cache="$3"
argTypeProd="$4"
metriquePattern="$5"
logFile=cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log
metricValues=$(grep -E "$metriquePattern" $logFile | sed -r "s/^ *($metriquePattern).*$/\1/;s/^ *([[:digit:]., ]+).*$/\1/;s/[,.]/./" | tr -d ' ')
totalValue=0
for metricValue in $metricValues
do
totalValue=$(echo "$totalValue + $metricValue" | bc)
done
echo -n "$totalValue"
loopValue="$(echo "$totalValue / $nbIter" | bc -l)"
echo -n " $loopValue"
stepValue=$(echo "$totalValue / $nbIter / $valuePerCacheLine" | bc -l)
echo -n " $stepValue"
}
create_simple_dat_body ()
{
local prod bench metrique argTypeProd -
prod="$1"
bench="$2"
metrique="$3"
argTypeProd="$4"
for com in `eval echo \\\$\${bench}List`
do
for i in 1 2 3 # 1: total, 2: by loop, 3: by write
do
echo -n "\n$com\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat
for cache in $cacheList
do
if [ $i -eq 1 ]
then
valuetmp=`get_metric_values "$prod" "$com" "$cache" "$argTypeProd" "$metriquePattern"`
eval value$cache=\"$valuetmp\"
fi
eval echo -n "\${value$cache}" | sed -r "s/^([^ ]+ ){$((i-1))}([^ ]+).*/\t\2/" >> bench_$bench-prod_$prod-metrique_$metrique.dat
done
done
done
}
create_complex_dat_body ()
{
local prod bench metrique firstComm argTypeProdList argTypeProd -
prod="$1"
bench="$2"
metrique="$3"
metriquePattern="$4"
firstComm=$(ls -1 *typeProd_$prod*.log | head -1 | sed -r "s/^.*nbIter_[^-]+-([^.]+)\.log$/\1/")
argTypeProdList=`eval ls *typeProd_$prod*${firstComm}.log | perl -ni -e '/argTypeProd_([\d]+)-/; $a{$1}=""; END { foreach ( sort { $a <=> $b } keys %a ) {print "$_ "}}'`
for argTypeProd in $argTypeProdList
do
for cache in $cacheList
do
if [ $cache != ${cacheList%% *} -o $argTypeProd != ${argTypeProdList%% *} ]
then
echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat
fi
for i in 1 2 3 # 1: total, 2: by loop, 3: by write
do
echo -n "\n$argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat
for com in `eval echo \\\$\${bench}List`
do
if [ $i -eq 1 ]
then
valuetmp=`get_metric_values "$prod" "$com" "$cache" "$argTypeProd" "$metriquePattern"`
eval value$com=\"$valuetmp\"
fi
eval echo -n "\${value$com}" | sed -r "s/^([^ ]+ ){$((i-1))}([^ ]+).*/\t\2/" >> bench_$bench-prod_$prod-metrique_$metrique.dat
done
done
done
done
}
create_dat_body ()
{
local prod bench metrique argTypeProd -
prod="$1"
bench="$2"
metrique="$3"
argTypeProd="$4"
if use_histo "$prod" "$bench"
then
create_simple_dat_body "$prod" "$bench" "$metrique" "$argTypeProd" "$metriquePattern"
else
create_complex_dat_body "$prod" "$bench" "$metrique" "$metriquePattern"
fi
}
create_gnuplot_header ()
{
local prod bench gnuplotFile -
prod="$1"
bench="$2"
gnuplotFile="$3"
echo "set style fill solid border -1" > $gnuplotFile
echo "set boxwidth 0.9" >> $gnuplotFile
echo "set xtic rotate by -45" >> $gnuplotFile
echo "set bmargin 5" >> $gnuplotFile
echo "set terminal postscript landscape color" >> $gnuplotFile
if use_histo "$prod" "$bench"
then
echo "set key autotitle columnhead" >> $gnuplotFile
echo "set style data histogram" >> $gnuplotFile
echo "set style histogram cluster gap 1" >> $gnuplotFile
else
echo "set style data linespoints" >> $gnuplotFile
fi
}
create_simple_gnuplot_body ()
{
local metrique ylabel yscale patternPlotFile datFile numCacheConfigs i -
ylabel="$1"
lineNum="$2"
datFile="$3"
patternPlotFile="$4"
numCacheConfigs="$5"
echo "set ylabel \"$ylabel\"" >> $patternPlotFile.gnuplot
echo "set output 'images/$patternPlotFile.ps'" >> $patternPlotFile.gnuplot
echo -n "plot '$datFile' every 3::$lineNum using 2:xtic(1)" >> $patternPlotFile.gnuplot
if [ $numCacheConfigs -ge 2 ]
then
i=2
while [ $i -le $numCacheConfigs ]
do
echo -n " , '' every 3::$lineNum u $((i+1))" >> $patternPlotFile.gnuplot
i=$((i+1))
done
fi
echo "" >> $patternPlotFile.gnuplot
}
create_complex_gnuplot_body ()
{
local bench ylabel lineNum datFile patternPlotFile columnNo baseTitle numCacheConfigs -
bench="$1"
ylabel="$2"
lineNum="$3"
datFile="$4"
patternPlotFile="$5"
numCacheConfigs="$6"
columnNo=2
echo "set ylabel \"$ylabel\"" >> $patternPlotFile.gnuplot
echo "set output 'images/$patternPlotFile.ps'" >> $patternPlotFile.gnuplot
for com in `eval echo \\\$\${bench}List` ; do
baseTitle=`head -1 $datFile | cut -f $((columnNo + 2))`
if [ $columnNo -ne 2 ]
then
echo -n ", '' " >> $patternPlotFile.gnuplot
else
echo -n "plot '$datFile' " >> $patternPlotFile.gnuplot
fi
echo -n "every :$numCacheConfigs:$lineNum:$((numCacheConfigs)):$lineNum using 1:$columnNo:xtic(1) title '$baseTitle (L2)'" >> $patternPlotFile.gnuplot
if [ $numCacheConfigs -gt 2 ]
then
echo -n ", '' every :$numCacheConfigs:$lineNum:$((numCacheConfigs * 2)):$lineNum using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> $patternPlotFile.gnuplot
fi
columnNo=$((columnNo + 1))
done
echo >> $patternPlotFile.gnuplot
}
create_gnuplot_body ()
{
local prod bench yscale ylabel lineNum datFile patternPlotFile numCacheConfigs -
prod="$1"
bench="$2"
yscale="$3"
ylabel="$4"
lineNum="$5"
datFile="$6"
patternPlotFile="$7"
numCacheConfigs="$8"
echo "set $yscale y" >> $patternPlotFile.gnuplot
if [ "$yscale" = "nologscale" ]
then
echo "set yrange [0:*]" >> $patternPlotFile.gnuplot
else
echo "set yrange [*:*]" >> $patternPlotFile.gnuplot
fi
echo "set title \"Producteur : $prod\"" >> $patternPlotFile.gnuplot
if use_histo "$prod" "$bench"
then
create_simple_gnuplot_body "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" "$numCacheConfigs"
else
create_complex_gnuplot_body "$bench" "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" "$numCacheConfigs"
fi
}
create_gnuplot_file ()
{
local prod bench metrique ylabel yscale avg lineNum numCacheConfigs -
prod="$1"
bench="$2"
metrique="$3"
baseYlabel="$4"
numCacheConfigs="$5"
for yscale in "nologscale" "logscale"
do
for avg in total byLoop byWrite
do
case $avg in
total)
lineNum=0
ylabel="$baseYlabel" ;;
byLoop)
lineNum=1
ylabel="$baseYlabel par boucle" ;;
byWrite)
lineNum=2
ylabel="$baseYlabel par ecriture" ;;
esac
datFile=bench_$bench-prod_$prod-metrique_$metrique.dat
patternPlotFile="bench_$bench-prod_$prod-$metrique-$avg-$yscale" # Name without extension of plot and ps files
if [ $yscale != "logscale" ] || ! contains_zero "$prod" "$bench" "$datFile" "$lineNum" "$numCacheConfigs"
then
create_gnuplot_header "$prod" "$bench" "$patternPlotFile.gnuplot"
create_gnuplot_body "$prod" "$bench" "$yscale" "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" "$numCacheConfigs"
fi
done
done
}
main()
{
local logDir benchName -
parse_args "$@"
cd $logDir
init_bench_vars
init_log_vars
for prod in $prodList ; do
case "$prod" in
matrice) argTypeProd=\* ;;
*) argTypeProd=\* ;;
esac
for bench in "communication" "barriere" ; do
eval benchName="\${${bench}List:-}"
if [ -n "${benchName}" ]
then
# Create dat headers
for metrique in $metriqueList ; do
case "$metrique" in
cache_hits)
metriquePattern="[[:digit:] ]+(L1-dcache-loads|L1-dcache-stores|L1-dcache-prefetches|LLC-loads|LLC-stores|LLC-prefetches) "
ylabel="Nb cache hit" ;;
cache_miss)
metriquePattern="[[:digit:] ]+(L1-dcache-load-misses|L1-dcache-store-misses|L1-dcache-prefetch-misses|LLC-load-misses|LLC-store-misses|LLC-prefetch-misses) "
ylabel="Nb cache miss" ;;
cycles)
metriquePattern="[[:digit:] ]+cycles "
ylabel="Nb cycles" ;;
total_time)
metriquePattern="[[:digit:]., ]+seconds time elapsed "
ylabel="Secondes" ;;
*)
echo "Pas de pattern pour cette métrique : $metrique"
echo "Pas de label pour cette métrique : $metrique"
exit 1 ;;
esac
numCacheConfigs=$(echo "$cacheList" | wc -w)
create_dat_header "$prod" "$bench" "$metrique" "$numCacheConfigs"
create_dat_body "$prod" "$bench" "$metrique" "$argTypeProd" "$metriquePattern"
create_gnuplot_file "$prod" "$bench" "$metrique" "$ylabel" "$numCacheConfigs"
done
fi
done
done
if [ ! -d images ]
then
mkdir images
fi
for gnuplotFile in *.gnuplot
do
gnuplot "$gnuplotFile"
done
cd images
for psFile in *.ps
do
ps2pdf $psFile
done
}
main "$@"