Commit 72e2caf1 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: manifest-like tests top - cases.list + run_cases.sh (Andrey's design),...

CLAUDE: manifest-like tests top - cases.list + run_cases.sh (Andrey's design), de-hardwire test defaults

The scene-sequence .list is the human single source of truth (SET header +
body lines selected by uncommenting; commented lines document the setup).
The tests now follow the SAME convention one level up:

- cases.list: SET header (listFile, version - the version deliberately kept
  out of the scene list, mirroring CORRECTION_PARAMETERS.x3dModelVersion vs
  .sourceSequencesList) + case lines selected by uncommenting; commented
  cases stay as documentation. gen lines map synthetic cases to generators.
- run_cases.sh: resolves ${MODEL} through the scene list's SET
  rootDirectory/x3dDirectory + its UNCOMMENTED sequence lines + the version
  (the *-CENTER dir carries the DERIVED center timestamp -> matched as the
  smallest center ts >= the sequence's first-scene ts containing <version>/);
  -x <corr-xml> reads sourceSequencesList/x3dModelVersion directly = the
  same two sources that drive the Java run. No args = all uncommented cases;
  named cases run even when commented; missing synthetic data triggers the
  generator.
- test_proc_consolidate: hardwired absolute case/repo paths -> standard
  --data/--src/--devrt interface (legacy positional kept).
- test_pose_corr_jna: srcdir default de-hardwired (repo-relative 'src').

Verified live: ./run_cases.sh ALL PASS (pose_corr real-scene tol-0 resolved
through the list+version, 4 synthetic cases); named-commented case
avg_td_oob_jna PASS bit-exact via the new interface; gen-on-missing works.
Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
parent 7ecab008
# cases.list - top-level test-case manifest for the per-kernel GPU tests.
# SAME CONVENTION as the scene-sequence .list files (lv_*.list): the header is
# SET lines, the main body SELECTS cases by uncommenting them. Run with:
#
# ./run_cases.sh # every uncommented case below
# ./run_cases.sh pose_corr peak # named cases (even if commented out here)
# ./run_cases.sh -x <file>.corr-xml pose_corr # list+version from the corr-xml
# ./run_cases.sh -v v013-MB2x pose_corr # version override
#
# ${MODEL} in a data template resolves through the SAME two sources that drive
# the Java runs: the scene-sequence list (its SET rootDirectory/x3dDirectory +
# the UNCOMMENTED sequence lines in its body) and the model version - which is
# deliberately NOT in the scene list (mirrors CORRECTION_PARAMETERS.
# x3dModelVersion vs .sourceSequencesList) so the same sequences re-run against
# different settings by changing ONE value here / one corr-xml entry.
# The <center>-CENTER dir name carries the DERIVED center-scene timestamp (not
# the sequence's first scene), so it is resolved by matching: the *-CENTER dir
# with the smallest timestamp >= the active sequence's first-scene timestamp
# that contains <version>/ (--model overrides if ever ambiguous).
# ${REPO} = this repo's root (synthetic cases live in-tree).
#
# 'gen' lines: if a case's data directory is missing and it has a gen line,
# run_cases.sh runs the generator first (synthetic cases only - real-scene
# cases are exported by a Java run, curt.kernel_test dropdown).
#
# By Claude on 07/13/2026, from Andrey's design (manifest-like tests top).
SET listFile /home/elphel/lwir16-proc/LV/lists/lv_0310_26.list
SET version v013
SET srcDir src # NVRTC kernel source, relative to this file
SET devrt /usr/local/cuda-12.8/lib64/libcudadevrt.a
# case <name> <binary> <data template> <extra args>
# --- real-scene cases (data exported by curt.kernel_test on the model below) ---
case pose_corr test_pose_corr_jna ${MODEL}/testdata/pose_corr --tol 0
#case pose_corr_dbg test_pose_corr ${MODEL}/testdata/pose_corr --tol 600 # -G stepping companion: ULP-tier only (see its header)
#case avg_td_oob_jna test_proc_consolidate ${MODEL}/testdata/avg_td_oob --tol 0
# --- synthetic cases (self-contained, generator below) ---
case peak test_peak ${REPO}/testdata/synth4/peak --tol 1e-9
case peak_recenter test_peak ${REPO}/testdata/synth4/peak_recenter --tol 1e-9
case avg_td test_avg_td ${REPO}/testdata/synth4/avg_td --tol 0
case avg_td_oob test_avg_td_oob ${REPO}/testdata/synth4/avg_td_oob --tol 0
#case convert_direct test_convert_direct ${REPO}/testdata/convert_direct_legacy # local blessed goldens (~200MB, make_convert_direct_case.py)
# gen <name(s)> <generator command, run from ${REPO}>
gen peak,peak_recenter python3 src/tests/make_peak_case.py
gen avg_td,avg_td_oob python3 src/tests/make_avg_td_oob_case.py
gen convert_direct python3 src/tests/make_convert_direct_case.py
...@@ -105,7 +105,7 @@ static int compareTasks(const float* got, const float* expected, ...@@ -105,7 +105,7 @@ static int compareTasks(const float* got, const float* expected,
int main(int argc, char** argv){ int main(int argc, char** argv){
std::string data_dir = "testdata/pose_corr"; std::string data_dir = "testdata/pose_corr";
std::string srcdir = "/home/elphel/git/tile_processor_gpu/src"; std::string srcdir = "src"; // cwd = repo root; run_cases.sh passes --src explicitly // By Claude on 07/13/2026
std::string devrt = "/usr/local/cuda-12.8/lib64/libcudadevrt.a"; std::string devrt = "/usr/local/cuda-12.8/lib64/libcudadevrt.a";
float tol = 0.0f; float tol = 0.0f;
float peak_tol = 1e-6f; // Java-double-oracle tier for the peak kernel (header note) // By Claude on 07/13/2026 float peak_tol = 1e-6f; // Java-double-oracle tier for the peak kernel (header note) // By Claude on 07/13/2026
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
// jna/test_proc_consolidate.cu src/tests/tp_test_data.cu \ // jna/test_proc_consolidate.cu src/tests/tp_test_data.cu \
// -o tests_bin/test_proc_consolidate -L jna -ltileproc \ // -o tests_bin/test_proc_consolidate -L jna -ltileproc \
// -Xlinker -rpath -Xlinker $PWD/jna // -Xlinker -rpath -Xlinker $PWD/jna
// Run: tests_bin/test_proc_consolidate [case_dir] // Run: tests_bin/test_proc_consolidate --data <case dir> (or ./run_cases.sh avg_td_oob_jna)
// //
// Created on: Jul 12, 2026 // Created on: Jul 12, 2026
// Author: Claude (Anthropic), for Elphel // Author: Claude (Anthropic), for Elphel
...@@ -35,10 +35,22 @@ extern "C" { ...@@ -35,10 +35,22 @@ extern "C" {
} }
int main(int argc, char** argv){ int main(int argc, char** argv){
const char* dir = (argc>1)? argv[1] : // standard case interface (run_cases.sh resolves --data through cases.list;
"/home/elphel/lwir16-proc/LV/models/models_1773135103-1773135664/1773135476_186641-CENTER/v013/testdata/avg_td_oob"; // src/devrt defaults assume cwd = repo root). Was hardwired absolute paths +
void* m = tp_create_module("/home/elphel/git/tile_processor_gpu/src", // positional dir. By Claude on 07/13/2026, Andrey's manifest-like-tests design.
"/usr/local/cuda-12.8/lib64/libcudadevrt.a"); const char* dir = nullptr;
const char* srcd = "src";
const char* devrt = "/usr/local/cuda-12.8/lib64/libcudadevrt.a";
for (int i = 1; i < argc; i++){
if (!strcmp(argv[i],"--data") && (i+1<argc)) dir = argv[++i];
else if (!strcmp(argv[i],"--src") && (i+1<argc)) srcd = argv[++i];
else if (!strcmp(argv[i],"--devrt") && (i+1<argc)) devrt = argv[++i];
else if (!strcmp(argv[i],"--tol") && (i+1<argc)) ++i; // accepted for run_cases.sh uniformity (test is tol-0 by design)
else if (argv[i][0] != '-' && !dir) dir = argv[i]; // legacy positional
else { fprintf(stderr,"Usage: %s --data <case dir> [--src <kernel src>] [--devrt <libcudadevrt.a>]\n", argv[0]); return 1; }
}
if(!dir){ fprintf(stderr,"%s: no case dir (use --data, or ./run_cases.sh avg_td_oob_jna)\n", argv[0]); return 1; }
void* m = tp_create_module(srcd, devrt);
if(!m){ printf("FAIL module: %s\n", tp_last_error()); return 1; } if(!m){ printf("FAIL module: %s\n", tp_last_error()); return 1; }
TpTestData data(dir); TpTestData data(dir);
int num_sens = data.paramInt("num_sensors", 16); int num_sens = data.paramInt("num_sensors", 16);
......
#!/usr/bin/env bash
# run_cases.sh - resolver/runner for the top-level test-case manifest (cases.list).
# The manifest follows the scene-list convention: header SET lines, main body
# selects cases by uncommenting. ${MODEL} resolves through the SAME two sources
# the Java runs use: the scene-sequence .list file + the model version (kept
# out of the scene list, mirroring CORRECTION_PARAMETERS.x3dModelVersion).
#
# ./run_cases.sh # all uncommented cases
# ./run_cases.sh pose_corr peak # named cases (commented ones too)
# ./run_cases.sh -x <file>.corr-xml ... # listFile+version from the corr-xml
# ./run_cases.sh -l <scene.list> -v v013-MB2x ... # explicit overrides
# ./run_cases.sh --model <dir> ... # pin ${MODEL} directly
# ./run_cases.sh --list # show cases + resolved paths, run nothing
#
# By Claude on 07/13/2026, from Andrey's design.
set -u
cd "$(dirname "$0")" # repo root = where cases.list lives
REPO="$PWD"
CASES="$REPO/cases.list"
list_file=""; version=""; model=""; corr_xml=""; show_only=0
declare -a want=()
while [ $# -gt 0 ]; do
case "$1" in
-x) corr_xml="$2"; shift 2;;
-l) list_file="$2"; shift 2;;
-v) version="$2"; shift 2;;
--model) model="$2"; shift 2;;
--list) show_only=1; shift;;
-h|--help) sed -n '2,15p' "$0"; exit 0;;
*) want+=("$1"); shift;;
esac
done
# ---- header SET values from cases.list (command line wins) ----
get_set() { # $1 = key
sed -n "s/^SET[[:space:]]\+$1[[:space:]]\+\([^#]*\).*/\1/p" "$CASES" | tail -1 | sed 's/[[:space:]]*$//'
}
[ -n "$list_file" ] || list_file="$(get_set listFile)"
[ -n "$version" ] || version="$(get_set version)"
src_dir="$(get_set srcDir)"; src_dir="${src_dir:-src}"
devrt="$(get_set devrt)"
# ---- corr-xml overrides both (the single-source mode) ----
if [ -n "$corr_xml" ]; then
xml_get() { sed -n "s/.*<entry key=\"CORRECTION_PARAMETERS.$1\">\([^<]*\)<.*/\1/p" "$corr_xml" | tail -1; }
v="$(xml_get sourceSequencesList)"; [ -n "$v" ] && list_file="$v"
v="$(xml_get x3dModelVersion)"; [ -n "$v" ] && version="$v"
fi
# ---- resolve ${MODEL} from the scene list + version (unless pinned) ----
# scene list: SET rootDirectory/x3dDirectory in its header; UNCOMMENTED body
# lines select sequences (first field = first-scene timestamp). The *-CENTER
# dir carries the DERIVED center-scene timestamp, so match: smallest center
# timestamp >= the sequence's first-scene timestamp, containing <version>/.
resolve_model() {
[ -f "$list_file" ] || { echo "run_cases.sh: scene list not found: $list_file" >&2; return 1; }
local lget root x3d
lget() { sed -n "s/^SET[[:space:]]\+$1[[:space:]]\+\([^#]*\).*/\1/p" "$list_file" | tail -1 | sed 's/[[:space:]]*$//'; }
root="$(lget rootDirectory)"; root="${root%/}"
x3d="$(lget x3dDirectory)"
case "$x3d" in /*) : ;; *) x3d="$root/$x3d";; esac
local seqs
seqs=$(grep -vE '^[[:space:]]*#' "$list_file" | grep -v '^SET' | awk 'NF {print $1}' | tr -d ',')
[ -n "$seqs" ] || { echo "run_cases.sh: no active (uncommented) sequences in $list_file" >&2; return 1; }
local out=""
local seq best best_ts cdir cts
for seq in $seqs; do
local seq_ts="${seq%%_*}"
best=""; best_ts=""
for cdir in "$x3d"/*-CENTER; do
[ -d "$cdir/$version" ] || continue
cts="$(basename "$cdir")"; cts="${cts%%_*}"
[ "$cts" -ge "$seq_ts" ] 2>/dev/null || continue
if [ -z "$best" ] || [ "$cts" -lt "$best_ts" ]; then best="$cdir"; best_ts="$cts"; fi
done
if [ -z "$best" ]; then
echo "run_cases.sh: no $x3d/*-CENTER/$version for sequence $seq" >&2
else
out="$out $best/$version"
fi
done
echo "$out"
}
models="$model"
if [ -z "$models" ] && grep -qE '^case[[:space:]]' "$CASES"; then
# resolve lazily only if some selected case actually uses ${MODEL} (below)
:
fi
# ---- collect selected cases ----
# case line: case <name> <binary> <data template> <extra args...>
declare -a sel_name=() sel_bin=() sel_data=() sel_args=()
while IFS= read -r line; do
set -- $line
nm="$2"; bin="$3"; data="$4"; shift 4; extra="$*"
if [ ${#want[@]} -gt 0 ]; then
hit=0; for w in "${want[@]}"; do [ "$w" = "$nm" ] && hit=1; done
[ $hit -eq 1 ] || continue
fi
sel_name+=("$nm"); sel_bin+=("$bin"); sel_data+=("$data"); sel_args+=("$extra")
done < <(
if [ ${#want[@]} -gt 0 ]; then
# named cases: match even if commented out (strip a leading '#')
sed -n 's/^#\?[[:space:]]*\(case[[:space:]].*\)/\1/p' "$CASES"
else
grep -E '^case[[:space:]]' "$CASES"
fi | sed 's/[[:space:]]*#.*$//'
)
[ ${#sel_name[@]} -gt 0 ] || { echo "run_cases.sh: no cases selected (see $CASES)"; exit 1; }
# resolve ${MODEL} once, only if needed
if [ -z "$models" ] && printf '%s\n' "${sel_data[@]}" | grep -q '\${MODEL}'; then
models="$(resolve_model)" || exit 1
[ -n "${models// }" ] || { echo "run_cases.sh: model resolution failed" >&2; exit 1; }
echo "resolved MODEL(s):$models (list $(basename "$list_file"), version $version)"
fi
# ---- run ----
fail=0
run_one() { # $1 name, $2 bin, $3 data(resolved), $4 extra args
local gen
if [ ! -d "$3" ]; then
# synthetic case with a generator? (gen <name,name2> <cmd...>)
gen="$(awk -v n="$1" '$1=="gen" { split($2,a,","); for (i in a) if (a[i]==n) { $1=""; $2=""; print; exit } }' "$CASES")"
if [ -n "${gen// }" ]; then
echo "== $1: data missing, generating: $gen"
(cd "$REPO" && eval "$gen") || { echo "== $1: generator FAILED"; fail=1; return; }
fi
fi
[ -d "$3" ] || { echo "== $1: data dir missing: $3 (export it from a Java run?)"; fail=1; return; }
local cmd="tests_bin/$2 --data $3 $4"
case "$2" in *_jna|*proc*) cmd="$cmd --src $REPO/$src_dir --devrt $devrt";; esac
echo "== $1: $cmd"
if [ $show_only -eq 0 ]; then
(cd "$REPO" && eval "$cmd"); local rc=$?
[ $rc -eq 0 ] || fail=1
echo "== $1: exit $rc"
fi
}
for i in "${!sel_name[@]}"; do
data="${sel_data[$i]}"
data="${data//\$\{REPO\}/$REPO}"
if [ "${data#*\$\{MODEL\}}" != "$data" ]; then
for m in $models; do
run_one "${sel_name[$i]}" "${sel_bin[$i]}" "${data//\$\{MODEL\}/$m}" "${sel_args[$i]}"
done
else
run_one "${sel_name[$i]}" "${sel_bin[$i]}" "$data" "${sel_args[$i]}"
fi
done
[ $show_only -eq 1 ] && exit 0
echo "run_cases.sh: $([ $fail -eq 0 ] && echo ALL PASS || echo FAILURES)"
exit $fail
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment