#!/usr/bin/env bash set -euo pipefail # cd to the directory where this script lives cd "$(dirname "$0")" echo "Running make..." make # detect MPI launcher if command -v mpirun >/dev/null 2>&1; then MPI_LAUNCHER=mpirun MPI_FLAG="-np" elif command -v mpiexec >/dev/null 2>&1; then MPI_LAUNCHER=mpiexec MPI_FLAG="-n" else echo "Error: neither mpirun nor mpiexec found in PATH." >&2 exit 2 fi # detect number of processes (fallback to 4) if command -v nproc >/dev/null 2>&1; then NP=$(nproc) elif [ -n "${NUMBER_OF_PROCESSORS-}" ]; then NP=$NUMBER_OF_PROCESSORS else NP=4 fi echo "Using $MPI_LAUNCHER $MPI_FLAG $NP" # helper to measure elapsed "real" time (seconds) while also showing program output measure_time() { local label="$1"; shift local -a cmd=("$@") echo "---- Running: $label ----" echo "Command: ${cmd[*]}" local outfile timefile outfile=$(mktemp) timefile=$(mktemp) if command -v /usr/bin/time >/dev/null 2>&1; then # /usr/bin/time prints real time with %e (seconds) into timefile /usr/bin/time -f "%e" -o "$timefile" "${cmd[@]}" 2>&1 | tee "$outfile" elapsed=$(<"$timefile") else # bash builtin time: capture stderr (which receives the timing) and stdout separately TIMEFORMAT='%R' { time "${cmd[@]}" 1> "$outfile"; } 2> "$timefile" elapsed=$(<"$timefile") # also print program output cat "$outfile" fi rm -f "$outfile" "$timefile" # normalize elapsed to a number (strip spaces) echo "${elapsed//[[:space:]]/}" } # ensure executables exist for exe in mpi_hello_world mpi_pi serial_pi; do if [ ! -x "./$exe" ]; then echo "Error: executable ./$exe not found or not executable. Did make build it?" >&2 exit 3 fi done # run mpi_hello_world (show output, don't measure for comparison) echo "==> Executing mpi_hello_world" "$MPI_LAUNCHER" "$MPI_FLAG" "$NP" ./mpi_hello_world # measure mpi_pi mpi_elapsed=$(measure_time "mpi_pi" "$MPI_LAUNCHER" "$MPI_FLAG" "$NP" ./mpi_pi) # measure serial_pi serial_elapsed=$(measure_time "serial_pi" ./serial_pi) # compute comparison # protect against zero if awk "BEGIN{exit($mpi_elapsed <= 0)}"; then echo "Error: measured mpi_pi time is zero or negative." >&2 exit 4 fi speedup=$(awk -v s="$serial_elapsed" -v m="$mpi_elapsed" 'BEGIN{ if(m==0){print "inf"; exit} printf "%.3f", s/m }') diff=$(awk -v s="$serial_elapsed" -v m="$mpi_elapsed" 'BEGIN{printf "%.3f", s-m }') echo echo "Summary:" echo " mpi_pi time (s): $mpi_elapsed" echo " serial_pi time (s): $serial_elapsed" echo " Difference (serial - mpi) (s): $diff" echo " Speedup (serial / mpi): $speedup x" exit 0