Skip to content

Commit bc7daa8

Browse files
committed
fix(ci): resolve macOS bit-exactness failure and Linux AVX-512 compile error
- **Linux (GCC)**: Include `avx512vpopcntdq` in `DEGLIB_TARGET_AVX512` definition so GCC allows inlining `_mm512_popcnt_epi64` into AVX-512 distance methods. - **macOS (Clang/libc++)**: Add index-based tie-breaking (`a.first != b.first ? a.first < b.first : a.second < b.second`) in `quantize_single` and `quantize_batch` calls to `std::nth_element` in `evp_quantize.h`. This guarantees identical top-K element partitioning regardless of standard library implementation differences.
1 parent 2e9f95e commit bc7daa8

3 files changed

Lines changed: 16 additions & 8 deletions

File tree

cpp/deglib/include/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
// Compile methods with this attribute for AVX-512 functions on GCC/Clang
1111
#if defined(DEGLIB_X86) && (defined(__GNUC__) || defined(__clang__))
12-
#define DEGLIB_TARGET_AVX512 __attribute__((target("avx512f,avx512dq,avx512bw,fma")))
12+
#define DEGLIB_TARGET_AVX512 __attribute__((target("avx512f,avx512dq,avx512bw,avx512vpopcntdq,fma")))
1313
#else
1414
#define DEGLIB_TARGET_AVX512
1515
#endif

cpp/deglib/include/quantization/evp_quantize.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ inline std::vector<std::byte> quantize_single(const float* embedding, uint32_t d
4343
abs_vals[i] = {std::abs(embedding[i]), i};
4444
}
4545
std::nth_element(abs_vals.begin(), abs_vals.begin() + (dim - non_zeros), abs_vals.end(),
46-
[](const auto& a, const auto& b) { return a.first < b.first; });
46+
[](const auto& a, const auto& b) {
47+
return a.first != b.first ? a.first < b.first : a.second < b.second;
48+
});
4749

4850
std::vector<uint8_t> is_top(dim, 0);
4951
for (uint32_t j = dim - non_zeros; j < dim; ++j) {
@@ -128,7 +130,9 @@ inline std::vector<std::byte> quantize_batch(const float* data, size_t count, ui
128130
abs_vals[k] = {std::abs(emb[k]), k};
129131
}
130132
std::nth_element(abs_vals.begin(), abs_vals.begin() + (dim - non_zeros), abs_vals.end(),
131-
[](const auto& a, const auto& b) { return a.first < b.first; });
133+
[](const auto& a, const auto& b) {
134+
return a.first != b.first ? a.first < b.first : a.second < b.second;
135+
});
132136

133137
is_top.assign(dim, 0);
134138
for (uint32_t j = dim - non_zeros; j < dim; ++j) {
@@ -243,7 +247,9 @@ inline std::vector<std::byte> quantize_batch(const uint16_t* data, size_t count,
243247
abs_vals[k] = {static_cast<uint16_t>(emb[k] & 0x7FFFu), k};
244248
}
245249
std::nth_element(abs_vals.begin(), abs_vals.begin() + (dim - non_zeros), abs_vals.end(),
246-
[](const auto& a, const auto& b) { return a.first < b.first; });
250+
[](const auto& a, const auto& b) {
251+
return a.first != b.first ? a.first < b.first : a.second < b.second;
252+
});
247253

248254
is_top.assign(dim, 0);
249255
for (uint32_t j = dim - non_zeros; j < dim; ++j) {
@@ -334,7 +340,9 @@ inline std::vector<std::byte> quantize_batch(const std::vector<std::vector<std::
334340
abs_vals[k] = {static_cast<uint16_t>(emb[k] & 0x7FFFu), k};
335341
}
336342
std::nth_element(abs_vals.begin(), abs_vals.begin() + (dim - non_zeros), abs_vals.end(),
337-
[](const auto& a, const auto& b) { return a.first < b.first; });
343+
[](const auto& a, const auto& b) {
344+
return a.first != b.first ? a.first < b.first : a.second < b.second;
345+
});
338346

339347
is_top.assign(dim, 0);
340348
for (uint32_t j = dim - non_zeros; j < dim; ++j) {

cpp/test/src/integration/test_builder_integration.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,9 @@ TEST(DeglibBuilderIntegration, EvpDatasetBitExactness)
354354

355355
// Hardcoded expected hashes computed on Windows (10k dataset)
356356
// Checksum verification ensures 100% bit-exact dataset generation and groundtruth across OS/compilers.
357-
EXPECT_EQ(base_hash, 0xe8de72f535d6e07dULL) << "base_evp checksum mismatch across platforms!";
358-
EXPECT_EQ(query_hash, 0xccb8e62c3224256fULL) << "query_evp checksum mismatch across platforms!";
359-
EXPECT_EQ(gt_evp_hash, 0xc01f476e432ca611ULL) << "gt_evp checksum mismatch across platforms!";
357+
EXPECT_EQ(base_hash, 0x524834ef619bf297ULL) << "base_evp checksum mismatch across platforms!";
358+
EXPECT_EQ(query_hash, 0x942208b0d125a817ULL) << "query_evp checksum mismatch across platforms!";
359+
EXPECT_EQ(gt_evp_hash, 0x6c0ad164a1cbbd8dULL) << "gt_evp checksum mismatch across platforms!";
360360
}
361361

362362
TEST(DeglibBuilderIntegration, EVPInnerProduct_Recall)

0 commit comments

Comments
 (0)