Monday, 20 March 2017

summarizeSpecTimes.sh

Borrowed from Nemanja, need to learn.


#!/usr/bin/env bash

if [[ -z "$3" ]]     # here  -z means: True if string is empty. from 'help test' doc
then
  echo "Usage: $0 -o <DIR> Baseline:<SPEC.out.csv> [<NAME>:<SPEC.out.csv> ...]"
  echo
  echo "This script creates a csv file that contains a summary of multiple SPEC"
  echo "run result csv files. The baseline is assumed to be the very first file"
  echo "passed in."
  echo "The -o option is mandatory and must appear prior to the list of files."
  echo
  echo "Sample invocation:"
  echo "$0 -o Summaries Baseline:CINT2006.110.ref.csv \\"
  echo "  Baseline:CFP2006.110.ref.csv NoCRBits:CINT2006.112.ref.csv \\"
  echo "  NoCRBits:CFP2006.112.ref.csv CheapBR:CINT2006.111.ref.csv \\"
  echo "  CheapBR:CFP2006.111.ref.csv"
  echo
  echo "Implementation detail: For processing the inputs, the script will"
  echo "create a directory for each of the named runs which it will clean"
  echo "up after. If this directory happens to contain directories of the"
  echo "same name, the script will prompt you before overwriting them."
  exit 1
fi

###########################SCRIPT BEGINS ON LINE 78#############################

function summarizeBench {
  SUMMARY=""
  if [ $(cat CurrBenchRunTimes.txt | wc -l) -eq 1 ]
  then
    cat CurrBenchRunTimes.txt CurrBenchRunTimes.txt > tmpCurrBenchRunTimes.txt
    mv tmpCurrBenchRunTimes.txt CurrBenchRunTimes.txt
  fi
  while read RT
  do
    SUMMARY="$SUMMARY $RT"
  done < CurrBenchRunTimes.txt
  echo $1,$($SUMMARIZE -a $SUMMARY)
}

function summarizeIndividualFile {
  START=0
  PREV_BENCH=""
  while IFS=, read BENCH REF_T RUN_T RATIO REST
  do
    if [ "$BENCH" = Benchmark ]
    then
      START=1
      continue
    fi
    if [ $START -ne 1 ]
    then
      continue
    fi
    if echo $REST | grep ',NR,' > /dev/null
    then
      continue
    fi
    if [[ -z "$BENCH" ]]
    then
      summarizeBench $PREV_BENCH
      break
    fi
    if [ "$BENCH" = "$PREV_BENCH" ]
    then
      echo $RUN_T >> CurrBenchRunTimes.txt
    else
      if [[ -n "$PREV_BENCH" ]]
      then
        summarizeBench $PREV_BENCH
      fi
      PREV_BENCH=$BENCH
      echo $RUN_T > CurrBenchRunTimes.txt
    fi
  done < $FILE_TO_READ
}

function addNamedSummary {
  echo "$(head -1 $OUTDIR/FinalSPECSummary.csv),$1(Median),$1(Best),$1(Worst),$1(%Variance),$1(%Diff(Median)),$1(%Diff(Best)),$1(%Diff(Worst))" > tmpSPECSummarizer.txt
  cat $1/* | while IFS=, read BENCH MEDIAN BEST WORST VARIANCE
    do
      BASE_LINE=$(grep ^$BENCH $OUTDIR/FinalSPECSummary.csv)
      BASE_MEDIAN=$(echo $BASE_LINE | cut -f2 -d,)
      BASE_BEST=$(echo $BASE_LINE | cut -f3 -d,)
      BASE_WORST=$(echo $BASE_LINE | cut -f4 -d,)

      DIFF_MEDIAN=$($SUMMARIZE -d $BASE_MEDIAN $MEDIAN)
      DIFF_BEST=$($SUMMARIZE -d $BASE_BEST $BEST)
      DIFF_WORST=$($SUMMARIZE -d $BASE_WORST $WORST)

      echo $(grep ^$BENCH $OUTDIR/FinalSPECSummary.csv),$MEDIAN,$BEST,$WORST,$VARIANCE,$DIFF_MEDIAN,$DIFF_BEST,$DIFF_WORST
    done >> tmpSPECSummarizer.txt
    mv tmpSPECSummarizer.txt $OUTDIR/FinalSPECSummary.csv
}

function cleanupIfNeeded {
  grep $RUN_NAME SPECSummarizerDirectories.txt > /dev/null
  UNSEEN_DIR=$?
  if [ $UNSEEN_DIR -ne 0 ]
  then
    echo $RUN_NAME >> SPECSummarizerDirectories.txt
    ls $RUN_NAME > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
      echo "Directory $RUN_NAME already exists. Overwrite (Y/N)?"
      read ANS<&1
      if echo "$ANS" | grep -i ^y
      then
        echo Overwriting...
        rm -Rf $RUN_NAME
      else
        exit 1
      fi
    fi
  fi
}

################################SCRIPT BEGINS###################################
if [ "$1" != "-o" ]
then
  echo "The -o option is mandatory as the first argument."
  exit 1
fi
shift
OUTDIR=$1
shift
ls $OUTDIR > /dev/null 2>&1 || mkdir $OUTDIR
if [[ $? -ne 0 ]]
then
  echo "Unable to create directory '$OUTDIR' that you specified as the output directory."
  exit 1
fi

# Build the summarizer executable
if which summarize >/dev/null 2>&1
then
  SUMMARIZE=$(which summarize)
else
  START_AT=$(grep -n '^#include' $0 | head -1 | cut -f1 -d:)
  END_AT=$(cat $0 | wc -l)
  CPROG_LINES=$(expr $END_AT - $START_AT)
  ((CPROG_LINES += 1))
  tail -$CPROG_LINES $0 > /tmp/summarize.cpp
  g++ /tmp/summarize.cpp -o summarize
  if [[ $? -ne 0 ]]
  then
    rm -f /tmp/summarize.cpp
    exit 1
  fi
  SUMMARIZE=./summarize
fi

rm -f SPECSummarizerDirectories.txt 2>/dev/null
# Summarize each of the individual files and put the summaries in separate dirs
while [[ -n "$1" ]]
do
  touch SPECSummarizerDirectories.txt
  FILE_TO_READ=${1#*:}
  RUN_NAME=${1%:*}
  cleanupIfNeeded
  mkdir $RUN_NAME 2>/dev/null
  grep $RUN_NAME SPECSummarizerDirectories.txt > /dev/null || echo $RUN_NAME >> SPECSummarizerDirectories.txt
  summarizeIndividualFile > $RUN_NAME/$FILE_TO_READ.SPECSummarizerSummary.txt
  echo "$RUN_NAME" > $OUTDIR/$RUN_NAME.$FILE_TO_READ
  cat $FILE_TO_READ >> $OUTDIR/$RUN_NAME.$FILE_TO_READ
  shift
done

echo "Benchmark,Baseline(Median),Baseline(Best),Baseline(Worst),Baseline(%Variance)" > $OUTDIR/FinalSPECSummary.csv
cat $(head -1 SPECSummarizerDirectories.txt)/* >> $OUTDIR/FinalSPECSummary.csv

# Combine all the individual summaries into one csv file
I=0
cat SPECSummarizerDirectories.txt | while read DIR
  do
    ((I += 1))
    if [ $I -eq 1 ]
    then
      continue
    fi
# The first one is the baseline, skip it
    echo Summarizing $DIR
    addNamedSummary $DIR
  done

# Add all the individual run summary files to the full summary
cat SPECSummarizerDirectories.txt | while read DIR
  do
    echo "$DIR" >> $OUTDIR/FinalSPECSummary.csv
    echo "Benchmark,mean,best,worst,variance" >> $OUTDIR/FinalSPECSummary.csv
    cat $DIR/* >> $OUTDIR/FinalSPECSummary.csv
  done
# Clean up
rm -Rf $(cat SPECSummarizerDirectories.txt)
rm -f /tmp/summarize.cpp ./summarize ./CurrBenchRunTimes.txt SPECSummarizerDirectories.txt
echo "Result is in file $OUTDIR/FinalSPECSummary.csv"

################################SCRIPT ENDS#####################################
exit 0
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>

double getMedian(std::vector<double> &Vec) {
  std::sort(Vec.begin(), Vec.end());
  int Size = Vec.size();
  if (!Size) return 0.;
  if (Size % 2)
    return Vec[Size/2];
  return (Vec[Size/2] + Vec[Size/2-1]) / 2;
}

// Assume the vector is sorted at this point
double getVariance(const std::vector<double> &Vec, double Median) {
  double Min = Vec[0];
  double Max = Vec[Vec.size()-1];
  return (Max - Min) / Median * 100.;
}

int main(int argc, const char **argv) {
  if (argc < 4) {
    fprintf(stderr, "Usage: %s [opt] <time1> <time2> [<time3>...]\n", argv[0]);
    fprintf(stderr, "       opt is one of -a or -d (for all or diff).\n");
    fprintf(stderr, "       The output for -a is: median,best,worst,variance.\n");
    fprintf(stderr, "       The output for -d is: ((time2-time1)/time1*100)%%.\n");
    return 1;
  }

  // Computing the diff
  if (!strcmp(argv[1], "-d")) {
    double T1 = strtod(argv[2], NULL);
    double T2 = strtod(argv[3], NULL);
    printf("%.2f%%\n", (T2-T1)/T1*100);
    return 0;
  } else if (strcmp(argv[1], "-a")) {
    fprintf(stderr, "Unrecognized option %s\n", argv[1]);
    return 1;
  }

  std::vector<double> RTSet;
  int i = 2;
  for (; i < argc; i++) {
    RTSet.push_back(strtod(argv[i], NULL));
  }
  double Median = getMedian(RTSet);
  printf("%.4f,%.4f,%.4f,%.2f%%\n", Median, RTSet[0], RTSet[RTSet.size()-1],
         getVariance(RTSet, Median));
  return 0;
}

No comments:

Post a Comment