Skip to content

Commit 3047d90

Browse files
committed
cleanup and updates numbers
1 parent e7fa66f commit 3047d90

5 files changed

Lines changed: 18 additions & 111 deletions

File tree

cpp/deglib/include/random.h

Lines changed: 3 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,18 @@
11
#pragma once
22

3-
#include <cmath>
43
#include <cstdint>
5-
#include <cstring>
64
#include <random>
75
#include <type_traits>
86

97
// Portable random distributions that produce identical sequences across
108
// compilers and platforms (Windows/MSVC, Linux/GCC, macOS/Clang).
119
//
12-
// std::uniform_int_distribution and std::normal_distribution are NOT portable:
13-
// - MSVC STL, libstdc++, and libc++ each use different algorithm implementations
14-
// - The same seed produces different sequences on different platforms
15-
// - This makes regression tests and graph builds non-deterministic across CI runners
16-
//
17-
// Both distributions operate on std::mt19937 (which IS portable — same seed
18-
// produces the same uniform sequence) and use deterministic algorithms:
19-
// - DeterministicUniformIntDistribution: bounded rejection sampling
20-
// - DeterministicNormalDistribution: Box-Muller transform with portable math
21-
//
22-
// Reference: Box, G.E.P. and Muller, M.E. (1958), "A Note on the Generation
23-
// of Random Normal Deviates", Annals of Mathematical Statistics, 29(2), pp.610-611.
10+
// std::uniform_int_distribution is NOT portable across MSVC STL, libstdc++, and libc++.
11+
// DeterministicUniformIntDistribution operates on std::mt19937 using bounded
12+
// rejection sampling to guarantee identical integer sequences on all platforms.
2413

2514
namespace deglib::random {
2615

27-
namespace detail {
28-
29-
// Portable float natural logarithm (log(x)) without platform libm dependencies.
30-
// Operates strictly on 32-bit floats with 24-bit mantissa precision.
31-
inline float portable_log(float x) {
32-
uint32_t ix;
33-
std::memcpy(&ix, &x, sizeof(float));
34-
int exp = static_cast<int>((ix >> 23) & 0xFF) - 127;
35-
ix = (ix & 0x007FFFFF) | 0x3F800000;
36-
float m;
37-
std::memcpy(&m, &ix, sizeof(float));
38-
if (m > 1.41421356f) {
39-
m *= 0.5f;
40-
exp += 1;
41-
}
42-
float f = m - 1.0f;
43-
float s = f / (2.0f + f);
44-
float z = s * s;
45-
float w = z * z;
46-
float R = z * (0.6666666666666666f + w * (0.4f + w * (0.2857142857142857f + w * (0.2222222222222222f + w * 0.1818181818181818f))));
47-
return static_cast<float>(exp) * 0.6931471805599453f + s * (2.0f + R);
48-
}
49-
50-
// Portable float cosine (cos(x)) without platform libm dependencies.
51-
// Input x is in [0, 2*PI). Uses symmetry reduction to [0, PI/2] and a 10th-degree polynomial.
52-
inline float portable_cos(float x) {
53-
constexpr float PI = 3.14159265358979323846f;
54-
constexpr float HALF_PI = 1.57079632679489661923f;
55-
constexpr float TWO_PI = 6.28318530717958647692f;
56-
57-
// Symmetry reduction to [0, PI]
58-
if (x > PI) {
59-
x = TWO_PI - x;
60-
}
61-
62-
// Symmetry reduction to [0, PI/2]
63-
bool sign = false;
64-
if (x > HALF_PI) {
65-
x = PI - x;
66-
sign = true;
67-
}
68-
69-
// Polynomial for cos(x) on [0, PI/2] accurate to 1e-7 (full float precision)
70-
float x2 = x * x;
71-
float res = 1.0f - x2 * (0.5f - x2 * (0.041666666666666664f - x2 * (0.0013888888888888889f - x2 * (0.0000248015873015873f - x2 * 0.000000275573192239859f))));
72-
73-
return sign ? -res : res;
74-
}
75-
76-
} // namespace detail
77-
7816
/// Portable uniform integer distribution using bounded rejection sampling.
7917
/// Guarantees identical integer sequences across Windows, Linux, and macOS.
8018
template <typename IntType = int>
@@ -112,35 +50,4 @@ class DeterministicUniformIntDistribution {
11250
uint64_t max_valid_{4294967295ULL};
11351
};
11452

115-
/// Portable normal distribution using the Box-Muller transform with portable math.
116-
/// Always consumes exactly 2 RNG values per call (no caching/spare state)
117-
/// to ensure deterministic behavior regardless of how multiple instances
118-
/// share the same RNG.
119-
class DeterministicNormalDistribution {
120-
public:
121-
explicit DeterministicNormalDistribution(float mean, float stddev)
122-
: mean_(mean), stddev_(stddev) {}
123-
124-
// Generate a single normally-distributed float using the provided RNG.
125-
// Operates strictly on 24-bit mantissa float division and portable math
126-
// to guarantee 100% bit-identical sequences across Windows, Linux, and macOS.
127-
float operator()(std::mt19937& rng) {
128-
float u1, u2;
129-
do {
130-
uint32_t v1 = rng() >> 8;
131-
u1 = static_cast<float>(v1) / 16777216.0f;
132-
} while (u1 <= 0.0f);
133-
134-
uint32_t v2 = rng() >> 8;
135-
u2 = static_cast<float>(v2) / 16777216.0f;
136-
137-
float mag = stddev_ * std::sqrt(-2.0f * detail::portable_log(u1));
138-
return mean_ + mag * detail::portable_cos(6.28318530717958647692f * u2);
139-
}
140-
141-
private:
142-
float mean_;
143-
float stddev_;
144-
};
145-
14653
} // namespace deglib::random

