From cec5702b0b1c31f242b9d35d5f193b0d80ccd9dc Mon Sep 17 00:00:00 2001 From: Weixiang Hong Date: Sat, 10 Oct 2026 01:42:32 -0700 Subject: [PATCH] DD: give fvec_L2sqr_ny_nearest_y_transposed_D internal linkage (#5720) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5720 `fvec_L2sqr_ny_nearest_y_transposed_D` is a template defined at namespace scope in both `distances_avx2.cpp` (`-mavx2`) and `distances_avx512.cpp` (`-mavx512*`), with the same signature, so both TUs emit the same weak symbols and the linker keeps one copy per `DIM`. Whichever copy it keeps is used by both levels. In a current DD build the AVX512 copies of `D<1>`, `D<2>`, `D<4>` were kept (72-95 `zmm` instructions each) and the AVX2 copy of `D<8>`, so the AVX512 path ran AVX2 code for `D<8>`. Nothing on the AVX2 path calls `D<1/2/4>` today, so there is no crash now; but a link that keeps the AVX512 `D<8>` would make the AVX2 path execute AVX512 instructions and raise SIGILL on CPUs without AVX512 (e.g. AMD Milan). Same class as D124399620 (`PQCodeDistanceScalar`), found by scanning the DD binary for functions that contain `zmm` instructions but are not marked as an AVX512 level and have external linkage. The only other hits were `DCBF16_IP` / `DCBF16_L2`, which are defined only in `sq-avx512-spr.cpp` and reached only through AVX512_SPR dispatch. Fix: put the template in an anonymous namespace in each TU, so each level keeps its own copy. Reviewed By: mnorris11 Differential Revision: D124411046 fbshipit-source-id: 9165061e67f1476ff038c173aa837f7e0959e920 --- faiss/utils/simd_impl/distances_avx2.cpp | 7 +++++++ faiss/utils/simd_impl/distances_avx512.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/faiss/utils/simd_impl/distances_avx2.cpp b/faiss/utils/simd_impl/distances_avx2.cpp index 1276e57f2..0537ef09f 100644 --- a/faiss/utils/simd_impl/distances_avx2.cpp +++ b/faiss/utils/simd_impl/distances_avx2.cpp @@ -1060,6 +1060,11 @@ size_t fvec_L2sqr_ny_nearest( &fvec_L2sqr_ny_nearest_D8); } +// Internal linkage: the same template is compiled with other -m flags in +// the other per-SIMD distances TU, and a shared symbol would let the linker +// hand one level the other's code. +namespace { + template size_t fvec_L2sqr_ny_nearest_y_transposed_D( float* /*distances_tmp_buffer*/, @@ -1176,6 +1181,8 @@ size_t fvec_L2sqr_ny_nearest_y_transposed_D( return current_min_index; } +} // namespace + template <> size_t fvec_L2sqr_ny_nearest_y_transposed( float* distances_tmp_buffer, diff --git a/faiss/utils/simd_impl/distances_avx512.cpp b/faiss/utils/simd_impl/distances_avx512.cpp index a13205da2..5aaa59194 100644 --- a/faiss/utils/simd_impl/distances_avx512.cpp +++ b/faiss/utils/simd_impl/distances_avx512.cpp @@ -1024,6 +1024,11 @@ size_t fvec_L2sqr_ny_nearest( &fvec_L2sqr_ny_nearest_D8); } +// Internal linkage: the same template is compiled with other -m flags in +// the other per-SIMD distances TU, and a shared symbol would let the linker +// hand one level the other's code. +namespace { + template size_t fvec_L2sqr_ny_nearest_y_transposed_D( float* /* distances_tmp_buffer */, @@ -1137,6 +1142,8 @@ size_t fvec_L2sqr_ny_nearest_y_transposed_D( return current_min_index; } +} // namespace + template <> size_t fvec_L2sqr_ny_nearest_y_transposed( float* distances_tmp_buffer,