summaryrefslogtreecommitdiff
path: root/experiments
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-07-27 15:21:21 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-07-27 15:21:21 -0500
commit03eff0389dbb3b18b4836c9588ed8c04541d3f91 (patch)
tree1edf653efd0bce9e00a13f48e60ede908c7d9145 /experiments
parent76a5c8ed16abc7275c874176915a8bbbc247d194 (diff)
experiment: queue complete 81-cell crossover
Diffstat (limited to 'experiments')
-rwxr-xr-xexperiments/handoff_selectors_to_full_crossover.sh233
1 files changed, 233 insertions, 0 deletions
diff --git a/experiments/handoff_selectors_to_full_crossover.sh b/experiments/handoff_selectors_to_full_crossover.sh
new file mode 100755
index 0000000..04d1b5d
--- /dev/null
+++ b/experiments/handoff_selectors_to_full_crossover.sh
@@ -0,0 +1,233 @@
+#!/usr/bin/env bash
+# After both P1 selectors are complete, bind them into frozen R2/T2
+# worktrees, run the full 27+27 cells sequentially, audit every record, and
+# commit the generated evidence on the corresponding run branches.
+set -euo pipefail
+
+if [ "$#" -ne 3 ]; then
+ echo "usage: $0 EXPECTED_P1_COMMIT EXPECTED_R2_BASE EXPECTED_T2_BASE" >&2
+ exit 2
+fi
+
+expected_p1_commit="$1"
+expected_r2_base="$2"
+expected_t2_base="$3"
+resnet_p1_root="/home/yurenh2/sdil-resnet-p1"
+transformer_p1_root="/home/yurenh2/sdil-transformer-p1"
+resnet_r2_root="/home/yurenh2/sdil-resnet-r2"
+transformer_t2_root="/home/yurenh2/sdil-transformer-t2"
+plain_root="/scratch/yurenh2/sdil-crossover/dualprop_vgg16"
+python_bin="/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3"
+gpu5_uuid="GPU-f4aed756-228e-7522-94e7-fb543c02cc74"
+gpu7_uuid="GPU-df3d5933-c3e9-9ea1-d595-9d2a3b68c14b"
+
+require_source() {
+ local root="$1"
+ local expected_commit="$2"
+ test "$(git -C "$root" rev-parse HEAD)" = "$expected_commit"
+ test -z "$(git -C "$root" status --porcelain --untracked-files=no)"
+}
+
+gpu_uuid() {
+ nvidia-smi \
+ --query-gpu=index,uuid \
+ --format=csv,noheader,nounits |
+ awk -F',' -v wanted="$1" '
+ {
+ gsub(/^[ \t]+|[ \t]+$/, "", $1)
+ gsub(/^[ \t]+|[ \t]+$/, "", $2)
+ if ($1 == wanted) print $2
+ }'
+}
+
+gpu_has_compute_process() {
+ nvidia-smi \
+ --query-compute-apps=gpu_uuid \
+ --format=csv,noheader,nounits 2>/dev/null |
+ awk -v wanted="$1" '
+ {
+ gsub(/^[ \t]+|[ \t]+$/, "", $0)
+ if ($0 == wanted) found=1
+ }
+ END { exit(found ? 0 : 1) }'
+}
+
+wait_for_idle_gpus() {
+ while gpu_has_compute_process "$gpu5_uuid" ||
+ gpu_has_compute_process "$gpu7_uuid"; do
+ sleep 60
+ done
+}
+
+manifest_count() {
+ local result_root="$1"
+ find "$result_root" -maxdepth 1 -type f \
+ -name '*.manifest.json' -print 2>/dev/null | wc -l
+}
+
+wait_for_file() {
+ while [ ! -f "$1" ]; do
+ sleep 60
+ done
+}
+
+validate_selector() {
+ local path="$1"
+ local stage="$2"
+ local count="$3"
+ jq -e --arg stage "$stage" --argjson count "$count" '
+ .gate == "pass" and
+ .stage == $stage and
+ .num_expected_records == $count and
+ .num_audited_records == $count and
+ .missing_experiments == [] and
+ (.selected | length) == 9 and
+ .test_policy == "none"
+ ' "$path" >/dev/null
+}
+
+test -x "$python_bin"
+test "$(gpu_uuid 5)" = "$gpu5_uuid"
+test "$(gpu_uuid 7)" = "$gpu7_uuid"
+require_source "$resnet_p1_root" "$expected_p1_commit"
+require_source "$transformer_p1_root" "$expected_p1_commit"
+require_source "$resnet_r2_root" "$expected_r2_base"
+require_source "$transformer_t2_root" "$expected_t2_base"
+
+resnet_p1_selector="$resnet_p1_root/results/resnet_crossover/p1_selector.json"
+transformer_p1_selector="$transformer_p1_root/results/transformer_crossover/p1_selector.json"
+echo "waiting for both audited P1 selectors at $(date --iso-8601=seconds)"
+wait_for_file "$resnet_p1_selector"
+wait_for_file "$transformer_p1_selector"
+validate_selector "$resnet_p1_selector" "resnet_crossover_p1" 19
+validate_selector \
+ "$transformer_p1_selector" "transformer_crossover_p1" 27
+
+resnet_r2_selector="$resnet_r2_root/results/resnet_crossover/p1_selector.json"
+transformer_t2_selector="$transformer_t2_root/results/transformer_crossover/p1_selector.json"
+test ! -e "$resnet_r2_selector"
+test ! -e "$transformer_t2_selector"
+mkdir -p "$(dirname "$resnet_r2_selector")"
+mkdir -p "$(dirname "$transformer_t2_selector")"
+(
+ cd "$resnet_p1_root"
+ "$python_bin" experiments/analyze_resnet_crossover_p1.py \
+ --out "$resnet_r2_selector"
+) >"$resnet_r2_root/results/resnet_crossover/p1_import.log" 2>&1
+(
+ cd "$transformer_p1_root"
+ "$python_bin" experiments/analyze_transformer_crossover_p1.py \
+ --out "$transformer_t2_selector"
+) >"$transformer_t2_root/results/transformer_crossover/p1_import.log" 2>&1
+validate_selector "$resnet_r2_selector" "resnet_crossover_p1" 19
+validate_selector \
+ "$transformer_t2_selector" "transformer_crossover_p1" 27
+git -C "$resnet_r2_root" add -f \
+ results/resnet_crossover/p1_selector.json
+git -C "$resnet_r2_root" commit -m \
+ "experiment: freeze ResNet crossover selector"
+git -C "$transformer_t2_root" add -f \
+ results/transformer_crossover/p1_selector.json
+git -C "$transformer_t2_root" commit -m \
+ "experiment: freeze Transformer crossover selector"
+resnet_r2_commit="$(git -C "$resnet_r2_root" rev-parse HEAD)"
+transformer_t2_commit="$(git -C "$transformer_t2_root" rev-parse HEAD)"
+require_source "$resnet_r2_root" "$resnet_r2_commit"
+require_source "$transformer_t2_root" "$transformer_t2_commit"
+echo "selectors frozen; launching ResNet R2 at $(date --iso-8601=seconds)"
+
+wait_for_idle_gpus
+if tmux has-session -t resnet_r2_gpu5 2>/dev/null ||
+ tmux has-session -t resnet_r2_gpu7 2>/dev/null; then
+ echo "ResNet R2 session already exists; refusing duplicate launch" >&2
+ exit 1
+fi
+tmux new-session -d -s resnet_r2_gpu5 \
+ "cd '$resnet_r2_root' && env CUDA_VISIBLE_DEVICES=5 '$python_bin' experiments/resnet_crossover_r2.py --num-shards 2 --shard-index 0 > results/resnet_crossover/r2_gpu5.log 2>&1"
+tmux new-session -d -s resnet_r2_gpu7 \
+ "cd '$resnet_r2_root' && env CUDA_VISIBLE_DEVICES=7 '$python_bin' experiments/resnet_crossover_r2.py --num-shards 2 --shard-index 1 > results/resnet_crossover/r2_gpu7.log 2>&1"
+tmux has-session -t resnet_r2_gpu5
+tmux has-session -t resnet_r2_gpu7
+while tmux has-session -t resnet_r2_gpu5 2>/dev/null ||
+ tmux has-session -t resnet_r2_gpu7 2>/dev/null; do
+ sleep 60
+done
+test "$(manifest_count \
+ "$resnet_r2_root/results/resnet_crossover/r2")" -eq 27
+require_source "$resnet_r2_root" "$resnet_r2_commit"
+(
+ cd "$resnet_r2_root"
+ "$python_bin" experiments/analyze_resnet_crossover_r2.py \
+ --out results/resnet_crossover/r2_audit.json
+) >"$resnet_r2_root/results/resnet_crossover/r2_audit.log" 2>&1
+jq -e '
+ .audit_status == "passed" and
+ .complete_grid == true and
+ .failure_retaining == true and
+ .num_audited_cells == 27 and
+ .test_policy == "none"
+' "$resnet_r2_root/results/resnet_crossover/r2_audit.json" >/dev/null
+git -C "$resnet_r2_root" add -f results/resnet_crossover
+git -C "$resnet_r2_root" commit -m \
+ "results: record complete ResNet crossover"
+echo "ResNet R2 audited and committed at $(date --iso-8601=seconds)"
+
+wait_for_idle_gpus
+require_source "$transformer_t2_root" "$transformer_t2_commit"
+if tmux has-session -t transformer_t2_gpu5 2>/dev/null ||
+ tmux has-session -t transformer_t2_gpu7 2>/dev/null; then
+ echo "Transformer T2 session already exists; refusing duplicate launch" >&2
+ exit 1
+fi
+tmux new-session -d -s transformer_t2_gpu5 \
+ "cd '$transformer_t2_root' && env CUDA_VISIBLE_DEVICES=5 '$python_bin' experiments/transformer_crossover_t2.py --num-shards 2 --shard-index 0 > results/transformer_crossover/t2_gpu5.log 2>&1"
+tmux new-session -d -s transformer_t2_gpu7 \
+ "cd '$transformer_t2_root' && env CUDA_VISIBLE_DEVICES=7 '$python_bin' experiments/transformer_crossover_t2.py --num-shards 2 --shard-index 1 > results/transformer_crossover/t2_gpu7.log 2>&1"
+tmux has-session -t transformer_t2_gpu5
+tmux has-session -t transformer_t2_gpu7
+while tmux has-session -t transformer_t2_gpu5 2>/dev/null ||
+ tmux has-session -t transformer_t2_gpu7 2>/dev/null; do
+ sleep 60
+done
+test "$(manifest_count \
+ "$transformer_t2_root/results/transformer_crossover/t2")" -eq 27
+require_source "$transformer_t2_root" "$transformer_t2_commit"
+(
+ cd "$transformer_t2_root"
+ "$python_bin" experiments/analyze_transformer_crossover_t2.py \
+ --out results/transformer_crossover/t2_audit.json
+) >"$transformer_t2_root/results/transformer_crossover/t2_audit.log" 2>&1
+jq -e '
+ .audit_status == "passed" and
+ .complete_grid == true and
+ .failure_retaining == true and
+ .num_audited_cells == 27 and
+ .test_policy == "none"
+' "$transformer_t2_root/results/transformer_crossover/t2_audit.json" \
+ >/dev/null
+
+plain_audit="$transformer_t2_root/results/plain_cnn_p2_audit.json"
+(
+ cd "$plain_root"
+ "$python_bin" analyze_p2.py --output "$plain_audit"
+)
+"$python_bin" "$transformer_t2_root/experiments/analyze_crossover_81.py" \
+ --plain "$plain_audit" \
+ --resnet "$resnet_r2_root/results/resnet_crossover/r2_audit.json" \
+ --transformer \
+ "$transformer_t2_root/results/transformer_crossover/t2_audit.json" \
+ --out "$transformer_t2_root/results/crossover_81_audit.json"
+jq -e '
+ .audit_status == "passed" and
+ .complete_grid == true and
+ .failure_retaining == true and
+ .num_audited_cells == 81 and
+ .test_policy == "none"
+' "$transformer_t2_root/results/crossover_81_audit.json" >/dev/null
+git -C "$transformer_t2_root" add -f \
+ results/transformer_crossover \
+ results/plain_cnn_p2_audit.json \
+ results/crossover_81_audit.json
+git -C "$transformer_t2_root" commit -m \
+ "results: record complete 81-cell crossover"
+echo "complete 81-cell crossover audited and committed at $(date --iso-8601=seconds)"