cpp/test/src/regression/builder/test_l2_builder_regression.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST(DeglibBuilderRegressionL2, Benchmark_LowLID)
1717

1818
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
1919

20-
run_regression_test("LowLID", deglib::Metric::L2, 27000.0, 9.3, 0.971,
20+
run_regression_test("LowLID", deglib::Metric::L2, 20000.0, 14, 0.971,
2121
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
2222
deglib::distances::fp32_l2::L2Float{}, 100,
2323
deglib::builder::OptimizationTarget::LowLID);
@@ -36,7 +36,7 @@ TEST(DeglibBuilderRegressionL2, Benchmark_HighLID)
3636

3737
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
3838

39-
run_regression_test("HighLID", deglib::Metric::L2, 16000.0, 10.0, 0.96,
39+
run_regression_test("HighLID", deglib::Metric::L2, 12000.0, 14.4, 0.96,
4040
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
4141
deglib::distances::fp32_l2::L2Float{}, 100,
4242
deglib::builder::OptimizationTarget::HighLID);
@@ -55,7 +55,7 @@ TEST(DeglibBuilderRegressionL2, Benchmark_StreamingData)
5555

5656
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
5757

58-
run_regression_test("StreamingData", deglib::Metric::L2, 24000.0, 23.8, 0.91,
58+
run_regression_test("StreamingData", deglib::Metric::L2, 16000.0, 30, 0.91,
5959
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
6060
deglib::distances::fp32_l2::L2Float{}, 100,
6161
deglib::builder::OptimizationTarget::StreamingData);

cpp/test/src/regression/metric/test_innerproduct_regression.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST(DeglibRegressionIP, Benchmark_AVX512_16Ext)
1717

1818
auto gt_data = compute_groundtruth_innerproduct(base_data, base_count, query_data, query_count, dim, 10);
1919

20-
run_regression_test("AVX512_16Ext", deglib::Metric::InnerProduct, 18000.0, 10.3, 0.78,
20+
run_regression_test("AVX512_16Ext", deglib::Metric::InnerProduct, 38000.0, 4.5, 0.866,
2121
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
2222
deglib::distances::fp32_ip::InnerProductFloat16Ext_AVX512{}, 50);
2323
#else
@@ -42,7 +42,7 @@ TEST(DeglibRegressionIP, Benchmark_AVX2_16Ext)
4242

4343
auto gt_data = compute_groundtruth_innerproduct(base_data, base_count, query_data, query_count, dim, 10);
4444

45-
run_regression_test("AVX2_16Ext", deglib::Metric::InnerProduct, 18000.0, 10.3, 0.78,
45+
run_regression_test("AVX2_16Ext", deglib::Metric::InnerProduct, 38000.0, 4.5, 0.866,
4646
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
4747
deglib::distances::fp32_ip::InnerProductFloat16Ext_AVX2{}, 50);
4848
#else
@@ -67,7 +67,7 @@ TEST(DeglibRegressionIP, Benchmark_SSE_16Ext)
6767

6868
auto gt_data = compute_groundtruth_innerproduct(base_data, base_count, query_data, query_count, dim, 10);
6969

70-
run_regression_test("SSE_16Ext", deglib::Metric::InnerProduct, 16000.0, 11.8, 0.81,
70+
run_regression_test("SSE_16Ext", deglib::Metric::InnerProduct, 33000.0, 5.0, 0.866,
7171
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
7272
deglib::distances::fp32_ip::InnerProductFloat16Ext_SSE{}, 50);
7373
#else
@@ -88,7 +88,7 @@ TEST(DeglibRegressionIP, Benchmark_Scalar)
8888

8989
auto gt_data = compute_groundtruth_innerproduct(base_data, base_count, query_data, query_count, dim, 10);
9090

91-
run_regression_test("Scalar", deglib::Metric::InnerProduct, 10000.0, 20.8, 0.83,
91+
run_regression_test("Scalar", deglib::Metric::InnerProduct, 18000.0, 9.8, 0.867,
9292
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
9393
deglib::distances::fp32_ip::InnerProductFloat{}, 50);
9494
}

cpp/test/src/regression/metric/test_l2_regression.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST(DeglibRegressionL2, Benchmark_AVX512_16Ext)
1717

1818
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
1919

20-
run_regression_test("AVX512_16Ext", deglib::Metric::L2, 42000.0, 6.0, 0.866,
20+
run_regression_test("AVX512_16Ext", deglib::Metric::L2, 46000.0, 6.0, 0.961,
2121
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
2222
deglib::distances::fp32_l2::L2Float16Ext_AVX512{}, 100);
2323
#else
@@ -42,7 +42,7 @@ TEST(DeglibRegressionL2, Benchmark_AVX2_16Ext)
4242

4343
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
4444

45-
run_regression_test("AVX2_16Ext", deglib::Metric::L2, 39000.0, 6.2, 0.866,
45+
run_regression_test("AVX2_16Ext", deglib::Metric::L2, 43000.0, 6.0, 0.961,
4646
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
4747
deglib::distances::fp32_l2::L2Float16Ext_AVX2{}, 100);
4848
#else
@@ -67,7 +67,7 @@ TEST(DeglibRegressionL2, Benchmark_SSE_16Ext)
6767

6868
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
6969

70-
run_regression_test("SSE_16Ext", deglib::Metric::L2, 35000.0, 7.0, 0.866,
70+
run_regression_test("SSE_16Ext", deglib::Metric::L2, 40000.0, 6.9, 0.961,
7171
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
7272
deglib::distances::fp32_l2::L2Float16Ext_SSE{}, 100);
7373
#else
@@ -88,7 +88,7 @@ TEST(DeglibRegressionL2, Benchmark_Scalar)
8888

8989
auto gt_data = compute_groundtruth_l2(base_data, base_count, query_data, query_count, dim, 10);
9090

91-
run_regression_test("Scalar", deglib::Metric::L2, 22000.0, 12.5, 0.867,
91+
run_regression_test("Scalar", deglib::Metric::L2, 21000.0, 14.0, 0.971,
9292
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
9393
deglib::distances::fp32_l2::L2Float{}, 100);
9494
}

cpp/test/src/regression/metric/test_l2_uint8_regression.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST(DeglibRegressionL2Uint8, Benchmark_AVX512_Ext32)
1717

1818
auto gt_data = compute_groundtruth_l2_uint8(base_data, base_count, query_data, query_count, dim, 10);
1919

20-
run_regression_test("AVX512_Ext32", deglib::Metric::L2_Uint8, 78000.0, 4.6, 0.99,
20+
run_regression_test("AVX512_Ext32", deglib::Metric::L2_Uint8, 58000.0, 4.8, 0.99,
2121
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
2222
deglib::distances::uint8_l2::L2Uint8Ext32_AVX512{}, 500);
2323
#else
@@ -42,7 +42,7 @@ TEST(DeglibRegressionL2Uint8, Benchmark_AVX2_Ext32)
4242

4343
auto gt_data = compute_groundtruth_l2_uint8(base_data, base_count, query_data, query_count, dim, 10);
4444

45-
run_regression_test("AVX2_Ext32", deglib::Metric::L2_Uint8, 78000.0, 4.6, 0.99,
45+
run_regression_test("AVX2_Ext32", deglib::Metric::L2_Uint8, 58000.0, 4.8, 0.99,
4646
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
4747
deglib::distances::uint8_l2::L2Uint8Ext32_AVX2{}, 500);
4848
#else
@@ -67,7 +67,7 @@ TEST(DeglibRegressionL2Uint8, Benchmark_SSE_Ext32)
6767

6868
auto gt_data = compute_groundtruth_l2_uint8(base_data, base_count, query_data, query_count, dim, 10);
6969

70-
run_regression_test("SSE_Ext32", deglib::Metric::L2_Uint8, 74000.0, 5.1, 0.99,
70+
run_regression_test("SSE_Ext32", deglib::Metric::L2_Uint8, 54000.0, 5.3, 0.99,
7171
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
7272
deglib::distances::uint8_l2::L2Uint8Ext32_SSE{}, 500);
7373
#else
@@ -88,7 +88,7 @@ TEST(DeglibRegressionL2Uint8, Benchmark_Scalar)
8888

8989
auto gt_data = compute_groundtruth_l2_uint8(base_data, base_count, query_data, query_count, dim, 10);
9090

91-
run_regression_test("Scalar", deglib::Metric::L2_Uint8, 67000.0, 5.5, 0.99,
91+
run_regression_test("Scalar", deglib::Metric::L2_Uint8, 50000.0, 5.8, 0.99,
9292
base_data.data(), query_data.data(), base_count, query_count, dim, gt_data,
9393
deglib::distances::uint8_l2::L2Uint8{}, 500);
9494
}

0 commit comments

Comments
 (0)