From df3249925bfb696ed7192b78015420cc9f952d48 Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Mon, 25 May 2026 22:19:43 +0800 Subject: [PATCH] B3 analyze: prefer per-policy engine_state over slicing shared dir The hot-sweep variant of B3 writes one shared engine_state across all policies; the isolated variant writes per-policy. Previously slice_engine_state.py was called unconditionally and would overwrite an isolated policy's real data with an empty slice (the isolated policy's run-window doesn't overlap with the shared dir's contents). Now we check the policy directory's engine_state for any non-empty engine_*.jsonl first; if present, use it directly; else slice from the shared one as before. Co-Authored-By: Claude Opus 4.7 --- scripts/b3_analyze.sh | 47 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/scripts/b3_analyze.sh b/scripts/b3_analyze.sh index b9a199f..ed823f9 100755 --- a/scripts/b3_analyze.sh +++ b/scripts/b3_analyze.sh @@ -15,21 +15,38 @@ SWEEP_DIR="${1:?usage: $0 }" WORKER_MAP="http://127.0.0.1:8000=engine_0,http://127.0.0.1:8001=engine_1,http://127.0.0.1:8002=engine_2,http://127.0.0.1:8003=engine_3,http://127.0.0.1:8004=engine_4,http://127.0.0.1:8005=engine_5,http://127.0.0.1:8006=engine_6,http://127.0.0.1:8007=engine_7" +_has_engine_data() { + # Return 0 (true) if $1/*.jsonl contains any non-empty file. + local dir="$1" + [ -d "$dir" ] || return 1 + local f + for f in "$dir"/engine_*.jsonl; do + if [ -s "$f" ]; then return 0; fi + done + return 1 +} + for policy_dir in "$SWEEP_DIR"/*/; do policy=$(basename "$policy_dir") case "$policy" in - engine_state|logs|capped) ;; + engine_state|logs) continue ;; esac if [ ! -f "$policy_dir/run_window.json" ]; then continue fi echo "=== $policy ===" - PYTHONPATH="$ROOT" "$VENV/python" \ - "$ROOT/scripts/slice_engine_state.py" \ - --input-dir "$SWEEP_DIR/engine_state" \ - --output-dir "$policy_dir/engine_state" \ - --window "$policy_dir/run_window.json" + # Isolated policies write engine_state into their own dir; hot-sweep + # policies share the sweep-root engine_state and need slicing. + if _has_engine_data "$policy_dir/engine_state"; then + echo " using policy-local engine_state ($(du -sh "$policy_dir/engine_state" | cut -f1))" + else + PYTHONPATH="$ROOT" "$VENV/python" \ + "$ROOT/scripts/slice_engine_state.py" \ + --input-dir "$SWEEP_DIR/engine_state" \ + --output-dir "$policy_dir/engine_state" \ + --window "$policy_dir/run_window.json" + fi PYTHONPATH="$ROOT" "$VENV/python" \ "$ROOT/analysis/characterization/joined_analysis.py" \ @@ -41,24 +58,6 @@ for policy_dir in "$SWEEP_DIR"/*/; do --out-dir "$policy_dir/joined" done -# Also handle capped/ which is nested -if [ -f "$SWEEP_DIR/capped/run_window.json" ]; then - echo "=== capped ===" - PYTHONPATH="$ROOT" "$VENV/python" \ - "$ROOT/scripts/slice_engine_state.py" \ - --input-dir "$SWEEP_DIR/engine_state" \ - --output-dir "$SWEEP_DIR/capped/engine_state" \ - --window "$SWEEP_DIR/capped/run_window.json" - PYTHONPATH="$ROOT" "$VENV/python" \ - "$ROOT/analysis/characterization/joined_analysis.py" \ - --metrics "$SWEEP_DIR/capped/metrics.jsonl" \ - --breakdown "$SWEEP_DIR/capped/breakdown.json" \ - --worker-state "$SWEEP_DIR/capped/worker_state.json" \ - --engine-state-dir "$SWEEP_DIR/capped/engine_state" \ - --worker-map "$WORKER_MAP" \ - --out-dir "$SWEEP_DIR/capped/joined" -fi - # Aggregate per-policy summary "$VENV/python" - <