xref: /libCEED/benchmarks/benchmark.sh (revision d4cc18453651bd0f94c1a2e078b2646a92dafdcc)
12f4d9adbSJeremy L Thompson#!/bin/bash
22f4d9adbSJeremy L Thompson
3*9ba83ac0SJeremy L Thompson# Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
45aed82e4SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
52f4d9adbSJeremy L Thompson#
65aed82e4SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause
72f4d9adbSJeremy L Thompson#
85aed82e4SJeremy L Thompson# This file is part of CEED:  http://github.com/ceed
92f4d9adbSJeremy L Thompson
102f4d9adbSJeremy L Thompsonthis_file="${BASH_SOURCE[0]}"
112f4d9adbSJeremy L Thompsonif [[ "${#BASH_ARGV[@]}" -ne "$#" ]]; then
122f4d9adbSJeremy L Thompson   script_is_sourced="yes"
132f4d9adbSJeremy L Thompson   exit_cmd=return
142f4d9adbSJeremy L Thompsonelse
152f4d9adbSJeremy L Thompson   script_is_sourced=""
162f4d9adbSJeremy L Thompson   exit_cmd=exit
172f4d9adbSJeremy L Thompsonfi
182f4d9adbSJeremy L Thompsontest_file=""
192f4d9adbSJeremy L Thompsonbackend_list="/cpu/self"
200c59ef15SJeremy L Thompsonbp_list="bp1 bp3"
212f4d9adbSJeremy L Thompsonrun=""
222f4d9adbSJeremy L Thompsonnum_proc_run=${num_proc_run:-""}
232f4d9adbSJeremy L Thompsonnum_proc_node=${num_proc_node:-""}
242f4d9adbSJeremy L Thompsondry_run="" # empty string = NO
252f4d9adbSJeremy L Thompsonstart_shell=""
262f4d9adbSJeremy L Thompsonverbose=""
272f4d9adbSJeremy L Thompsoncur_dir="$PWD"
282f4d9adbSJeremy L Thompson
292f4d9adbSJeremy L Thompsonmpiexec="mpirun"
302f4d9adbSJeremy L Thompsonmpiexec_np="-np"
312f4d9adbSJeremy L Thompsonmpiexec_opts=""
322f4d9adbSJeremy L Thompsonmpiexec_post_opts=""
332f4d9adbSJeremy L Thompsonprofiler=""
342f4d9adbSJeremy L Thompson
352f4d9adbSJeremy L Thompsonfunction abspath()
362f4d9adbSJeremy L Thompson{
372f4d9adbSJeremy L Thompson   local outvar="$1" path="$2" cur_dir="$PWD"
382f4d9adbSJeremy L Thompson   cd "$path" && path="$PWD" && cd "$cur_dir" && eval "$outvar=\"$path\""
392f4d9adbSJeremy L Thompson}
402f4d9adbSJeremy L Thompson
412f4d9adbSJeremy L Thompsonabspath root_dir ".." || $exit_cmd 1
422f4d9adbSJeremy L Thompsonbuild_root="$root_dir/build"
432f4d9adbSJeremy L Thompson
442f4d9adbSJeremy L Thompsonif [[ -t 1 ]]; then
452f4d9adbSJeremy L Thompson   # ANSI color codes
462f4d9adbSJeremy L Thompson   none=$'\E[0m'
472f4d9adbSJeremy L Thompson   red=$'\E[0;31m'
482f4d9adbSJeremy L Thompson   green=$'\E[0;32m'
492f4d9adbSJeremy L Thompson   yellow=$'\E[0;33m'
502f4d9adbSJeremy L Thompson   blue=$'\E[0;34m'
512f4d9adbSJeremy L Thompson   bblue=$'\E[1;34m'
522f4d9adbSJeremy L Thompson   magenta=$'\E[0;35m'
532f4d9adbSJeremy L Thompson   cyan=$'\E[0;36m'
542f4d9adbSJeremy L Thompson   clear="$(tput sgr0)"
552f4d9adbSJeremy L Thompsonfi
562f4d9adbSJeremy L Thompson
572f4d9adbSJeremy L Thompsonhelp_msg="
582f4d9adbSJeremy L Thompson$this_file [options]
592f4d9adbSJeremy L Thompson
602f4d9adbSJeremy L ThompsonOptions:
612f4d9adbSJeremy L Thompson   -h|--help                print this usage information and exit
620c59ef15SJeremy L Thompson   -b|--bp \"list\"           choose the benchmark problems to run
632f4d9adbSJeremy L Thompson   -c|--ceed \"list\"         choose the libCEED backends to benchmark
642f4d9adbSJeremy L Thompson   -r|--run <name>          run the tests in the script <name>
652f4d9adbSJeremy L Thompson   -n|--num-proc \"list\"     total number of MPI tasks to use in the tests
662f4d9adbSJeremy L Thompson   -p|--proc-node \"list\"    number of MPI tasks per node to use in the tests
672f4d9adbSJeremy L Thompson   -d|--dry-run             show (but do not run) the commands for the tests
682f4d9adbSJeremy L Thompson   -s|--shell               execute bash shell commands before running the test
692f4d9adbSJeremy L Thompson   -v|--verbose             print additional messages
702f4d9adbSJeremy L Thompson   -x                       enable script tracing with 'set -x'
712f4d9adbSJeremy L Thompson   var=value                define shell variables; evaluated with 'eval'
722f4d9adbSJeremy L Thompson
732f4d9adbSJeremy L ThompsonThis script builds and runs a set of benchmarks for a list of specified
742f4d9adbSJeremy L Thompsonbackends.
752f4d9adbSJeremy L Thompson
762f4d9adbSJeremy L ThompsonExample usage:
77cb32e2e7SValeria Barra  $this_file  --run petsc-bpsraw.sh
78e1ef8755Svaleriabarra  $this_file  --run petsc-bps.sh
792f4d9adbSJeremy L Thompson"
802f4d9adbSJeremy L Thompson
812f4d9adbSJeremy L Thompsonfunction build_examples()
822f4d9adbSJeremy L Thompson{
832f4d9adbSJeremy L Thompson   for example; do
842f4d9adbSJeremy L Thompson      # We require the examples to be already built because we do not know what
852f4d9adbSJeremy L Thompson      # options to use when building the library + examples.
862f4d9adbSJeremy L Thompson      if [ ! -e $build_root/$example ]; then
872f4d9adbSJeremy L Thompson         echo "Error: example is not built: $example"
882f4d9adbSJeremy L Thompson         return 1
892f4d9adbSJeremy L Thompson      fi
902f4d9adbSJeremy L Thompson   done
912f4d9adbSJeremy L Thompson}
922f4d9adbSJeremy L Thompson
932f4d9adbSJeremy L Thompsonfunction compose_mpi_run_command()
942f4d9adbSJeremy L Thompson{
952f4d9adbSJeremy L Thompson   mpi_run="${mpiexec:-mpirun} ${mpiexec_opts}"
962f4d9adbSJeremy L Thompson   mpi_run+=" ${mpiexec_np:--np} ${num_proc_run} ${mpiexec_post_opts}"
972f4d9adbSJeremy L Thompson   if [[ -n "$profiler" ]]; then
982f4d9adbSJeremy L Thompson      mpi_run+=" $profiler"
992f4d9adbSJeremy L Thompson   fi
1002f4d9adbSJeremy L Thompson}
1012f4d9adbSJeremy L Thompson
1022f4d9adbSJeremy L Thompsonfunction quoted_echo()
1032f4d9adbSJeremy L Thompson{
1042f4d9adbSJeremy L Thompson   local arg= string=
1052f4d9adbSJeremy L Thompson   for arg; do
1062f4d9adbSJeremy L Thompson      if [[ -z "${arg##* *}" ]]; then
1072f4d9adbSJeremy L Thompson         string+=" \"${arg//\"/\\\"}\""
1082f4d9adbSJeremy L Thompson      else
1092f4d9adbSJeremy L Thompson         string+=" $arg"
1102f4d9adbSJeremy L Thompson      fi
1112f4d9adbSJeremy L Thompson   done
1122f4d9adbSJeremy L Thompson   printf "%s\n" "${string# }"
1132f4d9adbSJeremy L Thompson}
1142f4d9adbSJeremy L Thompson
1152f4d9adbSJeremy L Thompsonfunction set_num_nodes()
1162f4d9adbSJeremy L Thompson{
1172f4d9adbSJeremy L Thompson   if [[ -n "$num_proc_node" ]]; then
1182f4d9adbSJeremy L Thompson      ((num_proc_run % num_proc_node != 0)) && {
1192f4d9adbSJeremy L Thompson         echo "The total number of tasks ($num_proc_run) must be a multiple of"
1202f4d9adbSJeremy L Thompson         echo "the number of tasks per node ($num_proc_node). Stop."
1212f4d9adbSJeremy L Thompson         return 1
1222f4d9adbSJeremy L Thompson      }
1232f4d9adbSJeremy L Thompson      ((num_nodes = num_proc_run / num_proc_node))
1242f4d9adbSJeremy L Thompson   else
1252f4d9adbSJeremy L Thompson      num_proc_node="unknown number of"
1262f4d9adbSJeremy L Thompson      num_nodes=""
1272f4d9adbSJeremy L Thompson   fi
1282f4d9adbSJeremy L Thompson   echo "Running the tests using a total of $num_proc_run MPI tasks ..." | tee -a $output_file
1292f4d9adbSJeremy L Thompson   echo "... with $num_proc_node tasks per node ..." | tee -a $output_file
1302f4d9adbSJeremy L Thompson   echo | tee -a $output_file
1312f4d9adbSJeremy L Thompson}
1322f4d9adbSJeremy L Thompson
1332f4d9adbSJeremy L Thompson### Process command line parameters
1342f4d9adbSJeremy L Thompson
1352f4d9adbSJeremy L Thompsonwhile [ $# -gt 0 ]; do
1362f4d9adbSJeremy L Thompson
1372f4d9adbSJeremy L Thompsoncase "$1" in
1382f4d9adbSJeremy L Thompson   -h|--help)
1392f4d9adbSJeremy L Thompson      # Echo usage information
1402f4d9adbSJeremy L Thompson      echo "$help_msg"
1412f4d9adbSJeremy L Thompson      $exit_cmd
1422f4d9adbSJeremy L Thompson      ;;
1430c59ef15SJeremy L Thompson   -b|--bp)
1440c59ef15SJeremy L Thompson      shift
1450c59ef15SJeremy L Thompson      [ $# -gt 0 ] || {
1460c59ef15SJeremy L Thompson      echo "Missing \"list\" in --bp \"list\""; $exit_cmd 1; }
1470c59ef15SJeremy L Thompson      bp_list="$1"
1480c59ef15SJeremy L Thompson      ;;
1492f4d9adbSJeremy L Thompson   -c|--ceed)
1502f4d9adbSJeremy L Thompson      shift
1512f4d9adbSJeremy L Thompson      [ $# -gt 0 ] || {
1522f4d9adbSJeremy L Thompson      echo "Missing \"list\" in --ceed \"list\""; $exit_cmd 1; }
1532f4d9adbSJeremy L Thompson      backend_list="$1"
1542f4d9adbSJeremy L Thompson      ;;
1552f4d9adbSJeremy L Thompson   -r|--run)
1562f4d9adbSJeremy L Thompson      run=on
1572f4d9adbSJeremy L Thompson      shift
1582f4d9adbSJeremy L Thompson      [ $# -gt 0 ] || { echo "Missing <name> in --run <name>"; $exit_cmd 1; }
1592f4d9adbSJeremy L Thompson      test_file="$1"
1602f4d9adbSJeremy L Thompson      [[ -r "$test_file" ]] || {
1612f4d9adbSJeremy L Thompson         echo "Test script not found: '$1'"; $exit_cmd 1
1622f4d9adbSJeremy L Thompson      }
1632f4d9adbSJeremy L Thompson      ;;
1642f4d9adbSJeremy L Thompson   -n|--num-proc)
1652f4d9adbSJeremy L Thompson      shift
1662f4d9adbSJeremy L Thompson      [ $# -gt 0 ] || {
1672f4d9adbSJeremy L Thompson      echo "Missing \"list\" in --num-proc \"list\""; $exit_cmd 1; }
1682f4d9adbSJeremy L Thompson      num_proc_run="$1"
1692f4d9adbSJeremy L Thompson      ;;
1702f4d9adbSJeremy L Thompson   -p|--proc-node)
1712f4d9adbSJeremy L Thompson      shift
1722f4d9adbSJeremy L Thompson      [ $# -gt 0 ] || {
1732f4d9adbSJeremy L Thompson      echo "Missing \"list\" in --proc-node \"list\""; $exit_cmd 1; }
1742f4d9adbSJeremy L Thompson      num_proc_node="$1"
1752f4d9adbSJeremy L Thompson      ;;
1762f4d9adbSJeremy L Thompson   -d|--dry-run)
1772f4d9adbSJeremy L Thompson      dry_run="quoted_echo"
1782f4d9adbSJeremy L Thompson      ;;
1792f4d9adbSJeremy L Thompson   -s|--shell)
1802f4d9adbSJeremy L Thompson      start_shell="yes"
1812f4d9adbSJeremy L Thompson      ;;
1822f4d9adbSJeremy L Thompson   -v|--verbose)
1832f4d9adbSJeremy L Thompson      verbose="yes"
1842f4d9adbSJeremy L Thompson      ;;
1852f4d9adbSJeremy L Thompson   -x)
1862f4d9adbSJeremy L Thompson      set -x
1872f4d9adbSJeremy L Thompson      ;;
1882f4d9adbSJeremy L Thompson   *=*)
1892f4d9adbSJeremy L Thompson      eval "$1" || { echo "Error evaluating argument: $1"; $exit_cmd 1; }
1902f4d9adbSJeremy L Thompson      ;;
1912f4d9adbSJeremy L Thompson   *)
1922f4d9adbSJeremy L Thompson      echo "Unknown option: '$1'"
1932f4d9adbSJeremy L Thompson      $exit_cmd 1
1942f4d9adbSJeremy L Thompson      ;;
1952f4d9adbSJeremy L Thompsonesac
1962f4d9adbSJeremy L Thompson
1972f4d9adbSJeremy L Thompsonshift
1982f4d9adbSJeremy L Thompsondone # while ...
1992f4d9adbSJeremy L Thompson# Done processing command line parameters
2002f4d9adbSJeremy L Thompson
2012f4d9adbSJeremy L Thompsonnum_proc_list=(${num_proc_run:-4})
2022f4d9adbSJeremy L Thompsonnum_proc_list_size=${#num_proc_list[@]}
2032f4d9adbSJeremy L Thompsonnum_proc_node_list=(${num_proc_node:-4})
2042f4d9adbSJeremy L Thompsonnum_proc_node_list_size=${#num_proc_node_list[@]}
2052f4d9adbSJeremy L Thompson(( num_proc_list_size != num_proc_node_list_size )) && {
2062f4d9adbSJeremy L Thompson   echo "
2072f4d9adbSJeremy L ThompsonThe size of the number-of-processors list (option --num-proc) must be the same
2082f4d9adbSJeremy L Thompsonas the size of the number-of-processors-per-node list (option --proc-node)."
2092f4d9adbSJeremy L Thompson   echo
2102f4d9adbSJeremy L Thompson   $exit_cmd 1
2112f4d9adbSJeremy L Thompson}
2122f4d9adbSJeremy L Thompson
2130c59ef15SJeremy L Thompson### Loop over BPs
2140c59ef15SJeremy L Thompson
2150c59ef15SJeremy L Thompsonfor bp in $bp_list; do
2162f4d9adbSJeremy L Thompson
2172f4d9adbSJeremy L Thompson### Loop over backends
2182f4d9adbSJeremy L Thompson
2192f4d9adbSJeremy L Thompsonfor backend in $backend_list; do
2202f4d9adbSJeremy L Thompson(  ## Run each backend in its own environment
2212f4d9adbSJeremy L Thompson
2222f4d9adbSJeremy L Thompson### Setup output
2232f4d9adbSJeremy L Thompson### Test name
2242f4d9adbSJeremy L Thompsoncd "$cur_dir"
2252f4d9adbSJeremy L Thompsonabspath test_dir "$(dirname "$test_file")" || $exit_cmd 1
2262f4d9adbSJeremy L Thompsontest_basename="$(basename "$test_file")"
2272f4d9adbSJeremy L Thompsontest_file="${test_dir}/${test_basename}"
2282f4d9adbSJeremy L Thompson### Backend name
2292f4d9adbSJeremy L Thompsonshort_backend=${backend//[\/]}
2302f4d9adbSJeremy L Thompson### Output file
2310c59ef15SJeremy L Thompsonoutput_file="${test_file%%.*}-$bp-$short_backend-output.txt"
2322f4d9adbSJeremy L Thompsonrm -rf output_file
2332f4d9adbSJeremy L Thompson
2342f4d9adbSJeremy L Thompson### Setup the environment based on $backend
2352f4d9adbSJeremy L Thompson
2362f4d9adbSJeremy L Thompsonecho
2372f4d9adbSJeremy L Thompsonecho "Using backend $backend ..." | tee $output_file
2382f4d9adbSJeremy L Thompson
2392f4d9adbSJeremy L Thompson### Run the tests (building and running $test_file)
2402f4d9adbSJeremy L Thompson
2412f4d9adbSJeremy L Thompson[ -n "$run" ] && {
2422f4d9adbSJeremy L Thompson
2432f4d9adbSJeremy L Thompson[[ "$verbose" = "yes" ]] && {
2442f4d9adbSJeremy L Thompson   echo "Test problem file, $test_basename:" | tee -a $output_file
2452f4d9adbSJeremy L Thompson   echo "------------------------------------------------" | tee -a $output_file
2462f4d9adbSJeremy L Thompson   cat $test_file | tee -a $output_file
2472f4d9adbSJeremy L Thompson   echo "------------------------------------------------" | tee -a $output_file
2482f4d9adbSJeremy L Thompson   echo | tee -a $output_file
2492f4d9adbSJeremy L Thompson}
2502f4d9adbSJeremy L Thompson
2512f4d9adbSJeremy L Thompsontest_exe_dir="$build_root"
2522f4d9adbSJeremy L Thompson
2532f4d9adbSJeremy L Thompsontrap 'printf "\nScript interrupted.\n"; '$exit_cmd' 33' INT
2542f4d9adbSJeremy L Thompson
2552f4d9adbSJeremy L Thompson## Source the test script file.
2562f4d9adbSJeremy L Thompsonecho "Reading test file: $test_file" | tee -a $output_file
2572f4d9adbSJeremy L Thompsonecho | tee -a $output_file
2582f4d9adbSJeremy L Thompsontest_required_examples=""
2592f4d9adbSJeremy L Thompson. "$test_file" || $exit_cmd 1
2602f4d9adbSJeremy L Thompson
2612f4d9adbSJeremy L Thompson## Build files required by the test
2622f4d9adbSJeremy L Thompsonecho "Example(s) required by the test: $test_required_examples" | tee -a $output_file
2632f4d9adbSJeremy L Thompsonbuild_examples $test_required_examples || $exit_cmd 1
2642f4d9adbSJeremy L Thompsonecho | tee -a $output_file
2652f4d9adbSJeremy L Thompson
2662f4d9adbSJeremy L Thompson## Loop over the number-of-processors list.
2672f4d9adbSJeremy L Thompsonfor (( num_proc_idx = 0; num_proc_idx < num_proc_list_size; num_proc_idx++ ))
2682f4d9adbSJeremy L Thompsondo
2692f4d9adbSJeremy L Thompson
2702f4d9adbSJeremy L Thompsonnum_proc_run="${num_proc_list[$num_proc_idx]}"
2712f4d9adbSJeremy L Thompsonnum_proc_node="${num_proc_node_list[$num_proc_idx]}"
2722f4d9adbSJeremy L Thompson
2732f4d9adbSJeremy L Thompsonset_num_nodes || $exit_cmd 1
2742f4d9adbSJeremy L Thompsoncompose_mpi_run_command
2752f4d9adbSJeremy L Thompson
2762f4d9adbSJeremy L Thompsonif [[ "$start_shell" = "yes" ]]; then
2772f4d9adbSJeremy L Thompson   if [[ ! -t 1 ]]; then
2782f4d9adbSJeremy L Thompson      echo "Standard output is not a terminal. Stop." | tee -a $output_file
2792f4d9adbSJeremy L Thompson      $exit_cmd 1
2802f4d9adbSJeremy L Thompson   fi
2812f4d9adbSJeremy L Thompson   echo "Reading shell commands, type 'c' to continue, 'exit' to stop ..." | tee -a $output_file
2822f4d9adbSJeremy L Thompson   echo | tee -a $output_file
2832f4d9adbSJeremy L Thompson   cd "$cur_dir"
2842f4d9adbSJeremy L Thompson   set -o emacs
2852f4d9adbSJeremy L Thompson   PS1='$ '
2862f4d9adbSJeremy L Thompson   [[ -r $HOME/.bashrc ]] && source $HOME/.bashrc
2872f4d9adbSJeremy L Thompson   HISTFILE="$root_dir/.bash_history"
2882f4d9adbSJeremy L Thompson   history -c
2892f4d9adbSJeremy L Thompson   history -r
2902f4d9adbSJeremy L Thompson   # bind '"\\C-i": menu-complete'
2912f4d9adbSJeremy L Thompson   alias c='break'
2922f4d9adbSJeremy L Thompson   while cwd="$PWD/" cwd="${cwd#${root_dir}/}" cwd="${cwd%/}" \
2932f4d9adbSJeremy L Thompson         prompt="[${cyan}benchmarks$none:$blue$cwd$clear]\$ " && \
2942f4d9adbSJeremy L Thompson         read -p "$prompt" -e line; do
2952f4d9adbSJeremy L Thompson      history -s "$line"
2962f4d9adbSJeremy L Thompson      history -w
2972f4d9adbSJeremy L Thompson      shopt -q -s expand_aliases
2982f4d9adbSJeremy L Thompson      eval "$line"
2992f4d9adbSJeremy L Thompson      shopt -q -u expand_aliases
3002f4d9adbSJeremy L Thompson   done
3012f4d9adbSJeremy L Thompson   [[ "${#line}" -eq 0 ]] && { echo; $exit_cmd 0; }
3022f4d9adbSJeremy L Thompson   shopt -q -u expand_aliases
3032f4d9adbSJeremy L Thompson   echo "Continuing ..." | tee -a $output_file
3042f4d9adbSJeremy L Thompsonfi
3052f4d9adbSJeremy L Thompson
3062f4d9adbSJeremy L Thompson# Call the function run_tests defined inside the $test_file
3072f4d9adbSJeremy L Thompsonceed=$backend
3082f4d9adbSJeremy L Thompsonif [ -z "$dry_run" ]; then
3092f4d9adbSJeremy L Thompson   run_tests >> $output_file
3102f4d9adbSJeremy L Thompsonelse
3112f4d9adbSJeremy L Thompson   run_tests
3122f4d9adbSJeremy L Thompsonfi
3132f4d9adbSJeremy L Thompsonecho
3142f4d9adbSJeremy L Thompson
3152f4d9adbSJeremy L Thompsondone ## End of loop over processor numbers
3162f4d9adbSJeremy L Thompson
3172f4d9adbSJeremy L Thompsontrap - INT
3182f4d9adbSJeremy L Thompson
3192f4d9adbSJeremy L Thompson} ## run is on
3202f4d9adbSJeremy L Thompson
3212f4d9adbSJeremy L Thompson$exit_cmd 0
3222f4d9adbSJeremy L Thompson
3232f4d9adbSJeremy L Thompson) || {
3242f4d9adbSJeremy L Thompson   echo "Sub-shell for backend '$backend' returned error code $?. Stop."
3252f4d9adbSJeremy L Thompson   $exit_cmd 1
3262f4d9adbSJeremy L Thompson}
3272f4d9adbSJeremy L Thompsondone ## Loop over $backend_list
3282f4d9adbSJeremy L Thompson
3290c59ef15SJeremy L Thompsondone ## Loop over $bp_list
3300c59ef15SJeremy L Thompson
3312f4d9adbSJeremy L Thompson$exit_cmd 0
3322f4d9adbSJeremy L Thompson
333