test: xfail regression for #1051 (bwds crash on runtime-start diff loop) + docs workaround - #1053
test: xfail regression for #1051 (bwds crash on runtime-start diff loop) + docs workaround#1053nv-slang-bot[bot] wants to merge 1 commit into
Conversation
The runtime_start test deliberately SIGSEGVs a GPU subprocess. On CI unit-test lanes SlangPy's Crashpad handler is active (crashpad flag), and it intercepts the intentional crash to capture a minidump -- which wedges the Python test step for hours (observed 2h+ on linux/windows, 6h on macos on PR #1053) instead of exiting cleanly. Locally crashpad is disabled (is_supported() == False) so the crash was clean and the hang did not reproduce. Skip the crashing subprocess case when spy.crashpad.is_supported(). The constant-start controls (const_neg_start, zero_start) still run on every lane and carry the regression value; the crashing tripwire runs on non-Crashpad builds and local dev, where a clean SIGSEGV -> XFAIL, and XPASS once the upstream fix (shader-slang/slang#12072) lands. Refs #1051
…wds crash) Backward dispatch (.bwds()) of a [Differentiable] function crashes when the body contains a loop whose start value is a runtime (non-constant) induction start, e.g. `for (int dx = -radius; dx <= radius; ++dx)` with radius a runtime no_diff param. The trigger is the start being non-constant, not negative: a constant negative start (-2) differentiates fine. Root cause is upstream in Slang reverse-mode autodiff (shader-slang/slang#12070, fixed by shader-slang/slang#12072), not SlangPy, which hands the function body verbatim to bwd_diff. Add two constant-start control tests (const_neg_start, zero_start) that differentiate correctly, compared element-wise against an independent numpy oracle on a non-square shape. They pin the #1051 trigger to runtime-ness and guard the documented zero-based workaround. The crashing runtime-start form is not exercised as a live test (it is a hard native crash; documented in the test docstring and docs/src/autodiff/autodiff.rst instead). Document the workaround in the autodiff docs. Refs #1051 Refs shader-slang/slang#12070 Refs shader-slang/slang#12072
bc4e5ba to
0fb3344
Compare
|
Status: this PR is BLOCKED on a CI/test-harness issue that is not a defect in this PR's code — do not merge; held pending a maintainer/operator decision.
🤖 Generated by an automated SlangPy coworker — may be inaccurate. A human maintainer should verify. |
|
Assigning over to @saipraveenb25 since he owns shader-slang/slang#12070 where this will ultimately need to be fixed |
|
Update — the upstream root cause is fixed; this PR's remaining gate is the bundled-Slang pin, not a release. Correcting my 2026-07-14 note above, which is now stale in three ways:
On the CI blocker (#1070), one caveat worth flagging before assuming this PR is unblocked. #1070 was closed as "the race condition in profiling", but two things don't fit, and I'd rather raise them than quietly rely on them:
Across 07-29 → 08-03 there were 46 Suggested next step, @saipraveenb25 / @jhelferty-nv — since this PR is assigned to you, flagging rather than pushing: the docs half (the 🤖 Generated by an automated SlangPy coworker — may be inaccurate. A human maintainer should verify. |
Summary
Regression coverage + a documented workaround for #1051, where backward dispatch (
.bwds()) of a[Differentiable]function crashes when the function body contains a loop with a runtime (non-constant) induction start, e.g.for (int dx = -radius; dx <= radius; ++dx)whereradiusis ano_diffruntime param.This PR does not fix the crash — the root cause is upstream in the Slang compiler's reverse-mode autodiff (tracked as shader-slang/slang#12070), and SlangPy cannot fix it: it hands the user function verbatim to
bwd_diffand does no loop/induction rewriting. Confirmed against the generated kernel (SLANGPY_PRINT_GENERATED_SHADERS=1): the bwds kernel prepends[Differentiable]to a_trampoline, calls the user function unchanged, then dispatchesbwd_diff(_trampoline).The trigger is the loop start being non-constant, not negative. A constant negative start such as
for (int dx = -2; dx <= 2; ++dx)differentiates fine; the reporter's-radiuswas incidentally both runtime and negative. Reproduced on CUDA and Vulkan (SIGSEGV, exit 139); the constant-start controls produce correct gradients.Uses
Refs(notFixes) intentionally: the issue must stay open to track the upstream fix. It will be closed by the upstream Slang change, not by merging this.Refs #1051
Refs shader-slang/slang#12070
Changes
slangpy/tests/slangpy_tests/test_diff_loop_runtime_start.py(new):test_diff_loop_runtime_startruns the crashingruntime_startbwds in an isolated subprocess (a SIGSEGV is a hard native crash that would otherwise take down the pytest worker / disruptpytest-xdist). It brackets the.bwds()dispatch with begin/end markers so a crash is attributed to the backward dispatch specifically (not setup/readback/teardown). Markedxfail(raises=_KnownCrash, strict=True):test_diff_loop_constant_startruns two in-process controls that must always pass:const_neg_start(constant-2→ shows negative-ness is not the trigger) andzero_start(the documented workaround). Together they isolate the trigger to runtime-ness.docs/src/autodiff/autodiff.rst: a note documenting the constant-start workaround, cross-linking [Bug] Backward dispatch segfaults when a [Differentiable] function has a loop with a negative runtime start value #1051 and slang#12070.Verification
pytest slangpy/tests/slangpy_tests/test_diff_loop_runtime_start.py→ 4 passed, 2 xfailed on CUDA + Vulkan, exit 0; identical underpytest-xdist -n2.blackclean, pure ASCII (satisfiescheck-ascii-source).5-bullet status
bwd_diff. In-repo action is coverage + docs only.🤖 Generated by an automated SlangPy coworker — may be inaccurate. A human maintainer should verify.