You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
psblas3/test/computational_routines/common/testlib.sh

173 lines
4.6 KiB
Bash

#!/bin/bash
# Common helpers for computational_routines autotest.sh scripts.
# Color codes
GREEN="\033[0;32m"
RED="\033[0;31m"
BLUE="\033[0;34m"
YELLOW="\033[33m"
RESET="\033[0m"
info() {
echo -e "${BLUE}[INFO]\t $*${RESET}"
}
warn() {
echo -e "${YELLOW}[WARNING] $*${RESET}"
}
err() {
echo -e "${RED}[ERROR]\t$*${RESET}"
}
ensure_dirs() {
for d in "$@"; do
mkdir -p "$d"
done
}
log_header() {
local logfile="$1"
local title="$2"
{
echo "[RUN] ${title}"
echo "[DATE] $(date +"%Y-%m-%d %H:%M:%S")"
} >> "$logfile"
}
run_mpi() {
local np="$1"
local exe="$2"
local label="$3"
info "Starting ${label}"
mpirun -np "$np" "$exe"
}
compare_dirs() {
local dir1="$1"
local dir2="$2"
local logfile="$3"
local eps
local eps_mode
local cmp_mode
local n_gamma
local u_round
local total_files=0
local total_fail=0
local total_diff=0
# EPS_MODE selects how the tolerance value is computed (absolute | gamma_n);
# COMPARE selects how it is applied (absolute | relative). They are
# orthogonal: e.g. gamma_n + relative gives the standard finite-precision
# error bound |fl - exact| <= gamma_n * |value| used for spmm.
eps_mode=${PSBLAS_TEST_EPS_MODE:-absolute}
cmp_mode=${PSBLAS_TEST_COMPARE:-absolute}
eps=${PSBLAS_TEST_TOL:-1e-6}
if [[ "$eps_mode" == "gamma_n" ]]; then
n_gamma=${PSBLAS_TEST_N:-0}
u_round=${PSBLAS_TEST_UNIT_ROUNDOFF:-1.19e-7}
if [[ "$n_gamma" -gt 0 ]]; then
eps=$(awk -v n="$n_gamma" -v u="$u_round" 'BEGIN { g = (n*u)/(1.0 - n*u); printf "%.12g", g }')
fi
fi
if [[ ! -d "$dir1" || ! -d "$dir2" ]]; then
warn "Missing directories for comparison (${dir1}, ${dir2})."
return 0
fi
for file1 in "$dir1"/*; do
if [[ ! -f "$file1" ]]; then
continue
fi
total_files=$((total_files + 1))
local filename
filename=$(basename "$file1")
local file2="$dir2/$filename"
if [[ -f "$file2" ]]; then
local diff_count
if [[ "${filename}" == *.mtx ]]; then
diff_count=$(awk -v f1="$file1" -v f2="$file2" -v eps="$eps" -v mode="$cmp_mode" '
function readvals(fname, vals, line, n, header_seen) {
n = 0
while ((getline line < fname) > 0) {
if (line ~ /^%/) continue
if (line ~ /^[[:space:]]*$/) continue
if (!header_seen) { header_seen = 1; continue }
n++; vals[n] = line + 0
}
close(fname)
return n
}
BEGIN {
n1 = readvals(f1, a)
n2 = readvals(f2, b)
n = (n1 < n2 ? n1 : n2)
diff = 0
for (i = 1; i <= n; i++) {
d = a[i] - b[i]
if (d < 0) d = -d
tol = eps
if (mode == "relative") {
# mixed relative/absolute tolerance: scale eps by the
# magnitude of the operands (floor of 1 keeps it absolute
# near zero). Required for finite-precision results whose
# summation order differs between serial and parallel runs.
m = (a[i] < 0 ? -a[i] : a[i])
p = (b[i] < 0 ? -b[i] : b[i])
scale = (m > p ? m : p)
if (scale < 1) scale = 1
tol = eps * scale
}
if (d > tol) diff++
}
if (n1 != n2) diff += (n1 > n2 ? n1 - n2 : n2 - n1)
print diff
}')
else
diff_count=$(diff -U 0 "$file1" "$file2" | grep -E '^[+-]' | grep -v '^[+-]{3}' | wc -l)
fi
echo "[DIFF] ${file1} vs ${file2}: ${diff_count} differences" >> "$logfile"
total_diff=$((total_diff + diff_count))
if [[ "$diff_count" -gt 0 ]]; then
total_fail=$((total_fail + 1))
fi
else
err "File ${filename} does not exist in ${dir2}"
total_fail=$((total_fail + 1))
fi
done
if [[ "$total_files" -eq 0 ]]; then
warn "No files to compare in ${dir1}."
return 0
fi
if [[ "$total_fail" -eq 0 ]]; then
echo -e "${GREEN}[PASS]\t ${dir1} vs ${dir2}: ${total_files}/${total_files} tests passed${RESET}"
return 0
elif [[ "$total_fail" -eq "$total_files" ]]; then
echo -e "${RED}[FAIL]\t ${dir1} vs ${dir2}: 0/${total_files} tests passed${RESET}"
return 2
else
local passed=$((total_files - total_fail))
echo -e "${YELLOW}[WARN]\t ${dir1} vs ${dir2}: ${passed}/${total_files} tests passed, ${total_fail} failed${RESET}"
return 1
fi
}
get_num_procs() {
local detected
local max
detected=${PSBLAS_TEST_NP:-$(nproc)}
max=${PSBLAS_TEST_MAX_NP:-4}
if [[ "$detected" -gt "$max" ]]; then
detected="$max"
fi
echo "$detected"
}