Overview
The Profiling Agent cannot see the compile-time corpus that autolens_profiling
is already producing. agents/conductors/profiling/AGENTS.md still lists "JAX
compilation-time profiling of likelihood functions" under Future modes, and
_profiling.py (353 lines) contains zero occurrences of "compile" — all three
modes read only results/runtime/. Meanwhile scripts/misc/jax_compile/ holds
93 committed probe records that nothing cross-references against the science grid.
This is phase 1 of the compile-axis arc: a read-only coverage answer. It is the
cheapest of the three legs and produces the number that justifies the other two.
Plan
- Add
--axis compile to the existing campaign mode; runtime stays the default
and is untouched.
- Load the compile corpus from
scripts/misc/jax_compile/results/*/*.json with
stdlib json, honouring the never-import-the-workspace rule.
- Resolve each record to a grid cell from its in-record
(dataset_class, model_type, instrument) — not its path, which drops class and instrument.
- Report coverage over cell × transform × hardware tier, with off-grid and
malformed records in their own buckets rather than silently counted or dropped.
- Emit a
probe.py dispatch plan for what is missing, mirroring how the runtime
campaign emits sweep.py lines.
- Add
tests/test_profiling_conductor.py — it does not exist yet; profiling is
currently the only conductor without one.
Detailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoBrain |
main |
clean |
Suggested branch: feature/compile-axis-campaign-coverage
Worktree root: ~/Code/PyAutoLabs-wt/compile-axis-campaign-coverage/
Implementation Steps
-
agents/conductors/profiling/_profiling.py — add load_compile_corpus(ws):
glob scripts/misc/jax_compile/results/*/*.json, each an append-only list of
flat records. Tolerate unreadable/malformed files the way ingest already
does (except (OSError, ValueError): continue).
-
Add TRANSFORMS, the seven axes from probe.py's docstring: jit, grad,
vag, vmap, vmap_vag, laxmap_vag, pyloop_vag.
-
Add campaign_compile(ws, tier). Resolve records to grid cells from
load_grid(ws) (existing, reads sweep.py::CELLS via ast). Bucket into
done / missing / off_grid / malformed:
- off-grid:
knn and delaunay_matern are real Prodigy-census
measurements that are not CELLS entries — they must not read as noise.
- malformed: 4 records currently carry
hardware/dataset_class/
instrument all null; report file + index so they can be fixed
deliberately.
-
Map hardware to tier. Runtime uses TIER_CONFIGS config names
(local_cpu_fp64 …); compile records carry a hardware string
(local_cpu, local_gpu_NVIDIA_A100_80GB_PCIe, …) plus a separate
mixed_precision bool. These are different vocabularies — needs an
explicit mapping, not a reuse of TIER_CONFIGS.
-
Dispatch plan: python jax_compile/probe.py --model-type <m> --transforms <list> for local; the hpc/batch_gpu/submit_* form for --tier a100.
-
main() — add --axis {runtime,compile} defaulting to runtime; dispatch
campaign accordingly. Reject --axis compile for ingest/triage with
exit 5 (usage) so phases 2–3 land it deliberately rather than half-working.
-
emit_human() — a compile branch printing the four buckets and the plan.
-
agents/conductors/profiling/AGENTS.md — document the axis under campaign.
Leave the Future modes entry until phase 3 closes the arc.
-
tests/test_profiling_conductor.py — new. Follow the hermetic pattern in
test_hygiene_conductor.py: PYAUTO_ROOT at a temp dir, drive the real CLI
via subprocess, build a synthetic workspace fixture (a sweep.py carrying
CELLS + a jax_compile/results/ tree) so no real checkout is needed.
Cover: bucket counts, off-grid separation, malformed handling, --json
shape, exit 5 on ingest --axis compile, and a runtime-axis regression guard.
Key Files
agents/conductors/profiling/_profiling.py — all logic
agents/conductors/profiling/AGENTS.md — mode documentation
tests/test_profiling_conductor.py — new
autolens_profiling/scripts/misc/jax_compile/probe.py — read-only reference
for the record schema and transform names
Out of scope
- Any judgement about whether a compile time is good (phase 3).
- Any pin, baseline or dashboard (phase 2).
- Executing
probe.py — the agent reasons and emits a plan, never runs the
workspace (ProfilingDecision contract).
Arc context
Phase 1 of three, re-scoped 2026-08-10 from the 2026-07-14 prompt
draft/feature/profiling/profiling_agent_jax_compile_time_scope.md. The original
"measure compile time so we can speed it up" framing is spent: the speed-up
shipped (persistent compilation cache 117.0s → 2.3s; --xla_gpu_autotune_level=0
17× on the pathological cold probe), so the surviving task is regression
surveillance — both wins are settings, and nothing watches for them reverting.
- Phase 2 —
compile_warm_baseline_dashboard.md (autolens_profiling + PyAutoBrain)
- Phase 3 —
compile_axis_triage_drift.md (PyAutoBrain)
Original Prompt
Click to expand starting prompt
Profiling Agent phase 1 — campaign --axis compile: what compile coverage do we actually have?
Type: feature
Target: PyAutoBrain
Repos:
- PyAutoBrain
Difficulty: small
Autonomy: supervised
Priority: high
Status: formalised
Phase 1 of profiling_agent_jax_compile_time_scope.md (read that first — it
carries the re-scope, the evidence and the comparability constraint).
Why this leg first
It is the cheapest of the three, it is pure-read, and it produces the number that
justifies the other two. Right now nobody can say how much of the science grid the
compile corpus covers, because nothing cross-references the two trees.
Measured by hand 2026-08-10 — this is what the mode should compute automatically:
- 93 records, all under
scripts/misc/jax_compile/results/<hardware>/<model_type>.json.
- Distinct
(dataset_class, model_type, instrument) touched: imaging/mge/hst,
imaging/pixelization/hst, imaging/delaunay_matern/hst, imaging/knn/hst,
plus two synthetic multi-band classes (datacube_img, datacube_img_hetero).
- The runtime grid (
scripts/misc/likelihood_runtime/sweep.py::CELLS) is 24
(class, model, instrument) cells across imaging / interferometer /
datacube × hst,jwst,ao / sma,alma,alma_high,jvla.
- So: no interferometer row, no datacube row, no
jwst, no ao — one
instrument out of seven, and delaunay_matern / knn are mesh variants that are
not grid cells at all.
- Hardware:
local_cpu (82 rows), A100 (9, all pixelization/mge × jit/vag),
RTX 2060 (2). Plus 4 malformed rows with hardware/dataset_class/
instrument all null.
Scope
Add --axis compile to the existing campaign mode in
agents/conductors/profiling/_profiling.py. The runtime axis stays the default and
is untouched.
- Read the compile corpus. Load
scripts/misc/jax_compile/results/*/*.json
(append-only lists of flat records). Stdlib json only — the same
never-import-the-workspace rule the runtime path already follows via ast.
- Resolve each record to a grid cell using its in-record
(dataset_class, model_type, instrument), not its file path — the results tree
is filed by <hardware>/<model_type> and drops class/instrument from the path.
- Report coverage over cell × transform × hardware-tier. The transform axis is
probe.py's seven: jit, grad, vag, vmap, vmap_vag, laxmap_vag,
pyloop_vag. Cells not in CELLS are reported in their own off-grid bucket
rather than silently counted or silently dropped — knn and delaunay_matern
are real measurements from the Prodigy census and must not read as noise.
- Report malformed records (missing
hardware / dataset_class /
instrument) as their own bucket with file + index, so they can be fixed or
deleted deliberately.
- Emit a dispatch plan of concrete
probe.py invocations for what is missing,
mirroring how the runtime campaign emits sweep.py lines:
python jax_compile/probe.py --model-type <m> --transforms <list> for local,
and the hpc/batch_gpu/submit_* form for --tier a100.
Explicitly not in scope
- Any judgement about whether a compile time is good — that is phase 3.
- Any pin, baseline or dashboard — that is phase 2.
- Running
probe.py. The agent reasons and emits a plan; it never executes the
workspace (ProfilingDecision contract).
Acceptance
pyauto-brain profiling campaign --axis compile and
... --axis compile --tier a100 both run against a real autolens_profiling
checkout and report done / missing / off-grid / malformed counts.
- The reported on-grid coverage matches the hand count above (3–4 cells of 24,
hst only) on the corpus as it stands.
--json emits the same structure, consistent with the existing modes.
- The runtime axis output is byte-identical to before the change (regression test).
- No file in
autolens_profiling is written or executed by the agent.
Overview
The Profiling Agent cannot see the compile-time corpus that
autolens_profilingis already producing.
agents/conductors/profiling/AGENTS.mdstill lists "JAXcompilation-time profiling of likelihood functions" under Future modes, and
_profiling.py(353 lines) contains zero occurrences of "compile" — all threemodes read only
results/runtime/. Meanwhilescripts/misc/jax_compile/holds93 committed probe records that nothing cross-references against the science grid.
This is phase 1 of the compile-axis arc: a read-only coverage answer. It is the
cheapest of the three legs and produces the number that justifies the other two.
Plan
--axis compileto the existingcampaignmode; runtime stays the defaultand is untouched.
scripts/misc/jax_compile/results/*/*.jsonwithstdlib
json, honouring the never-import-the-workspace rule.(dataset_class, model_type, instrument)— not its path, which drops class and instrument.malformed records in their own buckets rather than silently counted or dropped.
probe.pydispatch plan for what is missing, mirroring how the runtimecampaign emits
sweep.pylines.tests/test_profiling_conductor.py— it does not exist yet; profiling iscurrently the only conductor without one.
Detailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
Suggested branch:
feature/compile-axis-campaign-coverageWorktree root:
~/Code/PyAutoLabs-wt/compile-axis-campaign-coverage/Implementation Steps
agents/conductors/profiling/_profiling.py— addload_compile_corpus(ws):glob
scripts/misc/jax_compile/results/*/*.json, each an append-only list offlat records. Tolerate unreadable/malformed files the way
ingestalreadydoes (
except (OSError, ValueError): continue).Add
TRANSFORMS, the seven axes fromprobe.py's docstring:jit,grad,vag,vmap,vmap_vag,laxmap_vag,pyloop_vag.Add
campaign_compile(ws, tier). Resolve records to grid cells fromload_grid(ws)(existing, readssweep.py::CELLSviaast). Bucket intodone/missing/off_grid/malformed:knnanddelaunay_maternare real Prodigy-censusmeasurements that are not
CELLSentries — they must not read as noise.hardware/dataset_class/instrumentallnull; report file + index so they can be fixeddeliberately.
Map hardware to tier. Runtime uses
TIER_CONFIGSconfig names(
local_cpu_fp64…); compile records carry ahardwarestring(
local_cpu,local_gpu_NVIDIA_A100_80GB_PCIe, …) plus a separatemixed_precisionbool. These are different vocabularies — needs anexplicit mapping, not a reuse of
TIER_CONFIGS.Dispatch plan:
python jax_compile/probe.py --model-type <m> --transforms <list>forlocal; thehpc/batch_gpu/submit_*form for--tier a100.main()— add--axis {runtime,compile}defaulting toruntime; dispatchcampaignaccordingly. Reject--axis compileforingest/triagewithexit 5 (usage) so phases 2–3 land it deliberately rather than half-working.
emit_human()— a compile branch printing the four buckets and the plan.agents/conductors/profiling/AGENTS.md— document the axis undercampaign.Leave the Future modes entry until phase 3 closes the arc.
tests/test_profiling_conductor.py— new. Follow the hermetic pattern intest_hygiene_conductor.py:PYAUTO_ROOTat a temp dir, drive the real CLIvia
subprocess, build a synthetic workspace fixture (asweep.pycarryingCELLS+ ajax_compile/results/tree) so no real checkout is needed.Cover: bucket counts, off-grid separation, malformed handling,
--jsonshape, exit 5 on
ingest --axis compile, and a runtime-axis regression guard.Key Files
agents/conductors/profiling/_profiling.py— all logicagents/conductors/profiling/AGENTS.md— mode documentationtests/test_profiling_conductor.py— newautolens_profiling/scripts/misc/jax_compile/probe.py— read-only referencefor the record schema and transform names
Out of scope
probe.py— the agent reasons and emits a plan, never runs theworkspace (
ProfilingDecisioncontract).Arc context
Phase 1 of three, re-scoped 2026-08-10 from the 2026-07-14 prompt
draft/feature/profiling/profiling_agent_jax_compile_time_scope.md. The original"measure compile time so we can speed it up" framing is spent: the speed-up
shipped (persistent compilation cache 117.0s → 2.3s;
--xla_gpu_autotune_level=017× on the pathological cold probe), so the surviving task is regression
surveillance — both wins are settings, and nothing watches for them reverting.
compile_warm_baseline_dashboard.md(autolens_profiling + PyAutoBrain)compile_axis_triage_drift.md(PyAutoBrain)Original Prompt
Click to expand starting prompt
Profiling Agent phase 1 —
campaign --axis compile: what compile coverage do we actually have?Type: feature
Target: PyAutoBrain
Repos:
Difficulty: small
Autonomy: supervised
Priority: high
Status: formalised
Phase 1 of
profiling_agent_jax_compile_time_scope.md(read that first — itcarries the re-scope, the evidence and the comparability constraint).
Why this leg first
It is the cheapest of the three, it is pure-read, and it produces the number that
justifies the other two. Right now nobody can say how much of the science grid the
compile corpus covers, because nothing cross-references the two trees.
Measured by hand 2026-08-10 — this is what the mode should compute automatically:
scripts/misc/jax_compile/results/<hardware>/<model_type>.json.(dataset_class, model_type, instrument)touched:imaging/mge/hst,imaging/pixelization/hst,imaging/delaunay_matern/hst,imaging/knn/hst,plus two synthetic multi-band classes (
datacube_img,datacube_img_hetero).scripts/misc/likelihood_runtime/sweep.py::CELLS) is 24(class, model, instrument)cells acrossimaging/interferometer/datacube×hst,jwst,ao/sma,alma,alma_high,jvla.jwst, noao— oneinstrument out of seven, and
delaunay_matern/knnare mesh variants that arenot grid cells at all.
local_cpu(82 rows), A100 (9, allpixelization/mge×jit/vag),RTX 2060 (2). Plus 4 malformed rows with
hardware/dataset_class/instrumentallnull.Scope
Add
--axis compileto the existingcampaignmode inagents/conductors/profiling/_profiling.py. The runtime axis stays the default andis untouched.
scripts/misc/jax_compile/results/*/*.json(append-only lists of flat records). Stdlib
jsononly — the samenever-import-the-workspace rule the runtime path already follows via
ast.(dataset_class, model_type, instrument), not its file path — the results treeis filed by
<hardware>/<model_type>and drops class/instrument from the path.probe.py's seven:jit,grad,vag,vmap,vmap_vag,laxmap_vag,pyloop_vag. Cells not inCELLSare reported in their own off-grid bucketrather than silently counted or silently dropped —
knnanddelaunay_maternare real measurements from the Prodigy census and must not read as noise.
hardware/dataset_class/instrument) as their own bucket with file + index, so they can be fixed ordeleted deliberately.
probe.pyinvocations for what is missing,mirroring how the runtime campaign emits
sweep.pylines:python jax_compile/probe.py --model-type <m> --transforms <list>for local,and the
hpc/batch_gpu/submit_*form for--tier a100.Explicitly not in scope
probe.py. The agent reasons and emits a plan; it never executes theworkspace (
ProfilingDecisioncontract).Acceptance
pyauto-brain profiling campaign --axis compileand... --axis compile --tier a100both run against a realautolens_profilingcheckout and report done / missing / off-grid / malformed counts.
hstonly) on the corpus as it stands.--jsonemits the same structure, consistent with the existing modes.autolens_profilingis written or executed by the agent.