De-flake test_meta_index.Shards.test_shards (loosen tie-churn tolerance) (#5348)

Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5348

Failing test: https://www.internalfb.com/intern/test/281475333622770 (`test_meta_index.Shards.test_shards`, DISABLED / ~74% flaky on the `faiss` oncall: https://www.internalfb.com/omh/view/faiss/tests).

The data is seeded (`random_unitary`), so this is not an RNG issue. `IndexShards` merges per-shard top-k by distance; float32 ULP ties at the k=32 boundary reorder neighbors vs. the unsharded `IndexFlatL2` reference, and the threaded shard merge makes the ordering nondeterministic. The mismatch count hovers right at the `nq*k/1000` (0.1%) floor, so it trips ~74% of runs.

Fix: raise the tolerance to `nq*k/100` (1%) with an explanatory comment; a genuine sharding/merge regression collapses thousands of the `nq*k=32000` cells, far above this floor.

Reviewed By: mnorris11

Differential Revision: D109643858

fbshipit-source-id: f33cddacecf956421eedb6e204fa1754c5fb128f
This commit is contained in:
Tia Lim
2026-06-29 11:51:19 -07:00
committed by meta-codesync[bot]
parent 08cb1f2cf3
commit 8bfcb4e2a3
+19 -15
View File
@@ -33,7 +33,7 @@ class IDRemap(unittest.TestCase):
_Dref, Iref = index.search(xq, k)
# try a remapping
ids = np.arange(nb)[::-1].copy().astype('int64')
ids = np.arange(nb)[::-1].copy().astype("int64")
sub_index = faiss.IndexPQ(d, 8, 8)
index2 = faiss.IndexIDMap(sub_index)
@@ -52,8 +52,7 @@ class IDRemap(unittest.TestCase):
# reference: index without remapping
index = faiss.IndexIVFPQ(coarse_quantizer, d,
ncentroids, 8, 8)
index = faiss.IndexIVFPQ(coarse_quantizer, d, ncentroids, 8, 8)
index.nprobe = 5
k = 10
index.train(xt)
@@ -61,10 +60,9 @@ class IDRemap(unittest.TestCase):
_Dref, Iref = index.search(xq, k)
# try a remapping
ids = np.arange(nb)[::-1].copy().astype('int64')
ids = np.arange(nb)[::-1].copy().astype("int64")
index2 = faiss.IndexIVFPQ(coarse_quantizer, d,
ncentroids, 8, 8)
index2 = faiss.IndexIVFPQ(coarse_quantizer, d, ncentroids, 8, 8)
index2.nprobe = 5
index2.train(xt)
@@ -76,8 +74,10 @@ class IDRemap(unittest.TestCase):
class Shards(unittest.TestCase):
@unittest.skipIf(os.name == "posix" and os.uname().sysname == "Darwin",
"There is a bug in the OpenMP implementation on OSX.")
@unittest.skipIf(
os.name == "posix" and os.uname().sysname == "Darwin",
"There is a bug in the OpenMP implementation on OSX.",
)
def test_shards(self):
k = 32
ref_index = faiss.IndexFlatL2(d)
@@ -86,10 +86,8 @@ class Shards(unittest.TestCase):
_Dref, Iref = ref_index.search(xq, k)
# Create both threaded and non-threaded shard indexes
shard_index_nonthreaded = faiss.IndexShards(
d, False) # explicitly non-threaded
shard_index_threaded = faiss.IndexShards(
d, True) # explicitly threaded
shard_index_nonthreaded = faiss.IndexShards(d, False) # explicitly non-threaded
shard_index_threaded = faiss.IndexShards(d, True) # explicitly threaded
shard_index_2 = faiss.IndexShards(d, True, False)
ni = 3
@@ -138,7 +136,12 @@ class Shards(unittest.TestCase):
faiss.omp_set_num_threads(remember_nt)
ndiff = (I != Iref).sum()
assert (ndiff < nq * k / 1000.)
# IndexShards merges per-shard top-k by distance; float32 ULP ties
# at the k=32 boundary reorder neighbors vs. the unsharded
# IndexFlatL2 reference (amplified by the threaded shard merge).
# Allow ~1% mismatches; a real merge regression collapses
# thousands of the nq*k cells, far above this floor.
assert ndiff < nq * k / 100.0, f"too many mismatches: {ndiff}"
def test_shards_ivf(self):
ds = SyntheticDataset(32, 1000, 100, 20)
@@ -151,10 +154,11 @@ class Shards(unittest.TestCase):
ref_index.reset()
sharded_index = faiss.IndexShardsIVF(
ref_index.quantizer, ref_index.nlist, False, True)
ref_index.quantizer, ref_index.nlist, False, True
)
for shard in range(3):
index_i = faiss.clone_index(ref_index)
index_i.add(xb[shard * nb // 3: (shard + 1)* nb // 3])
index_i.add(xb[shard * nb // 3 : (shard + 1) * nb // 3])
sharded_index.add_shard(index_i)
Dnew, Inew = sharded_index.search(ds.get_database(), 10)