Latest Results
Make L2Denorm an array encoding instead of a scalar function
`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> Make L2Denorm an array encoding instead of a scalar function
`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> Exectuion and optimization tracing harness for testing (#7814)
## Summary
Introduces an internal tracing API that enables testing execution and
optimization flows with snapshot testing! Just wrap your code into a
callaback and call `trace_op`, and you get back both the result and a
snapshot you can assert.
For example:
```rust
#[test]
fn trace_optimize_reduce_fixpoint() -> VortexResult<()> {
let values = PrimitiveArray::from_iter([0i32, 1, 2, 3]).into_array();
let filter =
FilterArray::try_new(values.clone(), Mask::new_true(values.len()))?.into_array();
let traced = trace_op(|| filter.optimize())?;
assert!(traced.output.is::<Primitive>());
assert_arrays_eq!(traced.output, values);
insta::assert_snapshot!(traced.trace.to_string(), @r"
optimize root=vortex.filter(i32, len=4) session=false
reduce TrivialFilterRule: vortex.filter(i32, len=4) -> vortex.primitive(i32, len=4)
done output=vortex.primitive(i32, len=4)
");
Ok(())
}
```
The API for tests is pretty nice, internally there are still
improvements that can be made here, but this is a good step towards
building more confidence and making the execution model clearer.
---------
Signed-off-by: Adam Gutglick <adam@spiraldb.com>
Signed-off-by: Robert Kruszewski <github@robertk.io>
Co-authored-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Robert Kruszewski <github@robertk.io> Latest Branches
0%
0%
0%
© 2026 CodSpeed Technology