#!/usr/bin/env bash set -e LOGDIR="/tmp/typhoon/manual" HEAD_LOGDIR="../head_reference/logs" TESTS="../tests" # Suite names default to the three curated suites (see CLAUDE.md's # head_reference protocol). Override on the command line to run other # suites, e.g. ./run_tests.sh ecm_ringers ecm_lmr_delta SUITES=("$@") if [ ${#SUITES[@]} -eq 0 ]; then SUITES=(ecm_ringers ecm_confident_quick ecm_hard_quick) fi # sd (fixed depth) is the right choice when judging whether a pruning/ # ordering change makes the tree smaller or larger for the same search # effort; sn (fixed node budget) is the right choice when judging how many # positions solve within a fixed cost. Override via SD/SN env vars -- # this applies to every suite passed on the command line. # # ecm_late.ep_ (see its header comment) is a different shape of suite -- # curated for positions where the *correct* move is only confirmed well # into the search, specifically so avg-solution-time/total-nodecount from # the stats block below can be read as an extensions/search-quality # metric ("does the engine confirm these tactics sooner, in aggregate") # rather than a solve-count gate. It's sn-only (no sd sweep): the # discovery data behind it was measured on an 8-thread box (avg ~13 ply / # ~70M total nodes across all 8 threads) and a fixed *depth* on 1 thread, # with no cutoff-sharing across threads to shrink the tree, can blow up # unpredictably on the sharpest of these positions -- a fixed *node* # budget bounds wall-clock regardless. 15M nodes (~12s/position at this # box's ~1.3Mnps single-thread rate, ~5 min for all 25 positions) is # picked to stay in "quick ad hoc iteration" territory while still being # in the right ballpark of the per-thread node share implied by the # 8-thread discovery data -- not a rigorously derived number, adjust via # SN if it's cutting off too many positions before they confirm. SD="${SD:-10}" SN="${SN:-5000000}" SN_LABEL="${SN_LABEL:-5m}" ECM_LATE_SN=15000000 ECM_LATE_SN_LABEL=15m suite_sn_only() { [ "$1" = "ecm_late" ] } suite_sn() { if [ "$1" = "ecm_late" ]; then echo "$ECM_LATE_SN"; else echo "$SN"; fi } suite_sn_label() { if [ "$1" = "ecm_late" ]; then echo "$ECM_LATE_SN_LABEL"; else echo "$SN_LABEL"; fi } /bin/rm -rf "${LOGDIR}" mkdir -p "${LOGDIR}" echo -n "Launching test suites (${SUITES[*]}) in parallel... " _start_time=$(date +%s) for suite in "${SUITES[@]}"; do suite_sn=$(suite_sn "$suite") if ! suite_sn_only "$suite"; then ./typhoon \ --cpus 1 \ --hash 256m \ --logfile "$LOGDIR/sd${SD}_${suite}.log" \ --batch \ --command "force; book name /nonexistent.book.bin; sd ${SD}; script $TESTS/${suite}.ep_" \ > "$LOGDIR/sd${SD}_${suite}.out" 2>&1 & fi ./typhoon \ --cpus 1 \ --hash 256m \ --logfile "$LOGDIR/sn${suite_sn}_${suite}.log" \ --batch \ --command "force; book name /nonexistent.book.bin; sn ${suite_sn}; script $TESTS/${suite}.ep_" \ > "$LOGDIR/sn${suite_sn}_${suite}.out" 2>&1 & done wait _elapsed=$(( $(date +%s) - _start_time )) echo "DONE! (${_elapsed}s)" echo print_stats_table() { # $1 = head .out file, $2 = candidate .out file # Extracts the "Final statistics" block (correct solutions .. script time) # from each and prints a HEAD/CANDIDATE table with a numeric diff column. local headfile="$1" candfile="$2" awk -F: ' NR==FNR { n++; lbl[n]=$1; val1[n]=$2; next } { m++; val2[m]=$2 } END { printf(" %-22s %-35s %-35s\n", "", "HEAD", "CANDIDATE") for (i = 1; i <= n; i++) { label = lbl[i]; gsub(/^ +| +$/, "", label) v1 = val1[i]; gsub(/^ +| +$/, "", v1) v2 = (i <= m ? val2[i] : ""); gsub(/^ +| +$/, "", v2) if (label == "leftover") { gsub(/^[0-9.]+% alpha, +/, "", v1) gsub(/^[0-9.]+% alpha, +/, "", v2) } n1 = v1 + 0; n2 = v2 + 0 diff = n2 - n1 if (diff == 0) { dstr = "" } else if (diff == int(diff)) { dstr = sprintf(" (%+d)", diff) } else { dstr = sprintf(" (%+.2f)", diff) } printf(" %-22s %-35s %-35s\n", label ":", v1, v2 dstr) } } ' "$headfile" "$candfile" } for suite in "${SUITES[@]}"; do suite_sn=$(suite_sn "$suite") suite_sn_label=$(suite_sn_label "$suite") if ! suite_sn_only "$suite"; then echo "----[ $suite sd=${SD} ]------------------------------------------------------------------" print_stats_table \ <(sed -n '/correct solutions/,/script time/p' "$HEAD_LOGDIR/sd${SD}_${suite}.out") \ <(sed -n '/correct solutions/,/script time/p' "$LOGDIR/sd${SD}_${suite}.out") echo fi echo "----[ $suite sn=${suite_sn} ]------------------------------------------------------------------" print_stats_table \ <(sed -n '/correct solutions/,/script time/p' "$HEAD_LOGDIR/sn${suite_sn_label}_${suite}.out") \ <(sed -n '/correct solutions/,/script time/p' "$LOGDIR/sn${suite_sn}_${suite}.out") echo done echo echo "NOTE: The logfiles for these runs are in /tmp/typhoon/manual and will be" echo " overwritten by the next invocation of this script; save now them if" echo " you want them!"