From 775aa1bf80bc3b906c7df9c8265f3a2881d43e7c Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Fri, 31 Jul 2026 14:07:55 -0700 Subject: [PATCH 1/5] Fix distribution of `diskann-wide` float tests. --- diskann-wide/src/test_utils/distribution.rs | 33 ++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/diskann-wide/src/test_utils/distribution.rs b/diskann-wide/src/test_utils/distribution.rs index f336e257a..27a49557e 100644 --- a/diskann-wide/src/test_utils/distribution.rs +++ b/diskann-wide/src/test_utils/distribution.rs @@ -53,7 +53,7 @@ impl Layout for f32 { pub struct Finite; macro_rules! finite { - ($T:ty, $bits:ty) => { + ($T:ty, $bits:ty, $twice:ty) => { impl Distribution<$T> for Finite { /// Generate floating point numbers spread more-or-less uniformly across the /// distribution of floating point numbers. @@ -68,13 +68,26 @@ macro_rules! finite { /// /// This function does not generate infinities or NaNs. fn sample(&self, rng: &mut R) -> $T { - // Generate a uniformly distributed 32-bit integer - let mut value: $bits = StandardUniform {}.sample(rng); + // Generate a uniformly distributed integer. + // + // This integer is twice as large as what's actually needed to generate + // + // * the value that will be used to make the final floating point number + // (the lower order bits). + // + // * a selector for the kind of floating point number we are going to + // generate. + // + // Generating a number twice as big allows us to perform just a single sample + // from the random number generator without biasing the result. + let twice: $twice = StandardUniform {}.sample(rng); + + let mut value = twice as $bits; // The distribution from which we sample weights to determine the type of // floating point number we are going to generate. - let weight = value % 100; - let (mask, allow_edge_exponent, allow_zero_mantissa) = if weight < 90 { + let kind = (twice >> <$bits>::BITS) % 128; + let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < 116 { // Generate a normal floating point number. // // All digits are fair game, but the exponent cannot be all zeros @@ -83,7 +96,7 @@ macro_rules! finite { // // The mantissa is allowed to be all zeros. (<$T>::EXPONENT_MASK | <$T>::MANTISSA_MASK, false, true) - } else if weight < 95 { + } else if kind < 123 { // Generate a subnormal floating point number. // // The exponent must be all zero and the mantissa cannot be zero. @@ -117,8 +130,8 @@ macro_rules! finite { }; } -finite!(half::f16, u16); -finite!(f32, u32); +finite!(half::f16, u16, u32); +finite!(f32, u32, u64); /////////// // Tests // @@ -231,8 +244,8 @@ mod tests { where T: TestDistribution, { - let normal_weight = 90; - let subnormal_weight = 5; + let normal_weight = 116; + let subnormal_weight = 7; let zero_weight = 5; let total_weight = normal_weight + subnormal_weight + zero_weight; From fc5ba8def8591b470f8c61e4e5507057b333bb19 Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Fri, 31 Jul 2026 14:12:41 -0700 Subject: [PATCH 2/5] Clean up comments. --- diskann-wide/src/test_utils/distribution.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/diskann-wide/src/test_utils/distribution.rs b/diskann-wide/src/test_utils/distribution.rs index 27a49557e..0e0c1edfc 100644 --- a/diskann-wide/src/test_utils/distribution.rs +++ b/diskann-wide/src/test_utils/distribution.rs @@ -73,19 +73,16 @@ macro_rules! finite { // This integer is twice as large as what's actually needed to generate // // * the value that will be used to make the final floating point number - // (the lower order bits). + // (the lower bits). // // * a selector for the kind of floating point number we are going to - // generate. + // generate (the upper bits). // // Generating a number twice as big allows us to perform just a single sample // from the random number generator without biasing the result. let twice: $twice = StandardUniform {}.sample(rng); let mut value = twice as $bits; - - // The distribution from which we sample weights to determine the type of - // floating point number we are going to generate. let kind = (twice >> <$bits>::BITS) % 128; let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < 116 { // Generate a normal floating point number. From 19636881f77ffabd451791d78448b879f6a16a83 Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Fri, 31 Jul 2026 14:17:44 -0700 Subject: [PATCH 3/5] Slightly turn down occurance of subnormals. --- diskann-wide/src/test_utils/distribution.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/diskann-wide/src/test_utils/distribution.rs b/diskann-wide/src/test_utils/distribution.rs index 0e0c1edfc..53a70ad86 100644 --- a/diskann-wide/src/test_utils/distribution.rs +++ b/diskann-wide/src/test_utils/distribution.rs @@ -93,7 +93,7 @@ macro_rules! finite { // // The mantissa is allowed to be all zeros. (<$T>::EXPONENT_MASK | <$T>::MANTISSA_MASK, false, true) - } else if kind < 123 { + } else if kind < 122 { // Generate a subnormal floating point number. // // The exponent must be all zero and the mantissa cannot be zero. @@ -242,8 +242,8 @@ mod tests { T: TestDistribution, { let normal_weight = 116; - let subnormal_weight = 7; - let zero_weight = 5; + let subnormal_weight = 6; + let zero_weight = 6; let total_weight = normal_weight + subnormal_weight + zero_weight; let num_trials: i64 = 1_000_000; From a84b6eba55a5ebb1ba0186cd4ff317a014b15aea Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Wed, 5 Aug 2026 15:44:35 -0700 Subject: [PATCH 4/5] Fewer magic consts. --- diskann-wide/src/test_utils/distribution.rs | 68 ++++++++++++++------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/diskann-wide/src/test_utils/distribution.rs b/diskann-wide/src/test_utils/distribution.rs index 5a6be3f73..c92f714e0 100644 --- a/diskann-wide/src/test_utils/distribution.rs +++ b/diskann-wide/src/test_utils/distribution.rs @@ -19,6 +19,16 @@ use rand::{ distr::{Distribution, StandardUniform}, }; +const KIND_COUNT: u64 = 128; +const NORMAL_KIND_COUNT: u64 = 116; +const SUBNORMAL_KIND_COUNT: u64 = 6; +const ZERO_KIND_COUNT: u64 = 6; + +const _: () = assert!( + NORMAL_KIND_COUNT + SUBNORMAL_KIND_COUNT + ZERO_KIND_COUNT == KIND_COUNT, + "floating point kind counts must sum to the total kind count" +); + trait Layout { type Bits; @@ -83,8 +93,8 @@ macro_rules! finite { let twice: $twice = StandardUniform {}.sample(rng); let mut value = twice as $bits; - let kind = (twice >> <$bits>::BITS) % 128; - let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < 116 { + let kind = u64::from(twice >> <$bits>::BITS) % KIND_COUNT; + let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < NORMAL_KIND_COUNT { // Generate a normal floating point number. // // All digits are fair game, but the exponent cannot be all zeros @@ -93,7 +103,7 @@ macro_rules! finite { // // The mantissa is allowed to be all zeros. (<$T>::EXPONENT_MASK | <$T>::MANTISSA_MASK, false, true) - } else if kind < 122 { + } else if kind < NORMAL_KIND_COUNT + SUBNORMAL_KIND_COUNT { // Generate a subnormal floating point number. // // The exponent must be all zero and the mantissa cannot be zero. @@ -143,13 +153,13 @@ mod tests { #[derive(Debug, Default)] struct Kinds { - normal: i64, - subnormal: i64, - zero: i64, + normal: u64, + subnormal: u64, + zero: u64, } impl Kinds { - fn sum(&self) -> i64 { + fn sum(&self) -> u64 { self.normal + self.subnormal + self.zero } } @@ -241,12 +251,7 @@ mod tests { where T: TestDistribution, { - let normal_weight = 116; - let subnormal_weight = 6; - let zero_weight = 6; - let total_weight = normal_weight + subnormal_weight + zero_weight; - - let num_trials: i64 = 1_000_000; + let num_trials: u64 = 1_000_000; let margin = num_trials / 500; let counts = T::test_distribution(num_trials as usize, seed); @@ -255,18 +260,39 @@ mod tests { println!("Counts = {:?}", counts); - assert!((positive_count - num_trials / 2).abs() < margin); - assert!((negative_count - num_trials / 2).abs() < margin); + assert!(positive_count.abs_diff(num_trials / 2) < margin); + assert!(negative_count.abs_diff(num_trials / 2) < margin); - assert!((counts.positive.normal - counts.negative.normal).abs() < margin); - assert!((counts.positive.subnormal - counts.negative.subnormal).abs() < margin); - assert!((counts.positive.zero - counts.negative.zero).abs() < margin); + assert!(counts.positive.normal.abs_diff(counts.negative.normal) < margin); + assert!( + counts + .positive + .subnormal + .abs_diff(counts.negative.subnormal) + < margin + ); + assert!(counts.positive.zero.abs_diff(counts.negative.zero) < margin); let kinds = counts.sum_accross(); - assert!((kinds.normal - num_trials * normal_weight / total_weight).abs() < margin); - assert!((kinds.subnormal - num_trials * subnormal_weight / total_weight).abs() < margin); - assert!((kinds.zero - num_trials * zero_weight / total_weight).abs() < margin); + assert!( + kinds + .normal + .abs_diff(num_trials * NORMAL_KIND_COUNT / KIND_COUNT) + < margin + ); + assert!( + kinds + .subnormal + .abs_diff(num_trials * SUBNORMAL_KIND_COUNT / KIND_COUNT) + < margin + ); + assert!( + kinds + .zero + .abs_diff(num_trials * ZERO_KIND_COUNT / KIND_COUNT) + < margin + ); } #[test] From f2ca48a6d0e6d4f578b68366aebfeef78052d508 Mon Sep 17 00:00:00 2001 From: Mark Hildebrand Date: Wed, 5 Aug 2026 15:50:27 -0700 Subject: [PATCH 5/5] Bikeshed --- diskann-wide/src/test_utils/distribution.rs | 30 +++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/diskann-wide/src/test_utils/distribution.rs b/diskann-wide/src/test_utils/distribution.rs index c92f714e0..17af37f46 100644 --- a/diskann-wide/src/test_utils/distribution.rs +++ b/diskann-wide/src/test_utils/distribution.rs @@ -19,14 +19,15 @@ use rand::{ distr::{Distribution, StandardUniform}, }; -const KIND_COUNT: u64 = 128; -const NORMAL_KIND_COUNT: u64 = 116; -const SUBNORMAL_KIND_COUNT: u64 = 6; -const ZERO_KIND_COUNT: u64 = 6; +// Must be a power of two to avoid bias when reducing a uniformly distributed integer. +const TOTAL_WEIGHT: u64 = 128; +const NORMAL_WEIGHT: u64 = 116; +const SUBNORMAL_WEIGHT: u64 = 6; +const ZERO_WEIGHT: u64 = 6; const _: () = assert!( - NORMAL_KIND_COUNT + SUBNORMAL_KIND_COUNT + ZERO_KIND_COUNT == KIND_COUNT, - "floating point kind counts must sum to the total kind count" + NORMAL_WEIGHT + SUBNORMAL_WEIGHT + ZERO_WEIGHT == TOTAL_WEIGHT, + "floating point weights must sum to the total weight" ); trait Layout { @@ -93,8 +94,8 @@ macro_rules! finite { let twice: $twice = StandardUniform {}.sample(rng); let mut value = twice as $bits; - let kind = u64::from(twice >> <$bits>::BITS) % KIND_COUNT; - let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < NORMAL_KIND_COUNT { + let kind = u64::from(twice >> <$bits>::BITS) % TOTAL_WEIGHT; + let (mask, allow_edge_exponent, allow_zero_mantissa) = if kind < NORMAL_WEIGHT { // Generate a normal floating point number. // // All digits are fair game, but the exponent cannot be all zeros @@ -103,7 +104,7 @@ macro_rules! finite { // // The mantissa is allowed to be all zeros. (<$T>::EXPONENT_MASK | <$T>::MANTISSA_MASK, false, true) - } else if kind < NORMAL_KIND_COUNT + SUBNORMAL_KIND_COUNT { + } else if kind < NORMAL_WEIGHT + SUBNORMAL_WEIGHT { // Generate a subnormal floating point number. // // The exponent must be all zero and the mantissa cannot be zero. @@ -278,21 +279,16 @@ mod tests { assert!( kinds .normal - .abs_diff(num_trials * NORMAL_KIND_COUNT / KIND_COUNT) + .abs_diff(num_trials * NORMAL_WEIGHT / TOTAL_WEIGHT) < margin ); assert!( kinds .subnormal - .abs_diff(num_trials * SUBNORMAL_KIND_COUNT / KIND_COUNT) - < margin - ); - assert!( - kinds - .zero - .abs_diff(num_trials * ZERO_KIND_COUNT / KIND_COUNT) + .abs_diff(num_trials * SUBNORMAL_WEIGHT / TOTAL_WEIGHT) < margin ); + assert!(kinds.zero.abs_diff(num_trials * ZERO_WEIGHT / TOTAL_WEIGHT) < margin); } #[test]