@@ -3,8 +3,12 @@ use std::io::{Read, Seek, SeekFrom, Write};
33use std:: mem:: size_of;
44
55use byteorder:: { LittleEndian , ReadBytesExt , WriteBytesExt } ;
6+ #[ cfg( feature = "memmap" ) ]
7+ pub use mmap:: MmapQuantizedArray ;
68use ndarray:: { Array , Array1 , Array2 , ArrayView1 , ArrayView2 , Axis , CowArray , IntoDimension , Ix1 } ;
79use rand:: { CryptoRng , RngCore , SeedableRng } ;
10+ use rand_chacha:: ChaChaRng ;
11+ use reductive:: error:: ReductiveError ;
812use reductive:: pq:: { Pq , QuantizeVector , Reconstruct as _, TrainPq } ;
913
1014use super :: { sealed:: CloneFromMapping , Storage , StorageView } ;
@@ -419,6 +423,17 @@ where
419423 T : TrainPq < f32 > ,
420424 R : CryptoRng + RngCore + SeedableRng + Send ,
421425 {
426+ // Since we are storing quantized values in an u8 array, we have a stricter
427+ // upper bound than reductive.
428+ let max_subquantizer_bits = std:: cmp:: min ( 8 , ( self . shape ( ) . 0 as f64 ) . log2 ( ) . trunc ( ) as u32 ) ;
429+ if n_subquantizer_bits > max_subquantizer_bits {
430+ return Err ( Error :: QuantizationError (
431+ ReductiveError :: IncorrectNSubquantizerBits {
432+ max_subquantizer_bits,
433+ } ,
434+ ) ) ;
435+ }
436+
422437 let ( embeds, norms) = if normalize {
423438 let norms = self . view ( ) . outer_iter ( ) . map ( |e| e. dot ( & e) . sqrt ( ) ) . collect ( ) ;
424439 let mut normalized = self . view ( ) . to_owned ( ) ;
@@ -437,7 +452,8 @@ where
437452 n_attempts,
438453 embeds. view ( ) ,
439454 & mut rng,
440- ) ?;
455+ )
456+ . map_err ( Error :: QuantizationError ) ?;
441457
442458 let quantized_embeddings = quantizer. quantize_batch ( embeds. view ( ) ) ;
443459
@@ -668,10 +684,6 @@ mod mmap {
668684 }
669685}
670686
671- #[ cfg( feature = "memmap" ) ]
672- pub use mmap:: MmapQuantizedArray ;
673- use rand_chacha:: ChaChaRng ;
674-
675687#[ cfg( test) ]
676688mod tests {
677689 use std:: io:: { Cursor , Read , Seek , SeekFrom } ;
0 commit comments