fix(tensor): relu/leaky_relu/softmax/log_softmax accept a scalar (#632)#664
Merged
Conversation
The four returned a silent null — not a value, not an error — when handed a
scalar, while every sibling in the same BUILTINS.md tables (sqrt, exp, log,
negative, add) is scalar-clean. tensor_to_flat returns NULL for a 0-dim
VAL_NUM, and the functions did `if (!flat) return make_null()`.
The silent null is the real defect: it propagates until it hits an unrelated
operator, so the error surfaces far from the cause —
define layer(x) as: return relu of x
layer of ([-3, 4]) # [0, 4]
layer of -3 # null <- silently poisons
(relu of -3) + 1 # Error line N: cannot apply '+' to null and num
A generic layer that works on a batch quietly poisons on a single sample.
Same shape as the #490-#512 silent-tolerance train.
Fix: a scalar fast path at the top of each, the degenerate element-wise case,
matching sqrt/exp/log:
relu(x) = max(0, x)
leaky_relu(x) = x < 0 ? 0.01x : x
softmax(x) = 1.0 (one-element normalization)
log_softmax(x) = 0.0 (log(1))
Tests: six asserts in test_flat_buffer_tensor.eigs (each fails on the pre-fix
null), including that (relu of -3) + 1 no longer poisons downstream. BUILTINS.md
notes the scalar behavior for all four.
Suite 3078/3078 release, 3082/3082 ASan+UBSan (detect_leaks=1, tally 0).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #632
Four tensor functions returned a silent null — not a value, not an error — when handed a scalar, while every sibling in the same
docs/BUILTINS.mdtables (sqrt,exp,log,negative,add) is scalar-clean.tensor_to_flatreturnsNULLfor a 0-dimVAL_NUM, and each function didif (!flat) return make_null().Why the silent null is the real problem
It propagates until it hits an unrelated operator, so the failure surfaces far from the cause:
A generic
layerthat works on a batch quietly poisons on a single sample. Same shape as the #490–#512 silent-tolerance train.Fix
A scalar fast path at the top of each — the degenerate element-wise case, matching
sqrt/exp/log:relu of xmax(0, x)leaky_relu of xx < 0 ? 0.01x : xsoftmax of x1.0(one-element normalization)log_softmax of x0.0(log(1))The list/buffer/2-D paths are untouched —
relu of [-3, 4]still gives[0, 4].Verification
All from the issue, confirmed on
main:Six regression asserts added to
test_flat_buffer_tensor.eigs, each failing on the pre-fix null (including the downstream-poison case).BUILTINS.mddocuments the scalar behavior for all four.Gates
detect_leaks=13082/3082, leak tally 0🤖 Generated with Claude Code