#!/bin/sh
# StarPU --- Runtime system for heterogeneous multicore architectures.
#
# Copyright (C) 2010-2023   Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
#
# StarPU is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# StarPU is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See the GNU Lesser General Public License in COPYING.LGPL for more details.
#
PROGNAME=$0

usage()
{
    echo "Offline tool to display the activity of the workers during the execution."
    echo ""
    echo "  The starpu_fxt_tool utility now generates a file named 'activity.data' which"
    echo "  can be processed by this script to generate a plot named activity.eps"
    echo ""
    echo "  Typical usage:"
    echo "     ./starpu_fxt_tool -i /tmp/prof_file_foo &&"
    echo "     $PROGNAME activity.data"
    echo ""
    echo "Options:"
    echo "	-h, --help          display this help and exit"
    echo "	-v, --version       output version information and exit"
    echo "	-d directory        where to save output files, by default current directory"
    echo ""
    echo "Report bugs to <starpu-devel@inria.fr>"
    exit 0
}

if [ "$1" = "-v" ] || [ "$1" = "--version" ] ; then
    echo "$PROGNAME (StarPU) 1.4.7"
    exit 0
fi

if [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "" ] ; then
    usage
fi

odir="."
if [ "$1" = "-d" ]
then
    odir=$2
    shift ; shift
fi
if [ ! -f $1 ] ; then
    echo "Error. File <$1> not found"
    echo ""
    usage
fi

# The input file must be generated by the starpu_fxt_tool command
inputfile_with_counters=$1

# We extract the counters out of the input file
dir=$(dirname $1)
inputfile=$dir/.$(basename $1).activity
inputfile_cnt_ready=$dir/.$(basename $1).cnt_ready
inputfile_cnt_submitted=$dir/.$(basename $1).cnt_submitted
set_profiling_list=$dir/.$(basename $1).set_profiling_list
names=$dir/.$(basename $1).names

grep "^set_profiling" $inputfile_with_counters > $set_profiling_list
grep "0$" $set_profiling_list | cut -f 2 | sort -n > $set_profiling_list.disable
grep "1$" $set_profiling_list | cut -f 2 | sort -n > $set_profiling_list.enable

grep "^name" $inputfile_with_counters > $names

grep -v "^cnt" $inputfile_with_counters | grep -v "^set_profiling" | grep -v "^name" > $inputfile
grep "^cnt_ready" $inputfile_with_counters > $inputfile_cnt_ready
grep "^cnt_submitted" $inputfile_with_counters > $inputfile_cnt_submitted

# Count the number of workers in the trace
workers=`cut -f1 $inputfile | sort -n | uniq`
nworkers=`cut -f1 $inputfile | sort -n | uniq|wc -l`

# size of the entire graph
width=1.5
height=0.40
total_height=$(echo "$height + ($height * $nworkers)"|bc -l)

# In case 3 arguments are provided, the 2nd (resp. 3rd) indicates the start
# (resp. the end) of the interval to be displayed.
if [ $# -ge 3 ]; then
    starttime=$2
    endtime=$3
else
    #if profiling is explicitly enabled (resp. disabled) at some point, we set the
    # default start (rest. end) point when we enable (resp. disable) profiling for
    # the first time.
    profiling_enable_cnt=`wc -l $set_profiling_list.enable|sed -e "s/\(.*\) .*/\1/"`
    if [ $profiling_enable_cnt -ge 1 ]; then
	starttime=`head -1 $set_profiling_list.enable`
    else
	starttime=$(cut -f 2 $inputfile |sort -n|head -1)
    fi

    # TODO test if last disable > first enable

    profiling_disable_cnt=$(wc -l $set_profiling_list.disable|sed -e "s/\(.*\) .*/\1/")
    if [ $profiling_disable_cnt -ge 1 ]; then
	endtime=`tail -1 $set_profiling_list.disable`
    else
	endtime=$(cut -f 2 $inputfile |sort -n|tail -1)
    fi

    # The values in the file are in ms, we display seconds
    starttime=$(echo "$starttime * 0.001 "| bc -l)
    endtime=$(echo "$endtime * 0.001 "| bc -l)
fi

echo "START $starttime END $endtime"

# Gnuplot header
cat > gnuplotcmd << EOF
set term postscript eps enhanced color
set output "$odir/activity.eps"
set xrange [$starttime:$endtime]
set size $width,$total_height
set multiplot;

set origin 0.0,0.0;
set size $width,$height;

set logscale y

plot "$inputfile_cnt_submitted" using (\$2/1000):3 with filledcurves lt rgb "#999999" title "submitted",\
	"$inputfile_cnt_ready" using (\$2/1000):3 with filledcurves lt rgb "#000000" title "ready"

set nologscale y

EOF

cnt=0
for worker in $workers
do
	grep "^$worker\s" $inputfile > .tmp.$worker

	starty=$(echo "$height + ($height * $cnt)"|bc -l)

cat >> gnuplotcmd << EOF

set origin 0.0,$starty;
set size $width,$height;

set key off

set yrange [0:100]

set ylabel "$(cut -f2- $names |grep "^$worker$" | cut -f2)"

plot ".tmp.$worker" using (\$2/1000):(100) with filledcurves y1=0.0 lt rgb "#000000" notitle,\
	 ".tmp.$worker" using (\$2/1000):((100*(\$4+\$5))/\$3) with filledcurves y1=0.0 lt rgb "#ff0000" notitle,\
	 ".tmp.$worker" using (\$2/1000):((100*\$4)/\$3) with filledcurves y1=0.0 lt rgb "#00ff00" notitle
EOF

	cnt=$(($cnt+1))	
done


cat >> gnuplotcmd << EOF
unset multiplot
EOF

gnuplot < gnuplotcmd

rm gnuplotcmd
rm $inputfile
rm $inputfile_cnt_ready
rm $inputfile_cnt_submitted

rm $set_profiling_list
rm $set_profiling_list.enable
rm $set_profiling_list.disable

#rm $names

for worker in $workers
do
	rm .tmp.$worker
done
