Repository navigation
Compare primitive values with RowFn - #9979
connortsui20 wants to merge 4 commits into
Conversation
Merging this PR will regress 4 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | WallTime | threshold_avx2[8] |
2 µs | 2.4 µs | -18.01% |
| ❌ | WallTime | threshold_neon[8] |
2.9 µs | 3.5 µs | -16.8% |
| ❌ | WallTime | threshold_avx2[64] |
3 µs | 3.4 µs | -11.21% |
| ❌ | WallTime | threshold_neon[80] |
4.7 µs | 5.3 µs | -11.21% |
| ⚡ | WallTime | compare_f32_avx2 |
4.4 µs | 2.6 µs | +67.05% |
| ⚡ | WallTime | compare_f32_avx512 |
3.4 µs | 2.4 µs | +44.24% |
| ⚡ |
Simulation | random_i128[0.01] |
7.7 µs | 5.5 µs | +38.51% |
| ⚡ | WallTime | mul_u64_nonnull_neon |
39.6 µs | 28.7 µs | +38.21% |
| ⚡ | WallTime | compare_float_neon |
8.2 µs | 6 µs | +36.62% |
| ⚡ | WallTime | compare_f32_neon |
5.5 µs | 4.2 µs | +31.49% |
| ⚡ | WallTime | compare_u64_avx2 |
3.7 µs | 3 µs | +25.67% |
| ⚡ | WallTime | compare_float_avx2 |
4.9 µs | 3.9 µs | +23.81% |
| ⚡ | WallTime | deferred_bool_neon[i64, PerRowPerRow] |
7.2 µs | 6.1 µs | +19.16% |
| ⚡ | WallTime | compare_int_constant_neon |
4 µs | 3.4 µs | +18.43% |
| ⚡ | WallTime | mul_i64_nonnull_neon |
38.7 µs | 32.6 µs | +18.43% |
| ⚡ | WallTime | multiply_shapes_neon[(32768, PerRowPerRow)] |
38.6 µs | 32.6 µs | +18.28% |
| ⚡ | WallTime | compare_u8_neon |
2 µs | 1.7 µs | +15.57% |
| ⚡ | WallTime | compare_u64_neon |
4.5 µs | 3.9 µs | +15.56% |
| ⚡ | WallTime | words_gather_dispatch_neon[1048576] |
29.8 µs | 25.8 µs | +15.31% |
| ⚡ | WallTime | compare_int_neon |
4.5 µs | 3.9 µs | +14.38% |
| ... | ... | ... | ... | ... | ... |
ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ct/row-fn-compare-primitive (7a7559b) with develop (1a9ed68)
28d9dd8 to
cd4b46c
Compare
cd4b46c to
6830c56
Compare
6830c56 to
8594ed8
Compare
8594ed8 to
cce1488
Compare
cce1488 to
0823a7d
Compare
0823a7d to
f2db74e
Compare
f2db74e to
a600c93
Compare
## Summary
Allows lazy masks to attach directly as validity when an encoding can
inspect validity through metadata and the input is `AllValid` or
`NonNullable`. Array-backed validity and encodings that have not opted
in retain the existing lazy-mask fallback.
The reduction rule, in pseudocode, is:
```text
Mask(Array(values, validity = AllValid), m)
-> Array(values, validity = m)
Mask(Array(values, validity = NonNullable), m)
-> Array(values, validity = m)
```
This applies when the input encoding opts into
`VALIDITY_IS_METADATA_ONLY` and supports mask reduction. `m` is a
non-nullable Boolean array with the same length as the input, and it may
be lazy. The reduction reuses the values and attaches `m` as validity
without executing it. The output dtype is nullable.
The identity is `AllValid AND m = m`, so no intermediate validity array
is needed.
## Changes
Adds `MaskReduce::VALIDITY_IS_METADATA_ONLY`, defaulting to false, and
enables it for Boolean, primitive, decimal, string, list, struct, map,
and ByteBool encodings. String, decimal, and list reducers preserve
existing buffers and children when rebuilding. List-view masking also
preserves its metadata without revalidating the zero-copy flag.
Two focused tests cover direct attachment to an all-valid primitive
array and the fallback for array-backed validity, including an all-true
bitmap. Existing constant-mask tests remain unchanged, and all tests
stay inline. The Boolean device-buffer fix landed in #10018.
Validation before the rebase: 168 focused comparison, mask, and RowFn
tests passed on the combined stack through #9979, along with `cargo
clippy -p vortex-array --all-targets --all-features -- -D warnings`. The
rebase preserves this PR's patches. Tests, formatting, and benchmarks
were not rerun locally after the rebase.
---------
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
a600c93 to
8eb8c0c
Compare
Depends on #10016. RowFn output payloads bypass the execution allocator. This change allocates them directly through `ctx.allocator()` across owned, deferred-retry, selected, filtered, constant, and sink execution, while preserving zero-copy primitive publication and empty-output paths. `OutputElement` chooses its collection storage through an associated buffer type and an allocation hook. The executor writes through `OutputBuffer` slots, and the buffer implementation constructs the array. Vortex primitive and Boolean implementations use `BufferMut`, while scalar and fixed-size-list sinks use the same storage contract. UTF-8 descriptors, external bytes, and polygon payloads also use the execution allocator. Physical sink parameters remain separate from allocation resources. Regressions check ownership of returned payloads using canonical inputs prepared before allocation tracking, including a context override, constant UTF-8 output, retry execution, and zero-copy reuse. A zero-sized output with `Vec` storage exercises the owned execution paths without requiring `BufferMut`. Boolean collector selection is preserved. The Boolean dense-retry path from merged #9986 also uses the execution allocator, with coverage in the existing packed-output allocator test. Validation before the rebase: 168 focused comparison, mask, and RowFn tests passed on the combined stack through #9979, along with `cargo clippy -p vortex-array --all-targets --all-features -- -D warnings`. Tests, formatting, and benchmarks were not rerun locally after the rebase. --------- Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
8eb8c0c to
c2e7937
Compare
|
This PR has been marked as stale because it has been open for 14 days with no activity. Please comment or remove the stale label if you wish to keep it active, otherwise it will be closed in 7 days |
c2e7937 to
048a785
Compare
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Profiling the compare benchmarks against the previous lane kernels showed that the RowFn row loop is at parity (an optimal vpcmp + kmov loop), and the regression is per-call batch bookkeeping. This removes the cheap parts of it: - Attach validity directly to a canonical dense kernel output instead of wrapping it in a lazy Mask scalar function that the caller must execute again. - Pass the comparison operands as borrowed execution args instead of allocating a Vec and cloning both arrays. - Collect batch inputs and their dtypes in one loop without a Result collect. - Skip the all-valid probe for a kernel output whose dtype is non-nullable. Signed-off-by: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDfqW81ajABZf3Pq7MnRjD
A dense batch with partial validity built its Boolean output as a non-nullable array, checked that every row was valid, and then built a second array to attach the batch validity. The dense kernel now offers that validity to the visit: the packed-bool collectors take it and build the output with it attached, and batch execution then validates the output once and finishes it. Visits that cannot attach validity leave it untaken and keep the existing path. On the AVX-512 compare benchmarks the nullable cases improve by about 0.04 us at 8K rows. The null-free cases measure about 0.07 us slower, which profiling attributes to different cross-codegen-unit inlining in the 16-unit bench profile rather than to this change's code path. Signed-off-by: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDfqW81ajABZf3Pq7MnRjD
dfe24ab to
7a7559b
Compare
) ## Summary Allows lazy masks to attach directly as validity when an encoding can inspect validity through metadata and the input is `AllValid` or `NonNullable`. Array-backed validity and encodings that have not opted in retain the existing lazy-mask fallback. The reduction rule, in pseudocode, is: ```text Mask(Array(values, validity = AllValid), m) -> Array(values, validity = m) Mask(Array(values, validity = NonNullable), m) -> Array(values, validity = m) ``` This applies when the input encoding opts into `VALIDITY_IS_METADATA_ONLY` and supports mask reduction. `m` is a non-nullable Boolean array with the same length as the input, and it may be lazy. The reduction reuses the values and attaches `m` as validity without executing it. The output dtype is nullable. The identity is `AllValid AND m = m`, so no intermediate validity array is needed. ## Changes Adds `MaskReduce::VALIDITY_IS_METADATA_ONLY`, defaulting to false, and enables it for Boolean, primitive, decimal, string, list, struct, map, and ByteBool encodings. String, decimal, and list reducers preserve existing buffers and children when rebuilding. List-view masking also preserves its metadata without revalidating the zero-copy flag. Two focused tests cover direct attachment to an all-valid primitive array and the fallback for array-backed validity, including an all-true bitmap. Existing constant-mask tests remain unchanged, and all tests stay inline. The Boolean device-buffer fix landed in vortex-data#10018. Validation before the rebase: 168 focused comparison, mask, and RowFn tests passed on the combined stack through vortex-data#9979, along with `cargo clippy -p vortex-array --all-targets --all-features -- -D warnings`. The rebase preserves this PR's patches. Tests, formatting, and benchmarks were not rerun locally after the rebase. --------- Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Depends on #10014.
Summary
Moves primitive comparisons onto
RowFnso decoding, constants, validity, and packed Boolean output use the shared row executor.Changes
PrimitiveComparedispatches primitive types and comparison operators through multiversionedRowVisitor::visit_bool, replacing the primitive lane kernels and their operand wrapper. Float comparisons retain Vortex's total ordering.Depends on #10014 for execution-allocator ownership of Boolean output. The comparison tests added in #9948 are retained and now exercise the RowFn implementation.
Validation before the rebase: 168 focused comparison, mask, and RowFn tests passed on the combined stack, including
comparison_uses_execution_allocator, along withcargo clippy -p vortex-array --all-targets --all-features -- -D warnings. Tests, formatting, and benchmarks were not rerun locally after the rebase.