Skip to content

Make BlockTransposed cloneable#1267

Open
partychen wants to merge 4 commits into
microsoft:mainfrom
partychen:juchen-microsoft-fix-block-transposed-clone
Open

Make BlockTransposed cloneable#1267
partychen wants to merge 4 commits into
microsoft:mainfrom
partychen:juchen-microsoft-fix-block-transposed-clone

Conversation

@partychen

Copy link
Copy Markdown
Contributor
  • Does this PR have a descriptive title that could go in our release notes?
  • Does this PR add any new dependencies?
  • Does this PR modify any existing APIs?
  • Is the change to the API backwards compatible?
  • Should this result in any changes to our documentation, either updating existing docs or adding new ones?

Reference Issues/PRs

Fixes #1248.

What does this implement/fix? Briefly explain your changes.

This makes diskann_quantization::multi_vector::BlockTransposed implement Clone.

The block-transposed representation now implements NewCloned by copying its complete backing allocation, including row, column, and packing padding. This lets the existing Mat<T> clone machinery provide a deep clone without reconstructing the logical matrix or changing its physical layout.

A regression test verifies that the clone preserves the complete backing storage, owns a distinct allocation, and can be mutated without affecting the original.

Any other comments?

Validated with:

  • cargo test -p diskann-quantization
  • cargo clippy -p diskann-quantization --all-targets -- -D warnings

Implement cloning for the block-transposed representation by copying its complete backing allocation, including padding, and verify cloned matrices own independent storage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e50cc67e-4fa3-4f9c-ac82-89c85f4182f3

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Clone support for diskann_quantization::multi_vector::BlockTransposed by teaching the underlying BlockTransposedRepr how to deep-clone its entire backing allocation (including padding), enabling Mat<T>’s existing Clone machinery to produce a layout-preserving clone.

Changes:

  • Implement NewCloned for BlockTransposedRepr by copying storage_len() elements from the raw backing allocation into a new owned Mat.
  • Derive Clone for BlockTransposed, making the owned wrapper cloneable.
  • Add a regression test intended to validate allocation independence and clone correctness.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread diskann-quantization/src/multi_vector/block_transposed.rs
Write sentinels into column padding, remainder-row padding, and their intersection before cloning so the regression test distinguishes a full backing-allocation copy from logical reconstruction.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e50cc67e-4fa3-4f9c-ac82-89c85f4182f3
Copilot AI review requested due to automatic review settings July 21, 2026 08:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@codecov-commenter

codecov-commenter commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.48%. Comparing base (bacc7ef) to head (f18874e).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1267      +/-   ##
==========================================
- Coverage   91.06%   90.48%   -0.59%     
==========================================
  Files         500      498       -2     
  Lines       95938    95550     -388     
==========================================
- Hits        87369    86455     -914     
- Misses       8569     9095     +526     
Flag Coverage Δ
miri 90.48% <100.00%> (-0.59%) ⬇️
unittests 90.14% <100.00%> (-0.89%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...-quantization/src/multi_vector/block_transposed.rs 96.96% <100.00%> (+0.08%) ⬆️

... and 44 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

let repr = *v.repr();
// SAFETY: `v` points to an allocation described by `repr`, which contains
// exactly `storage_len` initialized elements.
let data =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably slightly more efficient as it doesn't have to go through Vec, which potentially over-allocates.

let b: Box<[_]> = unsafe { std::slice::from_raw_parts(...) }.into();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, let's avoid the indirection through Vec here since this is potentially a large-ish allocation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review. Fixed as suggestion.

// SAFETY: `v` points to an allocation described by `repr`, which contains
// exactly `storage_len` initialized elements.
let data =
unsafe { std::slice::from_raw_parts(v.as_raw_ptr().cast::<T>(), repr.storage_len()) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably do BlockTransposeRef::new(v).as_slice() to avoid the unsafe here. Or rather, we could if such a constructor existed ... which is probably needs to.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review. Fixed as suggestion.

Clone through BlockTransposedRef's safe slice API and convert the slice directly into a precisely sized Box allocation, avoiding both local unsafe code and Vec over-allocation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e50cc67e-4fa3-4f9c-ac82-89c85f4182f3
Copilot AI review requested due to automatic review settings July 23, 2026 02:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e50cc67e-4fa3-4f9c-ac82-89c85f4182f3
Copilot AI review requested due to automatic review settings July 23, 2026 02:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@partychen

Copy link
Copy Markdown
Contributor Author

@hildebrandmw and @arkrishn94,could you please help to review the pr again? Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] diskann_quantization::multi_vector::BlockTransposed should be Clone

5 participants