Skip to content

Cross-thread backward (#78) - #79

Merged
b-re-w merged 3 commits into
developfrom
feat/xthread-backward
Oct 16, 2026
Merged

b-re-w merged 3 commits into
developfrom
feat/xthread-backward

Conversation

@b-re-w

@b-re-w b-re-w commented Oct 5, 2026

Copy link
Copy Markdown
Member

Closes #78. Based on #77 (feat/thread-state), so merge #77 first.

Defect fixed

  • Forward on one thread then .backward() on another now gives upstream's gradient. Before, it raised the misnamed "backward through the graph a second time".
  • Each thread still records only into its own tape. A backward that does not find its output in its own tape looks in the other threads' tapes via a process-wide registry (try_lock, never blocking).

Test added

  • tests/api/test_threadstate.py +3:
    • two cross-thread cases: red on the old shim (the misnamed error), green now;
    • two threads training at once: green on both. It guards the design but has not been nullified.

Gate (worktree, local)

  • 123/123 suites, ok=2016 (+3 over Per-thread grad mode and device-mode stack (#76, part 1) #77's 2014, minus 1 CoreML).
  • Suites exiting non-zero:
    • the two build.py self-test suites that need .caches/;
    • test_anedecode, where MLComputePlan returned "internal failure". Rerun alone twice: 10 ok both times. This is the CoreML drift recorded in AGENTS.md §13.3.
  • cargo test: 46/46.

Not done

…#78)

Forward on one thread then .backward() on another raised 'Trying to backward
through the graph a second time': the eager tape was thread_local, so the
backward thread found none. Each thread still records into its own tape, now
an Arc<Mutex> also listed in a process-wide TAPES table; _eager_backward asks
its own tape first and otherwise takes the tape (try_lock, never blocking
under the GIL) that holds the output. Independent trainers never touch each
other's tapes. Door path unchanged; recording pays one uncontended lock per
op (not measured).

test_threadstate: two cross-thread tests red on the old shim with the
misnamed error, green now; a concurrent-trainers guard green on both.
@b-re-w

b-re-w commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

Recording-path cost, A/B on the macOS host, 3 interleaved rounds:

  • Workload: a loop of 50 y = y*1.0001 + 0.0 (100 recorded ops) followed by .backward(); per op, best of 7×50 steps.
  • Per-thread grad mode and device-mode stack (#76, part 1) #77 build: 3419 / 3427 / 3480 ns/op.
  • This PR: 3375 / 3327 / 3339 ns/op.
  • No regression visible; the difference is within noise.
  • Caveat: load average was 2.3, not an idle machine (AGENTS.md §16), so read this as 'no visible cost', not as a measurement. Script: .scratch/rec_bench.py (not committed).

@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Gate on CI (issue #24)

Full gate: 126 suites = 118 run on at least one CI runner + 8 local-only. The local gate (tests/run.sh on the Mac) is still the only run that covers all 126.

runner exit ran not run here PASS PARTIAL UNVERIFIED (all skipped) FAIL missing/empty ledger
linux 0 118 8 86 30 2 0 0 suites=126/126 ok=1766 FAIL=0 SKIP=270 (printed and re-read
macos 0 118 8 104 12 2 0 0 suites=126/126 ok=1865 FAIL=0 SKIP=171 (printed and re-read
  • linux CI PLAN: runner=linux ran=118/126 not-run=8 (UNVERIFIED on this runner, local-only here): devices/coreml/test_ane_subgraph_components.py, devices/coreml/test_anedecode.py, devices/coreml/test_anesubgraph.py, devices/coreml/test_anetracer.py, devices/coreml/test_coremlops.py, gate/test_toolguard_run_preflight.py, release/test_toolguard_wheel_staging.py, release/test_wheelmatrix.py
  • linux VULKAN COVERAGE: UNVERIFIED -- no Vulkan test executed in this run. A green gate here says nothing about any Vulkan kernel.
  • linux DOCWATCH: PASS -- 1508/1508 evaluated marker(s) hold, 30 skipped
  • macos CI PLAN: runner=macos ran=118/126 not-run=8 (UNVERIFIED on this runner, local-only here): devices/coreml/test_ane_subgraph_components.py, devices/coreml/test_anedecode.py, devices/coreml/test_anesubgraph.py, devices/coreml/test_anetracer.py, devices/coreml/test_coremlops.py, gate/test_toolguard_run_preflight.py, release/test_toolguard_wheel_staging.py, release/test_wheelmatrix.py
  • macos VULKAN COVERAGE: UNVERIFIED -- no Vulkan test executed in this run. A green gate here says nothing about any Vulkan kernel.
  • macos DOCWATCH: PASS -- 1508/1508 evaluated marker(s) hold, 30 skipped

Local-only: verified by no CI runner (8)

  • devices/coreml/test_ane_subgraph_components.py -- imports coremltools at module scope, so without it the suite dies at import, and what it measures is subgraph placement on the Apple Neural Engine, which no hosted runner has. It also has no _skip runner of its own.
  • devices/coreml/test_anedecode.py -- needs CoreML's MLComputePlan answering for the Apple Neural Engine (AGENTS.md §13.3), which no hosted runner has; and its fixture reports a missing coremltools with a hand-rolled print followed by ok, so on a runner it would print ok having run nothing. Local-only until its skips go through _skip, and even then it would only skip.
  • devices/coreml/test_anesubgraph.py -- needs CoreML's MLComputePlan answering for the Apple Neural Engine (AGENTS.md §13.3), which no hosted runner has; and its fixture reports a missing coremltools with a hand-rolled print followed by ok, so on a runner it would print ok having run nothing. Local-only until its skips go through _skip, and even then it would only skip.
  • devices/coreml/test_anetracer.py -- needs CoreML's MLComputePlan answering for the Apple Neural Engine (AGENTS.md §13.3), which no hosted runner has; and its fixture reports a missing coremltools with a hand-rolled print followed by ok, so on a runner it would print ok having run nothing. Local-only until its skips go through _skip, and even then it would only skip.
  • devices/coreml/test_coremlops.py -- needs CoreML's MLComputePlan answering for the Apple Neural Engine (AGENTS.md §13.3), which no hosted runner has; and its fixture reports a missing coremltools with a hand-rolled print followed by ok, so on a runner it would print ok having run nothing. Local-only until its skips go through _skip, and even then it would only skip.
  • gate/test_toolguard_run_preflight.py -- needs the release machine's toolchain, which a hosted runner does not have: the pinned interpreter at .caches/spike-venv (transformers 5.15.1, AGENTS.md §15.2), the rust cross targets and the target CPython distributions under tools/wheel. Measured on run 37078300696 (macos): 3 of 3 tests FAIL with known-good interpreter missing: .../.caches/spike-venv/bin/python.
  • release/test_toolguard_wheel_staging.py -- needs the release machine's toolchain, which a hosted runner does not have: the pinned interpreter at .caches/spike-venv (transformers 5.15.1, AGENTS.md §15.2), the rust cross targets and the target CPython distributions under tools/wheel. Measured on run 37078300696 (macos): its one test FAILs with FileNotFoundError on the same interpreter.
  • release/test_wheelmatrix.py -- needs the release machine's toolchain, which a hosted runner does not have: the pinned interpreter at .caches/spike-venv (transformers 5.15.1, AGENTS.md §15.2), the rust cross targets and the target CPython distributions under tools/wheel. Measured on run 37078300696 (macos): 20 of 22 ok; test_every_target_names_a_rust_target_that_is_installed needs the nine cross targets the release machine has, and test_build_pys_own_self_test_passes asserts LINUX SELF-TEST: PASS, which build.py prints only where the target CPython distribution exists (it skips loudly otherwise). The 20 lose CI coverage until those two take the runner's toolchain into account; follow-up.

Suites that verified nothing, or failed, on a runner

suite runner verdict ok FAIL SKIP
api/test_freethreaded.py linux UNVERIFIED 0 0 5
devices/coreml/test_anepath.py linux UNVERIFIED 0 0 6
api/test_freethreaded.py macos UNVERIFIED 0 0 5
devices/coreml/test_anepath.py macos UNVERIFIED 0 0 6
Every suite, every runner
suite linux macos
_support/test_shim.py PARTIAL (462 ok / 0 FAIL / 18 SKIP) PARTIAL (472 ok / 0 FAIL / 8 SKIP)
api/test_freethreaded.py UNVERIFIED (0 ok / 0 FAIL / 5 SKIP) UNVERIFIED (0 ok / 0 FAIL / 5 SKIP)
api/test_import.py PASS (3 ok / 0 FAIL / 0 SKIP) PASS (3 ok / 0 FAIL / 0 SKIP)
api/test_threadstate.py PASS (7 ok / 0 FAIL / 0 SKIP) PASS (7 ok / 0 FAIL / 0 SKIP)
api/test_tnnamespace.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
api/test_tntransformers.py PASS (14 ok / 0 FAIL / 0 SKIP) PASS (14 ok / 0 FAIL / 0 SKIP)
bindings/test_aliasinc.py PASS (8 ok / 0 FAIL / 0 SKIP) PASS (8 ok / 0 FAIL / 0 SKIP)
bindings/test_argform.py PASS (13 ok / 0 FAIL / 0 SKIP) PASS (13 ok / 0 FAIL / 0 SKIP)
bindings/test_bfallback.py PASS (9 ok / 0 FAIL / 0 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
bindings/test_bind2.py PASS (6 ok / 0 FAIL / 0 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
bindings/test_bind3.py PASS (17 ok / 0 FAIL / 0 SKIP) PASS (17 ok / 0 FAIL / 0 SKIP)
bindings/test_bind4.py PASS (19 ok / 0 FAIL / 0 SKIP) PASS (19 ok / 0 FAIL / 0 SKIP)
bindings/test_bind5.py PASS (27 ok / 0 FAIL / 0 SKIP) PASS (27 ok / 0 FAIL / 0 SKIP)
bindings/test_bindings.py PASS (14 ok / 0 FAIL / 0 SKIP) PASS (14 ok / 0 FAIL / 0 SKIP)
bindings/test_bkeyset.py PASS (9 ok / 0 FAIL / 0 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
bindings/test_convbackend.py PASS (3 ok / 0 FAIL / 0 SKIP) PASS (3 ok / 0 FAIL / 0 SKIP)
bindings/test_dispatch.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
bindings/test_metakey.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
bindings/test_methodspell.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
bindings/test_setitem.py PASS (11 ok / 0 FAIL / 0 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
devices/coreml/test_ane_subgraph_components.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_anedecode.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_anepath.py UNVERIFIED (0 ok / 0 FAIL / 6 SKIP) UNVERIFIED (0 ok / 0 FAIL / 6 SKIP)
devices/coreml/test_anesubgraph.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_anetracer.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_bf16ane.py PARTIAL (1 ok / 0 FAIL / 20 SKIP) PARTIAL (1 ok / 0 FAIL / 20 SKIP)
devices/coreml/test_coremlops.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_emptyplan.py PASS (17 ok / 0 FAIL / 0 SKIP) PASS (17 ok / 0 FAIL / 0 SKIP)
devices/coreml/test_npmarshal.py PARTIAL (6 ok / 0 FAIL / 1 SKIP) PARTIAL (6 ok / 0 FAIL / 1 SKIP)
devices/coreml/test_npu2.py PARTIAL (3 ok / 0 FAIL / 12 SKIP) PARTIAL (3 ok / 0 FAIL / 12 SKIP)
devices/cuda/test_cuda.py PASS (18 ok / 0 FAIL / 0 SKIP) PASS (18 ok / 0 FAIL / 0 SKIP)
devices/mps/test_absmps.py PARTIAL (2 ok / 0 FAIL / 2 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
devices/mps/test_constset.py PARTIAL (4 ok / 0 FAIL / 6 SKIP) PASS (10 ok / 0 FAIL / 0 SKIP)
devices/mps/test_gemmint.py PARTIAL (4 ok / 0 FAIL / 2 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
devices/mps/test_i8mps.py PARTIAL (1 ok / 0 FAIL / 4 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
devices/mps/test_intmps.py PARTIAL (3 ok / 0 FAIL / 5 SKIP) PASS (8 ok / 0 FAIL / 0 SKIP)
devices/mps/test_metalcount.py PARTIAL (1 ok / 0 FAIL / 3 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
devices/mps/test_metalplace.py PARTIAL (1 ok / 0 FAIL / 4 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsattn.py PARTIAL (4 ok / 0 FAIL / 6 SKIP) PASS (10 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsconst.py PARTIAL (3 ok / 0 FAIL / 10 SKIP) PASS (13 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsfwd.py PARTIAL (2 ok / 0 FAIL / 7 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsgen.py PARTIAL (2 ok / 0 FAIL / 5 SKIP) PASS (7 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsinplace.py PARTIAL (1 ok / 0 FAIL / 8 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
devices/mps/test_mpsrefuse.py PARTIAL (4 ok / 0 FAIL / 2 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
devices/mps/test_viewdtype.py PARTIAL (5 ok / 0 FAIL / 1 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
devices/npu/test_intelnpu.py PARTIAL (43 ok / 0 FAIL / 7 SKIP) PARTIAL (43 ok / 0 FAIL / 7 SKIP)
devices/npu/test_npublob.py PASS (13 ok / 0 FAIL / 0 SKIP) PASS (13 ok / 0 FAIL / 0 SKIP)
devices/npu/test_npudim.py PASS (8 ok / 0 FAIL / 0 SKIP) PASS (8 ok / 0 FAIL / 0 SKIP)
devices/npu/test_npufuse.py PARTIAL (11 ok / 0 FAIL / 3 SKIP) PARTIAL (11 ok / 0 FAIL / 3 SKIP)
devices/npu/test_npuvendor.py PASS (17 ok / 0 FAIL / 0 SKIP) PASS (17 ok / 0 FAIL / 0 SKIP)
devices/npu/test_npuwire.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
devices/npu/test_ovcache.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
devices/npu/test_ovpar.py PASS (14 ok / 0 FAIL / 0 SKIP) PASS (14 ok / 0 FAIL / 0 SKIP)
devices/qnn/test_qnn.py PARTIAL (15 ok / 0 FAIL / 12 SKIP) PARTIAL (16 ok / 0 FAIL / 11 SKIP)
devices/qnn/test_qnn_ops.py PASS (10 ok / 0 FAIL / 0 SKIP) PASS (10 ok / 0 FAIL / 0 SKIP)
devices/qnn/test_qnn_plan.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
devices/qnn/test_qnnci.py PASS (30 ok / 0 FAIL / 0 SKIP) PASS (30 ok / 0 FAIL / 0 SKIP)
devices/qnn/test_qnnprobe.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
devices/test_devicens.py PASS (25 ok / 0 FAIL / 0 SKIP) PASS (25 ok / 0 FAIL / 0 SKIP)
devices/test_dtmdev.py PARTIAL (1 ok / 0 FAIL / 4 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
devices/test_dtypedev.py PARTIAL (6 ok / 0 FAIL / 5 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
devices/vulkan/test_vulkan4.py PARTIAL (5 ok / 0 FAIL / 71 SKIP) PARTIAL (5 ok / 0 FAIL / 71 SKIP)
devices/vulkan/test_vulkancov.py PASS (8 ok / 0 FAIL / 0 SKIP) PASS (8 ok / 0 FAIL / 0 SKIP)
distributed/test_asyncwork.py PASS (9 ok / 0 FAIL / 0 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
distributed/test_collect2.py PASS (16 ok / 0 FAIL / 0 SKIP) PASS (16 ok / 0 FAIL / 0 SKIP)
distributed/test_gloopin.py PASS (6 ok / 0 FAIL / 0 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
export/test_export.py PASS (15 ok / 0 FAIL / 0 SKIP) PASS (15 ok / 0 FAIL / 0 SKIP)
export/test_export4.py PASS (18 ok / 0 FAIL / 0 SKIP) PASS (18 ok / 0 FAIL / 0 SKIP)
export/test_export5.py PASS (21 ok / 0 FAIL / 0 SKIP) PASS (21 ok / 0 FAIL / 0 SKIP)
export/test_export6.py PASS (11 ok / 0 FAIL / 0 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
export/test_liftfresh.py PASS (9 ok / 0 FAIL / 0 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
export/test_structseq.py PASS (7 ok / 0 FAIL / 0 SKIP) PASS (7 ok / 0 FAIL / 0 SKIP)
export/test_varmean.py PASS (7 ok / 0 FAIL / 0 SKIP) PASS (7 ok / 0 FAIL / 0 SKIP)
gate/test_benchguard_ab_upstream.py PASS (6 ok / 0 FAIL / 0 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
gate/test_gatelock.py PASS (10 ok / 0 FAIL / 0 SKIP) PASS (10 ok / 0 FAIL / 0 SKIP)
gate/test_skipvis.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
gate/test_split_probe.py PASS (2 ok / 0 FAIL / 0 SKIP) PASS (2 ok / 0 FAIL / 0 SKIP)
gate/test_tmpleak.py PASS (3 ok / 0 FAIL / 0 SKIP) PASS (3 ok / 0 FAIL / 0 SKIP)
gate/test_toolguard_run_preflight.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
golden/test_x86pins.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
models/test_cbpath.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
models/test_cbwalls.py PARTIAL (9 ok / 0 FAIL / 6 SKIP) PARTIAL (14 ok / 0 FAIL / 1 SKIP)
models/test_higgs.py PASS (23 ok / 0 FAIL / 0 SKIP) PASS (23 ok / 0 FAIL / 0 SKIP)
models/test_qwen3.py PARTIAL (9 ok / 0 FAIL / 13 SKIP) PARTIAL (12 ok / 0 FAIL / 10 SKIP)
models/test_stream.py PARTIAL (6 ok / 0 FAIL / 9 SKIP) PARTIAL (9 ok / 0 FAIL / 6 SKIP)
models/test_voice3.py PARTIAL (37 ok / 0 FAIL / 2 SKIP) PASS (39 ok / 0 FAIL / 0 SKIP)
models/test_voice4.py PARTIAL (12 ok / 0 FAIL / 2 SKIP) PARTIAL (12 ok / 0 FAIL / 2 SKIP)
numerics/test_agree.py PASS (16 ok / 0 FAIL / 0 SKIP) PASS (16 ok / 0 FAIL / 0 SKIP)
numerics/test_agree2.py PASS (13 ok / 0 FAIL / 0 SKIP) PASS (13 ok / 0 FAIL / 0 SKIP)
numerics/test_int8.py PASS (19 ok / 0 FAIL / 0 SKIP) PASS (19 ok / 0 FAIL / 0 SKIP)
numerics/test_remeasure2.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
ops/test_canine.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
ops/test_complex.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
ops/test_cplx2.py PASS (10 ok / 0 FAIL / 0 SKIP) PASS (10 ok / 0 FAIL / 0 SKIP)
ops/test_equal_allclose.py PASS (21 ok / 0 FAIL / 0 SKIP) PASS (21 ok / 0 FAIL / 0 SKIP)
ops/test_fft.py PASS (16 ok / 0 FAIL / 0 SKIP) PASS (16 ok / 0 FAIL / 0 SKIP)
ops/test_glu.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
ops/test_indexsel.py PASS (3 ok / 0 FAIL / 0 SKIP) PASS (3 ok / 0 FAIL / 0 SKIP)
ops/test_last7.py PASS (17 ok / 0 FAIL / 0 SKIP) PASS (17 ok / 0 FAIL / 0 SKIP)
ops/test_metaemb.py PASS (20 ok / 0 FAIL / 0 SKIP) PASS (20 ok / 0 FAIL / 0 SKIP)
ops/test_metafam.py PASS (15 ok / 0 FAIL / 0 SKIP) PASS (15 ok / 0 FAIL / 0 SKIP)
ops/test_metastride.py PASS (13 ok / 0 FAIL / 0 SKIP) PASS (13 ok / 0 FAIL / 0 SKIP)
ops/test_pad.py PASS (23 ok / 0 FAIL / 0 SKIP) PASS (23 ok / 0 FAIL / 0 SKIP)
ops/test_repeat.py PASS (18 ok / 0 FAIL / 0 SKIP) PASS (18 ok / 0 FAIL / 0 SKIP)
ops/test_rnn.py PASS (26 ok / 0 FAIL / 0 SKIP) PASS (26 ok / 0 FAIL / 0 SKIP)
ops/test_scatter.py PASS (23 ok / 0 FAIL / 0 SKIP) PASS (23 ok / 0 FAIL / 0 SKIP)
ops/test_strided.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
ops/test_tail1.py PASS (32 ok / 0 FAIL / 0 SKIP) PASS (32 ok / 0 FAIL / 0 SKIP)
ops/test_tail2.py PASS (11 ok / 0 FAIL / 0 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
ops/test_tail3.py PASS (17 ok / 0 FAIL / 0 SKIP) PASS (17 ok / 0 FAIL / 0 SKIP)
ops/test_tail4.py PASS (25 ok / 0 FAIL / 0 SKIP) PASS (25 ok / 0 FAIL / 0 SKIP)
ops/test_vmap.py PASS (8 ok / 0 FAIL / 0 SKIP) PASS (8 ok / 0 FAIL / 0 SKIP)
release/test_cigate.py PASS (19 ok / 0 FAIL / 0 SKIP) PASS (19 ok / 0 FAIL / 0 SKIP)
release/test_cipub.py PASS (38 ok / 0 FAIL / 0 SKIP) PASS (38 ok / 0 FAIL / 0 SKIP)
release/test_docrefs.py PASS (11 ok / 0 FAIL / 0 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
release/test_ftwheel.py PASS (26 ok / 0 FAIL / 0 SKIP) PASS (26 ok / 0 FAIL / 0 SKIP)
release/test_layout.py PASS (6 ok / 0 FAIL / 0 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
release/test_platver_harnesses.py PASS (9 ok / 0 FAIL / 0 SKIP) PASS (9 ok / 0 FAIL / 0 SKIP)
release/test_publish.py PASS (4 ok / 0 FAIL / 0 SKIP) PASS (4 ok / 0 FAIL / 0 SKIP)
release/test_release.py PARTIAL (10 ok / 0 FAIL / 1 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)
release/test_style.py PASS (5 ok / 0 FAIL / 0 SKIP) PASS (5 ok / 0 FAIL / 0 SKIP)
release/test_toolguard_wheel_staging.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
release/test_wheelmatrix.py NOT RUN (0 ok / 0 FAIL / 1 SKIP) NOT RUN (0 ok / 0 FAIL / 1 SKIP)
training/test_stage0.py PASS (12 ok / 0 FAIL / 0 SKIP) PASS (12 ok / 0 FAIL / 0 SKIP)
training/test_stagetype.py PASS (6 ok / 0 FAIL / 0 SKIP) PASS (6 ok / 0 FAIL / 0 SKIP)
training/test_train.py PASS (11 ok / 0 FAIL / 0 SKIP) PASS (11 ok / 0 FAIL / 0 SKIP)

A SKIP is unverified on that runner, never passed. UNVERIFIED means the suite ran and every one of its tests skipped by name.

@b-re-w

b-re-w commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

CI evidence (run 37329272870, 7c571d5): linux gate suites=123/123 ok=1731 FAIL=0. It fails only on DOCWATCH golden_cases_failed eq 0, with golden_cases_failed = 54: the #69 x86_64 golden mismatches. The macOS gate passed. That is 4 more than #77's 50 on the same 12103 cases. DOCWATCH prints no case names, so which 4 is not known yet; #77's linux job is being re-run to see whether the count varies between runs.

@b-re-w
b-re-w merged commit 1f4f63d into develop Oct 16, 2026
5 checks passed
@b-re-w
b-re-w deleted the feat/xthread-backward branch October 16, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant