Skip to content

Fix flaky IVF/Refine Panorama kNN tests under AVX512_SPR dispatch#5420

Closed
alibeklfc wants to merge 3 commits into
facebookresearch:mainfrom
alibeklfc:export-D111028010
Closed

Fix flaky IVF/Refine Panorama kNN tests under AVX512_SPR dispatch#5420
alibeklfc wants to merge 3 commits into
facebookresearch:mainfrom
alibeklfc:export-D111028010

Conversation

@alibeklfc

Copy link
Copy Markdown
Contributor

Summary:
D110092203 fixed the same flakiness in test_flat_panorama.py (36% flake rate
on AVX512_SPR dispatch). The root cause — brittle overlap_rate ID comparison
that breaks when SIMD dispatch changes float reduction order and reorders
near-tied neighbors — is identical in test_ivf_flat_panorama.py and
test_refine_panorama.py, which both use for_all_simd_levels.

Replace assert_search_results_equal in both files:

  • Remove overlap_rate = np.mean(I_regular == I_panorama) and assertGreater
  • Add check_ref_knn_with_draws for tie-aware set comparison
  • Relax atol 1e-7 -> 1e-4 (consistent with the flat_panorama fix)
  • Pass D_regular as both distance arrays to check_ref_knn_with_draws;
    distances already verified by assert_allclose(atol=atol), and using
    D_regular for tie-grouping avoids atol=0 failures on near-zero L2
    distances (e.g., test_ratio_dims_scanned exact-match scenario)

assert_range_results_equal in test_ivf_flat_panorama.py is left unchanged;
IVF range search has inherently approximate recall (nprobe), so the
intersection-based overlap check there is intentionally looser.

Differential Revision: D111028010

…entroids

Summary:
`ResidualQuantizer::compute_codes_add_centroids` dispatches on `use_beam_LUT`
with an if/else-if chain covering values 0 (lut0, direct L2 residuals) and 1
(lut1, LUT-accelerated encoding). Before this diff, any other value fell
through silently: the chunk loop executed but wrote nothing to `codes_out`,
leaving the output buffer uninitialized with no exception, no return code, and
no warning.

`use_beam_LUT` is a public `int` field with no enum constraint. A caller that
sets it to 2 — expecting a future mode, or by mistake — would get silently
garbage-filled codes from all index types backed by ResidualQuantizer (RQ, PRQ,
IVF-RQ, IVF-PRQ) with no way to detect the failure.

Fix: Add `FAISS_THROW_IF_NOT_FMT` validation **before the per-batch loop**,
checking `use_beam_LUT == 0 || use_beam_LUT == 1`. Placing the guard at method
entry (matching the pattern at line 437) ensures it fires for all n — including
n=0, where the loop body never executes. The validation uses the correct
FAISS_THROW_IF_NOT_FMT idiom (condition expression as first argument, not
`false`) so the error message is clean: "use_beam_LUT=X is not supported (must
be 0 or 1)".

Additionally:
- Updated the `use_beam_LUT` field comment in `ResidualQuantizer.h` to document
  valid values (0 and 1) and the no-other-value constraint.
- Updated the corresponding `__init__.pyi` stub comment to match, so Python IDE
  users see the constraint at the point of declaration.

Differential Revision: D110754282
Summary:
D110175030 (June 30, unpublished) replaced 1e20 distance argmin sentinels
in six sites but was never published and remained as an orphaned local commit.
This diff completes the sweep with all nine remaining non-HUGE_VALF sentinels
across the entire faiss codebase.

Sites fixed:

1. fvec_madd_and_argmin<SIMDLevel::NONE> (distances_simd.cpp:156): float
   vmin = 1e20 -> HUGE_VALF. Scalar fallback used on devservers and in CI.

2. fvec_madd_and_argmin_sse_ref (distances_sse-inl.h:313): __m128 vmin4 =
   _mm_set_ps1(1e20) -> _mm_set_ps1(HUGE_VALF). Called by both the AVX2
   and AVX-512 dispatch paths for fvec_madd_and_argmin.

3. fvec_madd_and_argmin<SIMDLevel::ARM_NEON> (distances_aarch64.cpp:109):
   vdupq_n_f32(1e20) -> vdupq_n_f32(HUGE_VALF).

4. fvec_madd_and_argmin<SIMDLevel::ARM_SVE> (distances_arm_sve.cpp:106):
   float vmin = 1e20 -> HUGE_VALF.

5. ProductQuantizer::compute_code_from_distance_table (ProductQuantizer.cpp:
   340): float mindis = 1e20 -> HUGE_VALF. Inner loop selects nearest PQ
   centroid from precomputed L2 distance table; wrong sentinel returns code 0
   instead of the true argmin for any LUT distance above 1e20.

6. EnumeratedVectors::find_nn (lattice_Zn.cpp:303): distances[i] = -1e20 ->
   -HUGE_VALF. Tracks maximum inner product per query; symmetric to the L2
   argmin case.

7. ranklist_handle_ties (utils.cpp:279): float prev_dis = -1e38 ->
   -HUGE_VALF. Used as a comparison seed for tie-group detection. The -1e38
   sentinel is wrong for any actual IP distance below -1e38 (possible with
   large unnormalized embeddings); -HUGE_VALF is the correct lower bound.

8-9. HeapWithBucketsGenericCMaxFloat and HeapWithBucketsCMaxFloat bucket
     initialization (approx_topk/generic.h:75, approx_topk/simdlib256-inl.h:
     54): std::numeric_limits<float>::max() (FLT_MAX = 3.4e38) -> HUGE_VALF
     (+Inf). Empty buckets initialized with FLT_MAX instead of HUGE_VALF pass
     the CMax::cmp2 gate (HUGE_VALF > FLT_MAX) and get pushed to the heap as
     spurious (FLT_MAX, 0) entries when k exceeds the number of filled buckets.
     HUGE_VALF is not less than itself so the gate rejects empty buckets.

All other sentinel initializations in faiss already use HUGE_VALF. The 1e20
value fails for any distance in [1e20, +Inf), which can occur with unnormalized
high-dimensional embeddings (d=2048, L2 norms near sqrt(2048) * large_value).

Differential Revision: D110878686
Summary:
D110092203 fixed the same flakiness in test_flat_panorama.py (36% flake rate
on AVX512_SPR dispatch). The root cause — brittle overlap_rate ID comparison
that breaks when SIMD dispatch changes float reduction order and reorders
near-tied neighbors — is identical in test_ivf_flat_panorama.py and
test_refine_panorama.py, which both use for_all_simd_levels.

Replace assert_search_results_equal in both files:
  - Remove overlap_rate = np.mean(I_regular == I_panorama) and assertGreater
  - Add check_ref_knn_with_draws for tie-aware set comparison
  - Relax atol 1e-7 -> 1e-4 (consistent with the flat_panorama fix)
  - Pass D_regular as both distance arrays to check_ref_knn_with_draws;
    distances already verified by assert_allclose(atol=atol), and using
    D_regular for tie-grouping avoids atol=0 failures on near-zero L2
    distances (e.g., test_ratio_dims_scanned exact-match scenario)

assert_range_results_equal in test_ivf_flat_panorama.py is left unchanged;
IVF range search has inherently approximate recall (nprobe), so the
intersection-based overlap check there is intentionally looser.

Differential Revision: D111028010
@meta-cla meta-cla Bot added the CLA Signed label Jul 14, 2026
@meta-codesync

meta-codesync Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@alibeklfc has exported this pull request. If you are a Meta employee, you can view the originating Diff in D111028010.

@meta-codesync

meta-codesync Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This pull request has been merged in ba6af9f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant