From 069619b884a1f1f26e12d8c6f0ea7d84af1bd127 Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Tue, 10 Feb 2026 16:40:33 -0800 Subject: [PATCH 1/3] Prepare for merge with main. --- .../src/multi_vector/matrix.rs | 134 ++++++++++++++++-- 1 file changed, 126 insertions(+), 8 deletions(-) diff --git a/diskann-quantization/src/multi_vector/matrix.rs b/diskann-quantization/src/multi_vector/matrix.rs index d834784f2..4d6272dd9 100644 --- a/diskann-quantization/src/multi_vector/matrix.rs +++ b/diskann-quantization/src/multi_vector/matrix.rs @@ -242,6 +242,11 @@ pub unsafe trait NewOwned: ReprOwned { #[derive(Debug, Clone, Copy)] pub struct Defaulted; +/// Create a new [`Mat`] cloned from a view. +pub trait NewCloned: ReprOwned { + fn new_cloned(v: MatRef<'_, Self>) -> Mat; +} + ////////////// // Standard // ////////////// @@ -299,6 +304,29 @@ impl Standard { Ok(()) } } + + /// Create a new [`Mat`] around the contents of `b` **without** any checks. + /// + /// # Safety + /// + /// The value [`Standard::num_elements`] must return `Some(v)` and `b` must have length `v`. + unsafe fn box_to_mat(self, b: Box<[T]>) -> Mat { + debug_assert_eq!( + b.len(), + self.num_elements() + .expect("safety contract requires `self` to be well-formed"), + "safety contract violated" + ); + + // SAFETY: Box [guarantees](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw) + // the returned pointer is non-null. + let ptr = unsafe { NonNull::new_unchecked(Box::into_raw(b)) }.cast::(); + + // SAFETY: `ptr` is properly aligned and points to a slice of the required length. + // Additionally, it is dropped via `Box::from_raw`, which is compatible with obtaining + // it from `Box::into_raw`. + unsafe { Mat::from_raw_parts(self, ptr) } + } } /// Error types for [`Standard`]. @@ -383,15 +411,11 @@ where { type Error = crate::error::Infallible; fn new_owned(self, value: T) -> Result, Self::Error> { - let b: Box<[T]> = (0..self.nrows() * self.ncols()).map(|_| value).collect(); - // SAFETY: Box [guarantees](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw) - // the returned pointer is non-null. - let ptr = unsafe { NonNull::new_unchecked(Box::into_raw(b)) }.cast::(); + let b: Box<[T]> = (0..self.num_elements().unwrap()).map(|_| value).collect(); - // SAFETY: `ptr` is properly aligned and points to a slice of the required length. - // Additionally, it is dropped via `Box::from_raw`, which is compatible with obtaining - // it from `Box::into_raw`. - Ok(unsafe { Mat::from_raw_parts(self, ptr) }) + // SAFETY: By construction, `b` has length `self.num_elements()`. Since we did + // not panic when creating `b`, we know that `num_elements()` is well formed. + Ok(unsafe { self.box_to_mat(b) }) } } @@ -442,6 +466,19 @@ where } } +impl NewCloned for Standard +where + T: Copy, +{ + fn new_cloned(v: MatRef<'_, Self>) -> Mat { + let b: Box<[T]> = v.rows().flatten().copied().collect(); + + // SAFETY: By construction, `b` has length `v.repr().num_elements()`. Furthermore, + // since `v` is a valid `MatRef`, we know that `v.repr().num_elements()` cannot overflow. + unsafe { v.repr().box_to_mat(b) } + } +} + ///////// // Mat // ///////// @@ -575,6 +612,12 @@ impl Drop for Mat { } } +impl Clone for Mat { + fn clone(&self) -> Self { + T::new_cloned(self.as_view()) + } +} + impl Mat> { /// Returns the raw dimension (columns) of the vectors in the matrix. #[inline] @@ -661,6 +704,14 @@ impl<'a, T: Repr> MatRef<'a, T> { Rows::new(*self) } + /// Return a [`Mat`] with the same contents as `self`. + pub fn to_owned(&self) -> Mat + where + T: NewCloned, + { + T::new_cloned(*self) + } + /// Construct a new [`MatRef`] over the raw pointer and representation without performing /// any validity checks. /// @@ -832,6 +883,14 @@ impl<'a, T: ReprMut> MatMut<'a, T> { RowsMut::new(self.reborrow_mut()) } + /// Return a [`Mat`] with the same contents as `self`. + pub fn to_owned(&self) -> Mat + where + T: NewCloned, + { + T::new_cloned(self.as_view()) + } + /// Construct a new [`MatMut`] over the raw pointer and representation without performing /// any validity checks. /// @@ -1338,6 +1397,65 @@ mod tests { } } + #[test] + fn test_mat_clone() { + for nrows in ROWS { + for ncols in COLS { + let repr = Standard::::new(*nrows, *ncols); + let ctx = &lazy_format!("nrows = {}, ncols = {}", nrows, ncols); + + let mut mat = Mat::new(repr, Defaulted).unwrap(); + fill_mat(&mut mat, repr); + + // Clone via Mat::clone + { + let ctx = &lazy_format!("{ctx} - Mat::clone"); + let cloned = mat.clone(); + + assert_eq!(cloned.num_vectors(), *nrows); + assert_eq!(cloned.vector_dim(), *ncols); + + check_mat(&cloned, repr, ctx); + check_mat_ref(cloned.reborrow(), repr, ctx); + check_rows(cloned.rows(), repr, ctx); + + // Cloned allocation is independent. + if repr.num_elements().unwrap_or(0) > 0 { + assert_ne!(mat.as_ptr(), cloned.as_ptr()); + } + } + + // Clone via MatRef::to_owned + { + let ctx = &lazy_format!("{ctx} - MatRef::to_owned"); + let owned = mat.as_view().to_owned(); + + check_mat(&owned, repr, ctx); + check_mat_ref(owned.reborrow(), repr, ctx); + check_rows(owned.rows(), repr, ctx); + + if repr.num_elements().unwrap_or(0) > 0 { + assert_ne!(mat.as_ptr(), owned.as_ptr()); + } + } + + // Clone via MatMut::to_owned + { + let ctx = &lazy_format!("{ctx} - MatMut::to_owned"); + let owned = mat.as_view_mut().to_owned(); + + check_mat(&owned, repr, ctx); + check_mat_ref(owned.reborrow(), repr, ctx); + check_rows(owned.rows(), repr, ctx); + + if repr.num_elements().unwrap_or(0) > 0 { + assert_ne!(mat.as_ptr(), owned.as_ptr()); + } + } + } + } + } + #[test] fn test_mat_refmut() { for nrows in ROWS { From 7bbe4e175c233c9ddbde0e12873d282a89f3e94b Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Tue, 10 Feb 2026 16:52:27 -0800 Subject: [PATCH 2/3] Enable `Mat` to be cloned and implement `to_owned` inherend methods. --- .../src/multi_vector/matrix.rs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/diskann-quantization/src/multi_vector/matrix.rs b/diskann-quantization/src/multi_vector/matrix.rs index 472112a2b..c38f07061 100644 --- a/diskann-quantization/src/multi_vector/matrix.rs +++ b/diskann-quantization/src/multi_vector/matrix.rs @@ -322,14 +322,9 @@ impl Standard { /// /// # Safety /// - /// The value [`Standard::num_elements`] must return `Some(v)` and `b` must have length `v`. + /// The length of `b` must be exactly [`Standard::num_elements`]. unsafe fn box_to_mat(self, b: Box<[T]>) -> Mat { - debug_assert_eq!( - b.len(), - self.num_elements() - .expect("safety contract requires `self` to be well-formed"), - "safety contract violated" - ); + debug_assert_eq!(b.len(), self.num_elements(), "safety contract violated"); // SAFETY: Box [guarantees](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw) // the returned pointer is non-null. @@ -472,10 +467,9 @@ where { type Error = crate::error::Infallible; fn new_owned(self, value: T) -> Result, Self::Error> { - let b: Box<[T]> = (0..self.num_elements().unwrap()).map(|_| value).collect(); + let b: Box<[T]> = (0..self.num_elements()).map(|_| value).collect(); - // SAFETY: By construction, `b` has length `self.num_elements()`. Since we did - // not panic when creating `b`, we know that `num_elements()` is well formed. + // SAFETY: By construction, `b` has length `self.num_elements()`. Ok(unsafe { self.box_to_mat(b) }) } } @@ -534,8 +528,7 @@ where fn new_cloned(v: MatRef<'_, Self>) -> Mat { let b: Box<[T]> = v.rows().flatten().copied().collect(); - // SAFETY: By construction, `b` has length `v.repr().num_elements()`. Furthermore, - // since `v` is a valid `MatRef`, we know that `v.repr().num_elements()` cannot overflow. + // SAFETY: By construction, `b` has length `v.repr().num_elements()`. unsafe { v.repr().box_to_mat(b) } } } @@ -1498,7 +1491,7 @@ mod tests { fn test_mat_clone() { for nrows in ROWS { for ncols in COLS { - let repr = Standard::::new(*nrows, *ncols); + let repr = Standard::::new(*nrows, *ncols).unwrap(); let ctx = &lazy_format!("nrows = {}, ncols = {}", nrows, ncols); let mut mat = Mat::new(repr, Defaulted).unwrap(); @@ -1517,7 +1510,7 @@ mod tests { check_rows(cloned.rows(), repr, ctx); // Cloned allocation is independent. - if repr.num_elements().unwrap_or(0) > 0 { + if repr.num_elements() > 0 { assert_ne!(mat.as_ptr(), cloned.as_ptr()); } } @@ -1531,7 +1524,7 @@ mod tests { check_mat_ref(owned.reborrow(), repr, ctx); check_rows(owned.rows(), repr, ctx); - if repr.num_elements().unwrap_or(0) > 0 { + if repr.num_elements() > 0 { assert_ne!(mat.as_ptr(), owned.as_ptr()); } } @@ -1545,7 +1538,7 @@ mod tests { check_mat_ref(owned.reborrow(), repr, ctx); check_rows(owned.rows(), repr, ctx); - if repr.num_elements().unwrap_or(0) > 0 { + if repr.num_elements() > 0 { assert_ne!(mat.as_ptr(), owned.as_ptr()); } } From 89f0514bdad9751f52104ffead7f2b9a64f085d2 Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Tue, 10 Feb 2026 16:57:40 -0800 Subject: [PATCH 3/3] Add documentation to `new_cloned`. --- diskann-quantization/src/multi_vector/matrix.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/diskann-quantization/src/multi_vector/matrix.rs b/diskann-quantization/src/multi_vector/matrix.rs index c38f07061..e8789b2c8 100644 --- a/diskann-quantization/src/multi_vector/matrix.rs +++ b/diskann-quantization/src/multi_vector/matrix.rs @@ -244,6 +244,9 @@ pub struct Defaulted; /// Create a new [`Mat`] cloned from a view. pub trait NewCloned: ReprOwned { + /// Clone the contents behind `v`, returning a new owning [`Mat`]. + /// + /// Implementations should ensure the returned [`Mat`] is "semantically the same" as `v`. fn new_cloned(v: MatRef<'_, Self>) -> Mat; }