slang-noinline-repro.zip
Summary
On an NVIDIA GB300 with driver 610.43.02, a small Neumaier compensated-summation
shader returns the wrong result through Vulkan when its correction helper is
inlined. Adding [noinline] to the helper makes the same shader return the
expected value. The CUDA target returns the expected value both with and
without [noinline].
The Slang session uses SlangFloatingPointMode.precise. Slang's emitted SPIR-V
still contains the expected OpFAdd followed by GLSL.std.450 Fma for the
inlined case, but it has no NoContraction decorations. This may therefore be
a Slang precise-mode semantics/code-generation issue or a downstream NVIDIA
Vulkan compiler issue. I would appreciate guidance on which layer owns it and
how an application should express this arithmetic requirement without using a
function-boundary workaround.
Expected result
For the input sequence [16777216.0, 1.0, -16777216.0], both implementations
should return the compensated average 0.33333334.
Actual result
Vulkan:
backend: vulkan
expected: np.float32(0.33333334)
inline: np.float32(0.0)
noinline: np.float32(0.33333334)
CUDA control:
backend: cuda
expected: np.float32(0.33333334)
inline: np.float32(0.33333334)
noinline: np.float32(0.33333334)
Reproduction
The attached repro.slang has inline and noinline versions of the same helper.
The attached repro.py dispatches both variants and prints their outputs. It
requires SlangPy and NumPy.
python repro.py vulkan
python repro.py cuda
The script exits with status 1 when either output differs from the expected
value, so the Vulkan command is expected to exit 1 while the bug is present.
Readable SPIR-V can also be generated with:
slangc repro.slang -entry compute_main -target spirv-assembly \
-profile glsl_450 -fp-mode precise -o repro-precise.spvasm
The inline path contains this operation order:
%next = OpFAdd %float %sum %value
%correction0 = OpExtInst %float %glsl Fma %float_n1 %next %sum
%correction = OpFAdd %float %correction0 %value
The noinline path is emitted as an OpFunction with DontInline and is called
with OpFunctionCall.
Environment
- Slang 2026.12
- SlangPy 0.41.0
- Linux aarch64, Ubuntu kernel 6.8.0-124-generic
- NVIDIA GB300
- NVIDIA driver 610.43.02
- CUDA toolkit 13.3, used only for the CUDA control
- Python 3.12.3
- NumPy 2.5.1
Workaround
Apply [noinline] to the correction helper for the Vulkan target. Falcor2 is
currently using this conditional workaround:
#ifdef __TARGET_VULKAN__
[noinline]
#endif
float neumaier_correction(float sum, float value, float next)
slang-noinline-repro.zip
Summary
On an NVIDIA GB300 with driver 610.43.02, a small Neumaier compensated-summation
shader returns the wrong result through Vulkan when its correction helper is
inlined. Adding
[noinline]to the helper makes the same shader return theexpected value. The CUDA target returns the expected value both with and
without
[noinline].The Slang session uses
SlangFloatingPointMode.precise. Slang's emitted SPIR-Vstill contains the expected
OpFAddfollowed byGLSL.std.450 Fmafor theinlined case, but it has no
NoContractiondecorations. This may therefore bea Slang precise-mode semantics/code-generation issue or a downstream NVIDIA
Vulkan compiler issue. I would appreciate guidance on which layer owns it and
how an application should express this arithmetic requirement without using a
function-boundary workaround.
Expected result
For the input sequence
[16777216.0, 1.0, -16777216.0], both implementationsshould return the compensated average
0.33333334.Actual result
Vulkan:
CUDA control:
Reproduction
The attached
repro.slanghas inline and noinline versions of the same helper.The attached
repro.pydispatches both variants and prints their outputs. Itrequires SlangPy and NumPy.
The script exits with status 1 when either output differs from the expected
value, so the Vulkan command is expected to exit 1 while the bug is present.
Readable SPIR-V can also be generated with:
slangc repro.slang -entry compute_main -target spirv-assembly \ -profile glsl_450 -fp-mode precise -o repro-precise.spvasmThe inline path contains this operation order:
The noinline path is emitted as an
OpFunctionwithDontInlineand is calledwith
OpFunctionCall.Environment
Workaround
Apply
[noinline]to the correction helper for the Vulkan target. Falcor2 iscurrently using this conditional workaround: