From f4338ade1bfae983ff03164f8ef53921b193f46c Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Wed, 22 Apr 2026 02:28:03 -0700 Subject: [PATCH] Parameterize existing tests with @for_all_simd_levels (#5134) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5134 Expand DD test coverage by applying for_all_simd_levels to existing test classes that exercise DD-dispatched code paths but were previously pinned to a single SIMD level. This is the "mega decorator" diff from the DD test coverage gaps plan -- pure decorator additions, no new test logic. Follow-up diffs add new test files and numerical cross-level assertions for gaps the decorator alone cannot close. Classes decorated (grouped by area): * Binary Hamming non-IVF: TestRange and TestKnn in test_binary_hashindex.py; TestBinarySearchParams in test_binary_search_params.py; TestIndexBinaryFromFloat in test_index_binary_from_float.py; TestSpectralHash in test_index_accuracy.py. * IVFPQ / search: EvalIVFPQAccuracy in test_index.py; TestSelector and TestSearchParams in test_search_params.py. * Flat / refine / Panorama: TestIndexFlat, TestIndexFlatL2, TestIndexFlatL2Panorama, TestScalarQuantizer in test_index.py; TestDistanceComputer, TestIndexRefineSearchParams, TestIndexRefineRangeSearch in test_refine.py; TestIndexRefinePanorama, TestIndexFlatPanorama, TestIndexHNSWFlatPanorama, TestIndexIVFFlatPanorama in their respective files. * Quantizer encode: TestResidualQuantizer, TestIndexResidualQuantizerSearch in test_residual_quantizer.py; TestComponents, TestLocalSearchQuantizer in test_local_search_quantizer.py. * Fast scan: TestFastScanFiltering, TestBlockSkipConsistency, TestFastScanRangeSearchFilter in test_fastscan_filter.py. * Broader index tests (search-exercising classes only): TestParameterSpace in test_autotune.py; TestSpectralHash in test_factory.py; TestMerge1, TestMerge2, TestRemoveFastScan in test_merge_index.py. BUCK changes move decorated tests from the legacy-listing lists to the simd_levels lists (which use supports_static_listing = False, required for dynamic class name generation), and add the new entries test_binary_search_params, test_fastscan_filter, test_refine_panorama, test_hnsw_panorama. ___ overriding_review_checks_triggers_an_audit_and_retroactive_review Oncall Short Name: fair_umami_cluster Differential Revision: D101822335 fbshipit-source-id: 9a432c6d6bee201c3731713226405a8c8ecebbe6 --- tests/test_autotune.py | 3 +++ tests/test_binary_hashindex.py | 4 +++- tests/test_binary_search_params.py | 3 +++ tests/test_factory.py | 2 ++ tests/test_fastscan_filter.py | 4 ++++ tests/test_flat_panorama.py | 2 ++ tests/test_hnsw_panorama.py | 2 ++ tests/test_index.py | 7 ++++++- tests/test_index_accuracy.py | 4 +++- tests/test_index_binary_from_float.py | 3 +++ tests/test_ivf_flat_panorama.py | 2 ++ tests/test_local_search_quantizer.py | 3 +++ tests/test_merge_index.py | 5 ++++- tests/test_refine.py | 4 ++++ tests/test_refine_panorama.py | 2 ++ tests/test_residual_quantizer.py | 3 +++ tests/test_search_params.py | 3 +++ 17 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/test_autotune.py b/tests/test_autotune.py index e32d0cb24..9cb830aa7 100644 --- a/tests/test_autotune.py +++ b/tests/test_autotune.py @@ -7,7 +7,10 @@ import unittest import faiss +from common_faiss_tests import for_all_simd_levels + +@for_all_simd_levels class TestParameterSpace(unittest.TestCase): def test_nprobe(self): diff --git a/tests/test_binary_hashindex.py b/tests/test_binary_hashindex.py index d1aa66e66..1ee50623b 100644 --- a/tests/test_binary_hashindex.py +++ b/tests/test_binary_hashindex.py @@ -7,7 +7,7 @@ import unittest import numpy as np import faiss -from common_faiss_tests import make_binary_dataset +from common_faiss_tests import for_all_simd_levels, make_binary_dataset def bitvec_shuffle(a, order): @@ -42,6 +42,7 @@ class TestSmallFuncs(unittest.TestCase): np.testing.assert_array_equal(x, z) +@for_all_simd_levels class TestRange(unittest.TestCase): def test_hash(self): @@ -122,6 +123,7 @@ class TestRange(unittest.TestCase): self.assertTrue(np.all(nfound[1:] >= nfound[:-1])) +@for_all_simd_levels class TestKnn(unittest.TestCase): def test_hash_and_multihash(self): diff --git a/tests/test_binary_search_params.py b/tests/test_binary_search_params.py index aa31a2e16..87733c3ae 100644 --- a/tests/test_binary_search_params.py +++ b/tests/test_binary_search_params.py @@ -8,7 +8,10 @@ import unittest import numpy as np import faiss +from common_faiss_tests import for_all_simd_levels + +@for_all_simd_levels class TestBinarySearchParams(unittest.TestCase): def do_test_with_param( diff --git a/tests/test_factory.py b/tests/test_factory.py index 2246eb8c1..30c35fb70 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -9,6 +9,7 @@ import unittest import gc import faiss +from common_faiss_tests import for_all_simd_levels from faiss.contrib import factory_tools from faiss.contrib import datasets @@ -321,6 +322,7 @@ class TestAdditive(unittest.TestCase): faiss.AdditiveQuantizer.ST_norm_qint8) +@for_all_simd_levels class TestSpectralHash(unittest.TestCase): def test_sh(self): diff --git a/tests/test_fastscan_filter.py b/tests/test_fastscan_filter.py index 2f6b9f44c..3c78a65e0 100644 --- a/tests/test_fastscan_filter.py +++ b/tests/test_fastscan_filter.py @@ -8,11 +8,13 @@ import unittest import numpy as np import faiss +from common_faiss_tests import for_all_simd_levels from faiss.contrib import datasets faiss.omp_set_num_threads(4) +@for_all_simd_levels class TestFastScanFiltering(unittest.TestCase): """ Test IDSelector filtering on IVF fast_scan indexes. @@ -149,6 +151,7 @@ class TestFastScanFiltering(unittest.TestCase): self.do_test_filter("IVF32,PQ4x4fs", "batch", nb=150) +@for_all_simd_levels class TestBlockSkipConsistency(unittest.TestCase): """ Test that block-skip filtering produces consistent results @@ -296,6 +299,7 @@ class TestBlockSkipConsistency(unittest.TestCase): self.assertIn(idx, allowed) +@for_all_simd_levels class TestFastScanRangeSearchFilter(unittest.TestCase): """Test range_search with IDSelector on fastscan IVF indexes.""" diff --git a/tests/test_flat_panorama.py b/tests/test_flat_panorama.py index 8e2378a66..05ba0d1ec 100644 --- a/tests/test_flat_panorama.py +++ b/tests/test_flat_panorama.py @@ -18,9 +18,11 @@ import unittest import faiss import numpy as np +from common_faiss_tests import for_all_simd_levels from faiss.contrib.datasets import SyntheticDataset +@for_all_simd_levels class TestIndexFlatPanorama(unittest.TestCase): """Test Suite for IndexFlatPanorama.""" diff --git a/tests/test_hnsw_panorama.py b/tests/test_hnsw_panorama.py index 78605ea0d..04a95e784 100644 --- a/tests/test_hnsw_panorama.py +++ b/tests/test_hnsw_panorama.py @@ -19,9 +19,11 @@ import os import numpy as np import faiss +from common_faiss_tests import for_all_simd_levels from faiss.contrib.datasets import SyntheticDataset +@for_all_simd_levels class TestIndexHNSWFlatPanorama(unittest.TestCase): """Test Suite for IndexHNSWFlatPanorama.""" diff --git a/tests/test_index.py b/tests/test_index.py index d6a036667..e413e9726 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -12,7 +12,7 @@ import unittest import faiss import re -from common_faiss_tests import get_dataset, get_dataset_2 +from common_faiss_tests import for_all_simd_levels, get_dataset, get_dataset_2 from faiss.contrib.evaluation import check_ref_knn_with_draws @@ -23,6 +23,7 @@ class TestModuleInterface(unittest.TestCase): assert re.match('^\\d+\\.\\d+\\.\\d+$', faiss.__version__) +@for_all_simd_levels class TestIndexFlat(unittest.TestCase): def do_test(self, nq, metric_type=faiss.METRIC_L2, k=10): @@ -110,6 +111,7 @@ class TestIndexFlat(unittest.TestCase): self.do_test(200, faiss.METRIC_INNER_PRODUCT, k=150) +@for_all_simd_levels class TestIndexFlatL2(unittest.TestCase): def test_indexflat_l2_sync_norms_1(self): d = 32 @@ -145,6 +147,7 @@ class TestIndexFlatL2(unittest.TestCase): np.testing.assert_equal(D3, D1) +@for_all_simd_levels class TestIndexFlatL2Panorama(unittest.TestCase): def test_indexflat_l2_panorama(self): d = 32 @@ -191,6 +194,7 @@ class TestIndexFlatL2Panorama(unittest.TestCase): ) +@for_all_simd_levels class EvalIVFPQAccuracy(unittest.TestCase): def test_IndexIVFPQ(self): @@ -343,6 +347,7 @@ class TestMultiIndexQuantizer(unittest.TestCase): self.assertEqual(np.abs(D1[:, :1] - D5[:, :1]).max(), 0) +@for_all_simd_levels class TestScalarQuantizer(unittest.TestCase): def test_4variants_ivf(self): diff --git a/tests/test_index_accuracy.py b/tests/test_index_accuracy.py index 1e69be611..21ce3d447 100644 --- a/tests/test_index_accuracy.py +++ b/tests/test_index_accuracy.py @@ -13,7 +13,8 @@ import faiss # translation of test_knn.lua import numpy as np -from common_faiss_tests import Randu10k, get_dataset_2, Randu10kUnbalanced +from common_faiss_tests import ( + for_all_simd_levels, get_dataset_2, Randu10k, Randu10kUnbalanced) ev = Randu10k() @@ -693,6 +694,7 @@ class TestRoundoff(unittest.TestCase): faiss.cvar.distance_compute_blas_threshold = saved_threshold +@for_all_simd_levels class TestSpectralHash(unittest.TestCase): # run on 2019-04-02 diff --git a/tests/test_index_binary_from_float.py b/tests/test_index_binary_from_float.py index 042937985..b2305262c 100644 --- a/tests/test_index_binary_from_float.py +++ b/tests/test_index_binary_from_float.py @@ -9,6 +9,8 @@ import numpy as np import unittest import faiss +from common_faiss_tests import for_all_simd_levels + def make_binary_dataset(d, nb, nt, nq): assert d % 8 == 0 @@ -24,6 +26,7 @@ def binary_to_float(x): return c8.astype('float32').reshape(n, d * 8) +@for_all_simd_levels class TestIndexBinaryFromFloat(unittest.TestCase): """Use a binary index backed by a float index""" diff --git a/tests/test_ivf_flat_panorama.py b/tests/test_ivf_flat_panorama.py index 6e0601c5a..c9f9f7dad 100644 --- a/tests/test_ivf_flat_panorama.py +++ b/tests/test_ivf_flat_panorama.py @@ -18,9 +18,11 @@ import unittest import faiss import numpy as np +from common_faiss_tests import for_all_simd_levels from faiss.contrib.datasets import SyntheticDataset +@for_all_simd_levels class TestIndexIVFFlatPanorama(unittest.TestCase): """Test Suite for IndexIVFFlatPanorama.""" diff --git a/tests/test_local_search_quantizer.py b/tests/test_local_search_quantizer.py index 76e76ee9b..4d2fd783d 100644 --- a/tests/test_local_search_quantizer.py +++ b/tests/test_local_search_quantizer.py @@ -13,6 +13,7 @@ import platform import faiss import unittest +from common_faiss_tests import for_all_simd_levels from faiss.contrib import datasets faiss.omp_set_num_threads(4) @@ -117,6 +118,7 @@ def icm_encode_ref(x, codebooks, codes): return codes +@for_all_simd_levels class TestComponents(unittest.TestCase): def test_decode(self): @@ -332,6 +334,7 @@ def eval_codec(q, xb): return ((xb - decoded) ** 2).sum() +@for_all_simd_levels class TestLocalSearchQuantizer(unittest.TestCase): def test_training(self): diff --git a/tests/test_merge_index.py b/tests/test_merge_index.py index 0fd0c058d..52750d65f 100644 --- a/tests/test_merge_index.py +++ b/tests/test_merge_index.py @@ -8,7 +8,7 @@ import faiss import numpy as np from faiss.contrib.datasets import SyntheticDataset -from common_faiss_tests import Randu10k +from common_faiss_tests import for_all_simd_levels, Randu10k ru = Randu10k() xb = ru.xb @@ -18,6 +18,7 @@ nb, d = xb.shape nq, d = xq.shape +@for_all_simd_levels class TestMerge1(unittest.TestCase): def make_index_for_merge(self, quant, index_type, master_index): ncent = 40 @@ -147,6 +148,7 @@ class TestMerge1(unittest.TestCase): # Test merge_from method for all IndexFlatCodes Types +@for_all_simd_levels class TestMerge2(unittest.TestCase): def do_flat_codes_test(self, factory_key): @@ -243,6 +245,7 @@ class TestMerge2(unittest.TestCase): self.do_test_with_ids("Flat,IDMap2") +@for_all_simd_levels class TestRemoveFastScan(unittest.TestCase): def do_fast_scan_test(self, diff --git a/tests/test_refine.py b/tests/test_refine.py index a24729cc4..dae3114b2 100644 --- a/tests/test_refine.py +++ b/tests/test_refine.py @@ -8,9 +8,11 @@ import numpy as np import unittest import faiss +from common_faiss_tests import for_all_simd_levels from faiss.contrib import datasets, evaluation +@for_all_simd_levels class TestDistanceComputer(unittest.TestCase): def do_test(self, factory_string, metric_type=faiss.METRIC_L2): @@ -66,6 +68,7 @@ class TestDistanceComputer(unittest.TestCase): self.do_test("RQ3x4_Nqint8", faiss.METRIC_INNER_PRODUCT) +@for_all_simd_levels class TestIndexRefineSearchParams(unittest.TestCase): def do_test(self, factory_string): @@ -129,6 +132,7 @@ class TestIndexRefineSearchParams(unittest.TestCase): self.do_test("IVF8,PQ2x4np,Refine(SQ8)") +@for_all_simd_levels class TestIndexRefineRangeSearch(unittest.TestCase): def do_test(self, factory_string): diff --git a/tests/test_refine_panorama.py b/tests/test_refine_panorama.py index 512fb3c41..ea3660a06 100644 --- a/tests/test_refine_panorama.py +++ b/tests/test_refine_panorama.py @@ -20,9 +20,11 @@ identical distances. import unittest import faiss import numpy as np +from common_faiss_tests import for_all_simd_levels from faiss.contrib.datasets import SyntheticDataset +@for_all_simd_levels class TestIndexRefinePanorama(unittest.TestCase): # Metrics to test diff --git a/tests/test_residual_quantizer.py b/tests/test_residual_quantizer.py index 21b77e0ad..4b63fe2eb 100644 --- a/tests/test_residual_quantizer.py +++ b/tests/test_residual_quantizer.py @@ -8,6 +8,7 @@ import numpy as np import faiss import unittest +from common_faiss_tests import for_all_simd_levels from faiss.contrib import datasets from faiss.contrib.inspect_tools import get_additive_quantizer_codebooks @@ -188,6 +189,7 @@ def eval_codec(q, xb): return ((xb - decoded) ** 2).sum() +@for_all_simd_levels class TestResidualQuantizer(unittest.TestCase): def test_training(self): @@ -741,6 +743,7 @@ class TestAdditiveQuantizerWithLUT(unittest.TestCase): np.testing.assert_array_almost_equal(Dref, Dnew, decimal=5) +@for_all_simd_levels class TestIndexResidualQuantizerSearch(unittest.TestCase): def test_search_IP(self): diff --git a/tests/test_search_params.py b/tests/test_search_params.py index f87efaa40..246ccaa71 100644 --- a/tests/test_search_params.py +++ b/tests/test_search_params.py @@ -9,12 +9,14 @@ import faiss import unittest import sys +from common_faiss_tests import for_all_simd_levels from faiss.contrib import datasets from faiss.contrib.evaluation import sort_range_res_2, check_ref_range_results faiss.omp_set_num_threads(4) +@for_all_simd_levels class TestSelector(unittest.TestCase): """ Test the IDSelector filtering for as many (index class, id selector class) @@ -358,6 +360,7 @@ class TestSelector(unittest.TestCase): self.do_test_id_selector("BinaryFlat", use_heap=False) +@for_all_simd_levels class TestSearchParams(unittest.TestCase): def do_test_with_param(