#!/bin/bash

function replace() # KEY VALUE FILE
{
  # strip leading zeros that confuse ccc_msub
  VALUE=$(echo $2 | sed 's/^0*//')
  sed -i -e "s/$1/$VALUE/g" $3
  echo "$1=$VALUE" >> params.sh
}

function create_run() # NBP TIME_STEP NSPLIT OMP_LEVEL_SIZE NB_MPI NB_OMP
{
  NBP=$1
  TIME_STEP=$2
  shift; shift

  NAME="run_$1_$2_$3_$4"
  mkdir $NAME
  cp run.def job.sh mpmd.conf gcm.sh *.xml $NAME
  cd $NAME
  touch params.sh

  replace NBP $NBP run.def
  replace TIME_STEP $TIME_STEP run.def
  replace NSPLIT $1 run.def
  replace OMP_LEVEL_SIZE $2 run.def
  replace NUM_MPI $3 mpmd.conf
  replace NUM_MPI $3 job.sh
  replace NUM_OMP $4 job.sh
  cd ..
}

function cmd_create_220km()
{
  rm -rf run_*
  create_run 41 600 4 6 040 24
  create_run 41 600 4 6 080 12
  create_run 41 600 4 6 160 06
  create_run 41 600 4 4 160 04
  create_run 41 600 4 4 080 08
  create_run 41 600 4 2 040 08
  create_run 41 600 4 1 020 08
  create_run 41 600 4 1 040 04
  create_run 41 600 4 1 080 02
  create_run 41 600 4 1 160 01
  create_run 41 600 2 1 040 01
  ls -d run_*
}

function cmd_create_110km()
{
  rm -rf run_*
  create_run 81 300 4 1 160 01
  create_run 81 300 6 1 360 01
  create_run 81 300 8 1 160 04
  create_run 81 300 8 1 640 01
  ls -d run_*
}

function cmd_create_70km()
{
  rm -rf run_*
  create_run 129 200 8 1 640 01
  create_run 129 200 10 1 1000 01
  create_run 129 200 12 1 1440 01
  create_run 129 200 16 1 2560 01
  ls -d run_*
}

function cmd_create_35km()
{
  rm -rf run_*
  create_run 257 100 12 1 1440 1
  create_run 257 100 12 1 0720 2
  create_run 257 100 12 1 0360 4
  create_run 257 100 12 1 0120 12
  create_run 257 100 12 1 0060 24
  create_run 257 100 12 2 1440 2
  create_run 257 100 12 4 1440 4
  create_run 257 100 12 6 1440 6
  create_run 257 100 12 8 1440 8
  create_run 257 100 16 1 2560 1
  create_run 257 100 16 1 1280 2
  create_run 257 100 16 1 0640 4
  create_run 257 100 16 1 0320 8
  create_run 257 100 16 4 2560 4
  create_run 257 100 16 6 2560 6
  create_run 257 100 16 8 2560 8
  create_run 257 100 24 4 5760 4
  ls -d run_*
}

function cmd_create_8km()
{
  rm -rf run_*
  create_run 1025 20 32 1 2560 4
  ls -d run_*
}

function cmd_submit()
{
  for RUN in run_* ; do
      cd $RUN
      if [ -f already_done ]; then
	  echo "$RUN has run already."
      else
	  ccc_msub job.sh
      fi
      cd ..
  done
}

#------------------------------------- Reporting --------------------------------------

function get_troughput()
{
    grep Throughput logs/gcm.log | tail -n 5 | awk '{print $12}' | sort -r | head -n 1
}

function get_ms_step()
{
    grep 'ms/step' logs/gcm.log | tail -n 5 | awk '{print $8}' | sort -r | head -n 1
}

function get_frac()
{
    grep $1 logs/gcm.log | grep -v DEFAULT | grep -v caldyn | grep -v nqdyn | tail -n 4 | head -n 1 | awk '{print $3}'
}
function cmd_stats()
{
    echo RUN frac_dyn_adv frac_MPI Throughput ms/step 
    for RUN in run_* ; do
	cd $RUN
#	pwd
#	ls logs/gcm.log
	frac_adv=$(get_frac adv)
	frac_dyn=$(get_frac dyn)
	frac_adv_MPI=$(get_frac adv_MPI)
	frac_dyn_MPI=$(get_frac dyn_MPI)
#	echo $frac_adv $frac_dyn $frac_adv_MPI $frac_dyn_MPI
	echo $RUN $(( frac_adv+frac_dyn )) $((frac_adv_MPI+frac_dyn_MPI)) $(get_troughput) $(get_ms_step)
        cd ..
    done
}

function MPI()
{
    run=$1
    cmd=$2
    nprocs=$(echo $run | tr "_" ' ' | awk '{print $4'} )
    nprocs=$(compute $nprocs)
    stats=$(grep MPI_$cmd $run/logs/gcm.log | tail -n 1)
    time=$(echo $stats | awk '{print $3}')
    count=$(echo $stats | awk '{print $4}')
    wall=$(echo $stats | awk '{print $5}')
#    echo $stats
#    echo $nprocs $time $count $wall >&2
#    echo $run $cmd
    echo $run $cmd $(compute "$time/$nprocs") $((count/nprocs)) $wall
}

function compute()
{
    bc <<< "scale=2 ; $1"
}
function cmd_MPI()
{
# MPI_Waitall MPI_Alltoall MPI_Allreduce MPI_Bcast MPI_Barrier MPI_Isend MPI_Comm_size MPI_Reduce MPI_Irecv MPI_Comm_rank MPI_Init MPI_Finalize
    echo '# [run] [func] [time] [count] <%wall>'
    for cmd in Alltoall Allreduce Bcast Waitall Barrier ; do
	for run in run_* ; do 
#	    echo $run $(grep MPI_$cmd $run/logs/gcm.log)
	    MPI $run $cmd
	done 
    done
}
function  elapsed()
{
    cd $1
    useful=$(grep elapsed logs/gcm.log | awk '{print $4}')
    echo $useful
    hhmmss=$(grep icosa_gcm.exe DYN_bench*.o | awk '{print $7}')
    minutes=$(date +'%M' -d $hhmmss)
    seconds=$(date +'%S' -d $hhmmss)    
    echo $(compute "$seconds+60*$minutes-$useful")
    cd ..
}

function cmd_elapsed()
{
    for x in run_* ; do
	echo $x $(elapsed $x)
    done
}

#---------------------------------------------------------------------------------------

function cmd_clean()
{
    rm -f $(find . -name restart.nc)
}

echo "Usage : benchmark.sh COMMAND"
echo "Available commands : create_220km create_35km submit clean stats"
echo "Your command : $1"

cmd_$1
