[Fix] Separate pytorch/jax build and test sub-jobs per phase - #83
Conversation
| candidate = RunLeaf( | ||
| run_id=workflow_run.workflow_run_id, | ||
| run_attempt=workflow_run.run_attempt, | ||
| status=status, | ||
| started_at=min(starts) if starts else existing.started_at, | ||
| completed_at=(max(ends) if status.is_terminal and ends else None), | ||
| variants=build_variants, | ||
| ) | ||
| if not existing.should_replace(candidate): | ||
| return False |
There was a problem hiding this comment.
Based on the test in here, what if, for example, 802 finishes earlier than 801
Quartz/scripts/receive_therock/tests/therock_update_status_json_test.py
Lines 1706 to 1722 in ebce36a
Looks like it will be rejected.
Quartz/scripts/receive_therock/therock_status_document.py
Lines 241 to 263 in 4eca82c
There was a problem hiding this comment.
for rid, py in ((801, "3.10"), (802, "3.12")):
these are independent build variants: one for py 3.10 and one for py 3.12. as such they are always listed and the run id does not matter
| if not variants: | ||
| variants = _variants_from_inputs(workflow_run, axis_key) |
There was a problem hiding this comment.
Please see agent comment regarding build/test partition bypass via input fallback:
The concern is: phase filtering may correctly remove all test jobs while deriving a build, but then this unconditional fallback can create a build variant from workflow inputs anyway. Will this bypass the new build-vs-test partitioning?
There was a problem hiding this comment.
see my wonderful claude reply:
Good catch on the fallback being phase-blind. It is a latent gap, not a live one, so I documented the invariant in-code rather than restructuring the #82 fix.
The fallback (_variants_from_inputs) runs only when the job-sourced derivation returns empty. For a build phase that happens only before any build-cell job exists in the run. At that instant no test sub-job exists either, since tests need builds. So the whole-run status the fallback reads reflects only setup/build-start state, never a test outcome, and it cannot stamp a build cell with a test-influenced status. This holds across all three topologies: the portable pytorch build (started notify inside the build job, so the fallback never fires for build at all) and the jax/pytorch release workflows (started notify in setup_matrix, before build jobs exist). Once the build and test jobs materialize, the job-sourced partition takes over and replaces the cell by key.
I discussed this with Claude to confirm the reachability holds for the release setup-job topology too.
Summary
Quartz doubled pytorch/jax build cells and flipped a green build to
cancelled/failed whenever a nested test job failed (#82). The build leaf was
absorbing the run's nested test sub-jobs as if they were extra build cells. We
now partition a shared run's job list by phase, so the build leaf holds only
build sub-jobs and the test leaf only test sub-jobs. We also finalize the build
leaf early from a test-phase snapshot, so it never stalls
in_progresswaitingfor the run-level completion notify.
Fixes #82
Root cause
pytorch/jax build workflows invoke their test coverage as a reusable
workflow_call, so build and test jobs share one run id and one job list.rockrel wraps each job in an uppercase ancestor segment
(
Release | py 3.13 | JAX 0.11.0 / ...). A test-only cell borrowed thatancestor's looser ref (
0.11.0) while the sibling build cell carried its owntail ref (
rocm-jaxlib-v0.11.0), so the two landed as separate cells --doubling the build leaf -- and the nested test's cancellation flipped the
build's rolled-up status.
What changed
Test | <arch>segment of itsown; a build sub-job never does.
_is_test_subjobencodes this, and_variants_from_jobstakes aphaseargument to keep only the matching half._TEST_ARCH_JOB_REis now case-insensitive (matching_MATRIX_JOB_RE),because it is now the build-vs-test signal, not just arch extraction.
can no longer flip a green build or add a phantom cell.
_refresh_same_run_build_from_test). When atest-phase notify arrives for a shared run, we scan the same job list for the
build sub-jobs and finalize the build leaf, so it does not stall
in_progressuntil the run-level completion notify fires._refresh_same_run_tests_from_buildand_refresh_same_run_build_from_test.Test plan
standalone-test isolation (a standalone test dispatch has its own run id
and must never rewrite the real build run's leaf).
pytest scripts/receive_therock/tests/therock_update_status_json_test.py-> 116 passed.
scripts/receive_therock/tests/-> 429 passed + 16 subtests. The 3failures in
therock_workflow_registry_test.pyare pre-existing andunrelated (they scan real TheRock workflow YAML for
notify_quartzphases).