@@ -3156,6 +3156,75 @@ TEST(SVSTest, scalar_quantization_query) {
31563156 }
31573157}
31583158
3159+ #if defined(__linux__) && defined(__x86_64__)
3160+ TEST (SVSTest, compute_distance) {
3161+ // Test svs::distance computation for custom data allocations and alignments
3162+ constexpr size_t dim = 4 ;
3163+
3164+ // get system pagesize
3165+ size_t page_size = sysconf (_SC_PAGESIZE);
3166+ ASSERT_GT (page_size, 16 );
3167+
3168+ // Allocate two consecutive pages: one for data, one as a guard (inaccessible)
3169+ uint8_t *raw_a = (uint8_t *)mmap (nullptr , 2 * page_size, PROT_READ | PROT_WRITE,
3170+ MAP_PRIVATE | MAP_ANONYMOUS, -1 , 0 );
3171+ ASSERT_NE (raw_a, MAP_FAILED);
3172+ // Protect the second page to prevent access
3173+ ASSERT_EQ (mprotect (raw_a + page_size, page_size, PROT_NONE), 0 );
3174+
3175+ // Allocate the second buffer
3176+ uint8_t *raw_b = (uint8_t *)mmap (nullptr , 2 * page_size, PROT_READ | PROT_WRITE,
3177+ MAP_PRIVATE | MAP_ANONYMOUS, -1 , 0 );
3178+ ASSERT_NE (raw_b, MAP_FAILED);
3179+ // Protect the second page to prevent access
3180+ ASSERT_EQ (mprotect (raw_b + page_size, page_size, PROT_NONE), 0 );
3181+
3182+ // use last bytes of page for data
3183+ // Note: Accessing above 'dim' should trigger Memory Access Error.
3184+ constexpr size_t data_size = dim * sizeof (float );
3185+ float *a = reinterpret_cast <float *>(raw_a + page_size - data_size);
3186+ float *b = reinterpret_cast <float *>(raw_b + page_size - data_size);
3187+
3188+ std::iota (a, a + dim, 1 .f );
3189+ std::iota (b, b + dim, 2 .f );
3190+
3191+ // Verify default implementation
3192+ auto dist_l2 = svs::distance::compute (svs::DistanceL2{}, std::span (a, dim), std::span (b, dim));
3193+ EXPECT_GT (dist_l2, 0.0 );
3194+ auto dist_ip = svs::distance::compute (svs::DistanceIP{}, std::span (a, dim), std::span (b, dim));
3195+ EXPECT_GT (dist_ip, 0.0 );
3196+
3197+ // Verify AVX2 and AVX512 implementations
3198+ if (svs::detail::avx_runtime_flags.is_avx2_supported ()) {
3199+ // AVX2 implementations
3200+ auto dist_l2_avx2 = svs::distance::
3201+ L2Impl<svs::Dynamic, float , float , svs::distance::AVX_AVAILABILITY::AVX2>::compute (
3202+ a, b, svs::lib::MaybeStatic (dim));
3203+ auto dist_ip_avx2 = svs::distance::
3204+ IPImpl<svs::Dynamic, float , float , svs::distance::AVX_AVAILABILITY::AVX2>::compute (
3205+ a, b, svs::lib::MaybeStatic (dim));
3206+ EXPECT_DOUBLE_EQ (dist_l2, dist_l2_avx2);
3207+ EXPECT_DOUBLE_EQ (dist_ip, dist_ip_avx2);
3208+ }
3209+
3210+ if (svs::detail::avx_runtime_flags.is_avx512f_supported ()) {
3211+ // AVX512 implementations
3212+ auto dist_l2_avx512 = svs::distance::
3213+ L2Impl<svs::Dynamic, float , float , svs::distance::AVX_AVAILABILITY::AVX512>::compute (
3214+ a, b, svs::lib::MaybeStatic (dim));
3215+ auto dist_ip_avx512 = svs::distance::
3216+ IPImpl<svs::Dynamic, float , float , svs::distance::AVX_AVAILABILITY::AVX512>::compute (
3217+ a, b, svs::lib::MaybeStatic (dim));
3218+ EXPECT_DOUBLE_EQ (dist_l2, dist_l2_avx512);
3219+ EXPECT_DOUBLE_EQ (dist_ip, dist_ip_avx512);
3220+ }
3221+
3222+ // unmap pages
3223+ munmap (raw_a, 2 * page_size);
3224+ munmap (raw_b, 2 * page_size);
3225+ }
3226+ #endif // defined(__linux__) && defined(__x86_64__)
3227+
31593228#else // HAVE_SVS
31603229
31613230TEST (SVSTest, svs_not_supported) {
0 commit comments