[diskann-vector] Support truly unaligned distances.#981
[diskann-vector] Support truly unaligned distances.#981hildebrandmw wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support in diskann-vector for computing SIMD-accelerated distances over truly under-aligned vector buffers (e.g., alignment 1), avoiding the need to copy data just to form &[T].
Changes:
- Introduces
UnalignedSlice+AsUnalignedand re-exports them from the crate root. - Updates SIMD distance kernels and specialization/dispatch plumbing to accept
AsUnalignedinputs. - Extends
Distancewithcall_unalignedand adds tests that exercise intentionally misaligned buffers.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
diskann-vector/src/unaligned.rs |
Adds UnalignedSlice, AsUnaligned, and a test-only Buffer to create intentionally misaligned data. |
diskann-vector/src/lib.rs |
Exposes the new unaligned APIs from the crate root. |
diskann-vector/src/test_util.rs |
Refactors test harness to accept a &mut dyn DistanceChecker (trait object). |
diskann-vector/src/distance/simd.rs |
Changes simd_op to accept AsUnaligned and adds tests validating unaligned correctness/Miri safety. |
diskann-vector/src/distance/implementations.rs |
Updates architecture hooks and fixed-size specialization to operate on AsUnaligned / UnalignedSlice. |
diskann-vector/src/distance/distance_provider.rs |
Switches dispatched function signature to UnalignedSlice and adds Distance::call_unaligned. |
diskann-vector/Cargo.toml |
Adds bytemuck (dev) and enables half/bytemuck for tests. |
diskann-providers/src/model/pq/distance/multi.rs |
Adjusts reference distance calls to pass slices via explicit deref (&*...). |
Cargo.lock |
Records the new bytemuck dependency resolution. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #981 +/- ##
==========================================
+ Coverage 89.48% 90.63% +1.14%
==========================================
Files 448 449 +1
Lines 84081 84206 +125
==========================================
+ Hits 75239 76318 +1079
+ Misses 8842 7888 -954
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| A: Architecture, | ||
| F: for<'a, 'b> diskann_wide::arch::Target2<A, T, &'a [L; N], &'b [R; N]> + Default, | ||
| F: for<'a, 'b> diskann_wide::arch::Target2<A, T, UnalignedSlice<'a, L>, UnalignedSlice<'b, R>> | ||
| + Default, |
There was a problem hiding this comment.
In the Specialize bound, for<'a, 'b> Target2<..., UnalignedSlice<'a, L>, UnalignedSlice<'a, R>> declares two lifetimes but uses 'a for both arguments (leaving 'b unused). This looks like a typo and unnecessarily couples the left/right lifetimes. Consider changing the second argument to UnalignedSlice<'b, R> (or removing 'b entirely if same-lifetime is intended) to keep the specialization constraints correct and future-proof.
There was a problem hiding this comment.
This is fixed.
An internal user has a case where full-precision vectors (e.g.
f32) are stored in completely unaligned buffers (e.g. align of 1), requiring a data copy to align the data before the slices can be safely constructed. However, our distance function implementations useSIMDVector::load_unalignedunder the hood, which are compatible with under-aligned pointers.This PR exposes a proper API to the
DistanceProvidertrait (via theDistancetype) for invoking the SIMD implementations with unaligned pointers.Suggested Reviewing Order
diskann-wide: The implementations ofSIMDVector::load*andSIMDVector::store*already support underaligned pointers. This PR updates the documentation and restructures the load/store tests to verify this property (we were already using this property in some of the quantized distance kernels). The new load/store tests successfully pass Miri.unaligned.rs- a newUnalignedSliceis added for unaligned slices. This is just a pointer + length pair with some validity requirements but no alignment requirement. Conversions from&[T]and&[T; N]are added and the traitAsUnalignedreplaces the use ofAsRef<[T]>and the internalToSlicetraits.A test-only
Bufferis used to purposely offset simple types to exercise the unaligned cases.distance/simd.rs: Thesimd_opkernel is tweaked to acceptAsUnalignedinstead ofAsRef. Checks have been added to the existing tests to ensure that the under-unaligned versions are both Miri compatible and yield the exact same results as their properly aligned counterparts.distance/implementation.rs: The architecture hooks and specialization are changed to useAsUnaligned. I've investigated the code generation and the checks forimpl FTarget<...> for Specialize<N, F>are sufficient to trigger constant propagation and the full unrolling of small fixed-sized kernels.distance/distance_provider.rs: TheDistancetype is changed to passUnalignedSlices across the function pointer boundary rather than raw slices. We can keep the existing API for slices trivially viaAsUnaligned.Code Generation
Unfortunately, the order in which functions are code-generated seems to have changed with this PR. That said, the fixed-sized specializations I have spot-checked result in identical assembly with this PR as with main, which is to be expected.