Skip to content

Standardize scalar function array construction - #9135

Draft
connortsui20 wants to merge 2 commits into
developfrom
ct/scalar-fn-factory-ext
Draft

Standardize scalar function array construction#9135
connortsui20 wants to merge 2 commits into
developfrom
ct/scalar-fn-factory-ext

Conversation

@connortsui20

@connortsui20 connortsui20 commented Aug 1, 2026

Copy link
Copy Markdown
Member

(semi-related) Tracking Issue: #9129

Right now the tensor and geo scalar functions maintain bespoke inherent constructors alongside ScalarFnFactoryExt::try_new_array. This removes the redundant constructors and migrates the in-tree callers to the shared factory API.

Note that this intentionally removes public new() and try_new_array(...) methods from CosineSimilarity, InnerProduct, and L2Norm, plus try_new_array(...) from the four geo scalar functions. This is a source compatibility break, which is why I split it out from the RowFn work and left the PR as a draft. The main review question is whether the smaller and consistent API is worth that break, or whether these should remain as forwarding methods.

L2Denorm used to be the awkward exception here: its constructors enforce or explicitly bypass the normalized-row invariant, which the generic factory can't express. That turned out to be a sign it was never a scalar function in the first place, so it moves to a dedicated array encoding in #9138 and is no longer part of this diff.

Edit: rebased onto #9138. The GitHub base is still showing develop, so this diff currently includes the #9138 commit. It needs to be re-pointed at ct/l2-denorm-encoding.

@connortsui20

Copy link
Copy Markdown
Member Author

Still need to figure out if there is a way to make the generic factor ext trait able to express more complicated validation logic as in L2Denorm::try_new_array

claude and others added 2 commits August 2, 2026 18:03
`L2Denorm` was registered as a `ScalarFnVTable`, but it never behaved like
one. Its constructor took an `ExecutionCtx` and scanned both children to
enforce a unit-norm invariant, `L2Norm` read its stored norms instead of
recomputing, `CosineSimilarity` and `InnerProduct` reached into its physical
children, and the compressor scheme named it as a produced encoding. Those
are all properties of a physical decomposition, not of an operation over
arbitrary well-typed values.

Moves it to `vortex-tensor/src/encodings/l2_denorm/` as a real `VTable` with
two slots (`normalized`, `norms`). Structural validation runs on construction
and on deserialization, `try_new` additionally scans for the exact unit-norm
invariant, and `try_new_trusted` skips that scan for lossy normalized
children whose stored norms stay authoritative. Neither constructor is
`unsafe`, since violating the contract produces wrong answers rather than
undefined behavior.

The encoding keeps the `vortex.tensor.l2_denorm` array ID and the same
two-field metadata message, so the wire format is unchanged.

Slice and filter now push down into both children through `reduce_parent`.
The generic `ScalarFnArray` filter rule only fired when at most one child was
non-constant, which for this encoding was almost never.

Also makes `L2DenormScheme` cascade its two children like `TemporalScheme`
does, which lets both `HACK TO SUPPORT L2 DENORMALIZATION` special cases come
out of `CascadingCompressor`. The scheme now competes on measured size like
every other scheme.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XEo4wnqKfAf1QLJbdrz76j
Signed-off-by: Claude <noreply@anthropic.com>
Uses `ScalarFnFactoryExt` for tensor and geo scalar functions instead of maintaining per-function constructors. `L2Denorm` keeps its checked constructor because it validates the normalized-row invariant.

Signed-off-by: "Connor Tsui" <connor.tsui20@gmail.com>
@connortsui20
connortsui20 force-pushed the ct/scalar-fn-factory-ext branch from ce52f49 to bf43ecf Compare August 2, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/break A breaking API change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants