@@ -182,7 +182,7 @@ pub(crate) mod tests {
182182 use diskann_utils:: { test_data_root, views:: Matrix } ;
183183 use diskann_vector:: {
184184 DistanceFunction , PureDistanceFunction ,
185- distance:: { Metric , SquaredL2 } ,
185+ distance:: { CosineNormalized , Metric , SquaredL2 } ,
186186 } ;
187187 use rand:: { distr:: Distribution , rngs:: StdRng , seq:: SliceRandom } ;
188188 use rstest:: rstest;
@@ -1378,29 +1378,36 @@ pub(crate) mod tests {
13781378 }
13791379
13801380 const SIFTSMALL : & str = "/sift/siftsmall_learn_256pts.fbin" ;
1381+ const SIFTSMALL_NORMALIZED : & str = "/sift/siftsmall_learn_256pts_normalized.fbin" ;
13811382
13821383 #[ rstest]
13831384 #[ tokio:: test]
13841385 async fn test_sift_build_and_search < S > (
13851386 #[ values( FullPrecision , Hybrid :: new( None ) ) ] build_strategy : S ,
13861387 #[ values( 1 , 10 ) ] batchsize : usize ,
1388+ #[ values(
1389+ ( Metric :: L2 , SIFTSMALL ) ,
1390+ ( Metric :: CosineNormalized , SIFTSMALL_NORMALIZED ) ,
1391+ ) ]
1392+ metric_and_file : ( Metric , & str ) ,
13871393 ) where
13881394 S : for < ' a > InsertStrategy < ' a , TestProvider , & ' a [ f32 ] >
13891395 + MultiInsertStrategy < TestProvider , Matrix < f32 > >
13901396 + Clone ,
13911397 {
1398+ let ( metric, file) = metric_and_file;
13921399 let ctx = & DefaultContext ;
13931400 let parameters = InitParams {
13941401 l_build : 64 ,
13951402 max_degree : 16 ,
1396- metric : Metric :: L2 ,
1403+ metric,
13971404 batchsize : NonZeroUsize :: new ( batchsize) . unwrap ( ) ,
13981405 } ;
13991406
14001407 let ( index, data) = init_from_file (
14011408 build_strategy. clone ( ) ,
14021409 parameters,
1403- SIFTSMALL ,
1410+ file ,
14041411 8 ,
14051412 StartPointStrategy :: RandomSamples {
14061413 nsamples : ONE ,
@@ -1433,7 +1440,11 @@ pub(crate) mod tests {
14331440 //
14341441 // Because this dataset is small, we can expect exact equality.
14351442 for ( q, query) in data. row_iter ( ) . enumerate ( ) {
1436- let gt = groundtruth ( data. as_view ( ) , query, |a, b| SquaredL2 :: evaluate ( a, b) ) ;
1443+ let gt = groundtruth ( data. as_view ( ) , query, |a, b| match metric {
1444+ Metric :: L2 => SquaredL2 :: evaluate ( a, b) ,
1445+ Metric :: CosineNormalized => CosineNormalized :: evaluate ( a, b) ,
1446+ _ => unreachable ! ( ) ,
1447+ } ) ;
14371448 {
14381449 let mut result_output_buffer =
14391450 search_output_buffer:: IdDistance :: new ( & mut ids, & mut distances) ;
@@ -2061,8 +2072,11 @@ pub(crate) mod tests {
20612072 /// PQ only Build & Search ///
20622073 //////////////////////////////
20632074
2075+ #[ rstest]
2076+ #[ case( Metric :: L2 , SIFTSMALL ) ]
2077+ #[ case( Metric :: CosineNormalized , SIFTSMALL_NORMALIZED ) ]
20642078 #[ tokio:: test]
2065- async fn test_sift_pq_only_build_and_search ( ) {
2079+ async fn test_sift_pq_only_build_and_search ( # [ case ] metric : Metric , # [ case ] file : & str ) {
20662080 let ctx = & DefaultContext ;
20672081 let create_fn = |data : Arc < Matrix < f32 > > , start_points : & [ f32 ] | {
20682082 let pq_table = train_pq (
@@ -2074,8 +2088,7 @@ pub(crate) mod tests {
20742088 . unwrap ( ) ;
20752089
20762090 let ( config, parameters) =
2077- simplified_builder ( 64 , 16 , Metric :: L2 , data. ncols ( ) , data. nrows ( ) , no_modify)
2078- . unwrap ( ) ;
2091+ simplified_builder ( 64 , 16 , metric, data. ncols ( ) , data. nrows ( ) , no_modify) . unwrap ( ) ;
20792092
20802093 let index =
20812094 Arc :: new ( new_quant_only_index ( config, parameters, pq_table, NoDeletes ) . unwrap ( ) ) ;
@@ -2086,7 +2099,7 @@ pub(crate) mod tests {
20862099 index
20872100 } ;
20882101 let ( index, data) =
2089- init_and_build_index_from_file ( SIFTSMALL , create_fn, build_using_single_insert) . await ;
2102+ init_and_build_index_from_file ( file , create_fn, build_using_single_insert) . await ;
20902103
20912104 let neighbor_accessor = & mut index. provider ( ) . neighbors ( ) ;
20922105 // There should be one more reachable node than points in the dataset to account for
@@ -2131,7 +2144,17 @@ pub(crate) mod tests {
21312144 . await
21322145 . unwrap ( ) ;
21332146
2134- assert_top_k_exactly_match ( q, & gt, & ids, & distances, top_k) ;
2147+ if metric == Metric :: CosineNormalized {
2148+ let expected: Vec < _ > = gt
2149+ . iter ( )
2150+ . rev ( )
2151+ . take ( top_k)
2152+ . map ( |neighbor| * neighbor. id ( ) )
2153+ . collect ( ) ;
2154+ assert_eq ! ( expected, ids, "failed on query {q}" ) ;
2155+ } else {
2156+ assert_top_k_exactly_match ( q, & gt, & ids, & distances, top_k) ;
2157+ }
21352158 }
21362159 }
21372160
0 commit comments