mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-12 02:13:36 +00:00
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5444 We fix every remaining flake8 E501 (line > 80 chars) violation in fbcode/faiss/ (excluding gpu/), closing out a lint-cleanup initiative that a June 29, 2026 diff stack (9a05463576 -> d304e29b9a -> 7d140d86ca) explicitly promised but left 41% incomplete. The middle diff in that stack aligned .flake8's max-line-length to black's 80-char width and stated the remaining 277 violations after the config change were "genuine lint (E501 long strings/URLs, F401/F841/B011, etc.), addressed in later commits in this stack." The follow-up commit fixed only the F401/F403/F841/B011 categories (45 issues) and never touched E501, leaving 192 violations across 53 files live in trunk. A direct re-scan today found 201 violations across 54 files (two files gained lines since the original count). We fixed 183 violations across 52 files. Two of the originally-flagged files, benchs/bench_rabitq.py and demos/index_pq_flat_separate_codes_from_codebook.py, already carry a file-level `# flake8: noqa` directive (the second is a Bento/Grimaldi notebook export that also fails standalone py_compile due to embedded shell magic) -- flake8 ignores both files entirely, so no changes were needed there and they are excluded from this diff. Fix approach, by category: - The large majority of violations are prose: docstrings and comments rewrapped at word boundaries, preserving each file's existing indentation and docstring conventions. No wording was changed. - Code lines (function calls, f-strings, assert messages, long argument lists) were reflowed in black-compatible style: parenthesization, comma breaks, or implicit adjacent string-literal concatenation. Every touched file is confirmed unchanged by `black --line-length 80 --diff` after the edit. - A small number of genuinely unwrappable long URLs (no reasonable break point) were suppressed with `# noqa: E501` rather than force-wrapped, matching the precedent set by the original black-format diff stack. - demos/offline_ivf/offline_ivf.py: a repeated, non-trivial ratio expression used in both an assert condition and its (lazily-evaluated) failure message was hoisted into a single local variable, eliminating the duplicate computation. The expression is pure and deterministic (built from already-computed arrays), so this is behaviorally identical to the original -- not a functional change. - `arc lint -a` additionally auto-fixed a real bug it detected while processing these files: `raise NotImplemented` -> `raise NotImplementedError` in contrib/evaluation.py (the sentinel object NotImplemented is not an exception type; raising it produces a TypeError masking the intended NotImplementedError). It also added a missing trailing newline in benchs/fb/bench_index_binary_from_float.py and, in the same file, rewrote the `#!/usr/bin/env python2` shebang to `#!/usr/bin/env fbpython` -- that rewrite was reverted by hand, since the file still does `import cPickle` (a Python 2-only module), so the auto-fix would have made the shebang describe an interpreter the script cannot actually run under. Fixing the underlying py2-to-py3 migration is out of scope for this line-length-only sweep. - Rebasing onto master (this diff's base commit had drifted) surfaced two concurrent upstream fixes to `check_ref_knn_with_draws(...)` calls in tests/test_ivf_flat_panorama.py and tests/test_refine_panorama.py (an unrelated in-flight correctness fix passing `D_panorama`/`atol` instead of a stale `D_regular` arg with no `atol`). The rebase took upstream's corrected arguments and re-applied only this diff's line-wrap on top. We verified zero functional change with an AST-level check: every string and f-string literal in every touched file was extracted before and after the edit and compared with whitespace normalized, confirming no wording, value, or expression was altered beyond the intended `# noqa: E501` suffixes and the one documented ratio-hoisting simplification above. Reviewed By: mnorris11 Differential Revision: D112525458 fbshipit-source-id: e4b85d73dafcaac779f3522a383a66e490fa942a
196 lines
5.7 KiB
Python
196 lines
5.7 KiB
Python
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
#
|
|
# This source code is licensed under the MIT license found in the
|
|
# LICENSE file in the root directory of this source tree.
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
|
|
from faiss.benchs.bench_fw.benchmark import Benchmark
|
|
from faiss.benchs.bench_fw.benchmark_io import BenchmarkIO
|
|
from faiss.benchs.bench_fw.descriptors import (
|
|
DatasetDescriptor,
|
|
IndexDescriptorClassic,
|
|
)
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
|
|
def factory_factory(d):
|
|
return (
|
|
[
|
|
("SQ4", None, 256 * (2**10), None),
|
|
("SQ8", None, 256 * (2**10), None),
|
|
("SQfp16", None, 256 * (2**10), None),
|
|
("ITQ64,LSH", None, 256 * (2**10), None),
|
|
("Pad128,ITQ128,LSH", None, 256 * (2**10), None),
|
|
("Pad256,ITQ256,LSH", None, 256 * (2**10), None),
|
|
]
|
|
+ [
|
|
(f"OPQ32_128,Residual2x14,PQ32x{b}", None, 256 * (2**14), None)
|
|
for b in range(8, 16, 2)
|
|
]
|
|
+ [
|
|
(f"PCAR{2 ** d_out},SQ{b}", None, 256 * (2**10), None)
|
|
for d_out in range(6, 11)
|
|
if 2**d_out <= d
|
|
for b in [4, 8]
|
|
]
|
|
+ [
|
|
(f"OPQ{M}_{M * dim},PQ{M}x{b}", None, 256 * (2**b), None)
|
|
for M in [8, 12, 16, 32, 64, 128]
|
|
for dim in [2, 4, 6, 8, 12, 16]
|
|
if M * dim <= d
|
|
for b in range(8, 16, 2)
|
|
]
|
|
+ [
|
|
(
|
|
f"RQ{cs // b}x{b}",
|
|
[{"max_beam_size": 32}],
|
|
256 * (2**b),
|
|
{"max_beam_size": bs, "use_beam_LUT": bl},
|
|
)
|
|
for cs in [64, 128, 256, 512]
|
|
for b in [6, 8, 10, 12]
|
|
for bs in [1, 2, 4, 8, 16, 32]
|
|
for bl in [0, 1]
|
|
if cs // b > 1
|
|
if cs // b < 65
|
|
if cs < d * 8 * 2
|
|
]
|
|
+ [
|
|
(
|
|
f"LSQ{cs // b}x{b}",
|
|
[{"encode_ils_iters": 16}],
|
|
256 * (2**b),
|
|
{"encode_ils_iters": eii, "lsq_gpu": lg},
|
|
)
|
|
for cs in [64, 128, 256, 512]
|
|
for b in [6, 8, 10, 12]
|
|
for eii in [2, 4, 8, 16]
|
|
for lg in [0, 1]
|
|
if cs // b > 1
|
|
if cs // b < 65
|
|
if cs < d * 8 * 2
|
|
]
|
|
+ [
|
|
(
|
|
f"PRQ{sub}x{cs // sub // b}x{b}",
|
|
[{"max_beam_size": 32}],
|
|
256 * (2**b),
|
|
{"max_beam_size": bs, "use_beam_LUT": bl},
|
|
)
|
|
for sub in [2, 3, 4, 8, 16, 32]
|
|
for cs in [64, 96, 128, 192, 256, 384, 512, 768, 1024, 2048]
|
|
for b in [6, 8, 10, 12]
|
|
for bs in [1, 2, 4, 8, 16, 32]
|
|
for bl in [0, 1]
|
|
if cs // sub // b > 1
|
|
if cs // sub // b < 65
|
|
if cs < d * 8 * 2
|
|
if d % sub == 0
|
|
]
|
|
+ [
|
|
(
|
|
f"PLSQ{sub}x{cs // sub // b}x{b}",
|
|
[{"encode_ils_iters": 16}],
|
|
256 * (2**b),
|
|
{"encode_ils_iters": eii, "lsq_gpu": lg},
|
|
)
|
|
for sub in [2, 3, 4, 8, 16, 32]
|
|
for cs in [64, 128, 256, 512, 1024, 2048]
|
|
for b in [6, 8, 10, 12]
|
|
for eii in [2, 4, 8, 16]
|
|
for lg in [0, 1]
|
|
if cs // sub // b > 1
|
|
if cs // sub // b < 65
|
|
if cs < d * 8 * 2
|
|
if d % sub == 0
|
|
]
|
|
)
|
|
|
|
|
|
def run_local(rp):
|
|
bio, d, tablename, distance_metric = rp
|
|
if tablename == "contriever":
|
|
training_vectors = DatasetDescriptor(tablename="training_set.npy")
|
|
database_vectors = DatasetDescriptor(
|
|
tablename="database1M.npy",
|
|
)
|
|
query_vectors = DatasetDescriptor(
|
|
tablename="queries.npy",
|
|
)
|
|
else:
|
|
training_vectors = DatasetDescriptor(
|
|
namespace="std_t",
|
|
tablename=tablename,
|
|
)
|
|
database_vectors = DatasetDescriptor(
|
|
namespace="std_d",
|
|
tablename=tablename,
|
|
)
|
|
query_vectors = DatasetDescriptor(
|
|
namespace="std_q",
|
|
tablename=tablename,
|
|
)
|
|
|
|
benchmark = Benchmark(
|
|
num_threads=32,
|
|
training_vectors=training_vectors,
|
|
database_vectors=database_vectors,
|
|
query_vectors=query_vectors,
|
|
index_descs=[
|
|
IndexDescriptorClassic(
|
|
factory=factory,
|
|
construction_params=construction_params,
|
|
training_size=training_size,
|
|
search_params=search_params,
|
|
)
|
|
for (
|
|
factory,
|
|
construction_params,
|
|
training_size,
|
|
search_params,
|
|
) in factory_factory(d)
|
|
],
|
|
k=1,
|
|
distance_metric=distance_metric,
|
|
)
|
|
benchmark.set_io(bio)
|
|
benchmark.benchmark(
|
|
result_file="result.json",
|
|
train=True,
|
|
reconstruct=False,
|
|
knn=False,
|
|
range=False,
|
|
)
|
|
|
|
|
|
def run(bio, d, tablename, distance_metric):
|
|
bio.launch_jobs(
|
|
run_local, [(bio, d, tablename, distance_metric)], local=True
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("experiment")
|
|
parser.add_argument("path")
|
|
args = parser.parse_args()
|
|
assert os.path.exists(args.path)
|
|
path = os.path.join(args.path, args.experiment)
|
|
if not os.path.exists(path):
|
|
os.mkdir(path)
|
|
bio = BenchmarkIO(
|
|
path=path,
|
|
)
|
|
if args.experiment == "sift1M":
|
|
run(bio, 128, "sift1M", "L2")
|
|
elif args.experiment == "bigann":
|
|
run(bio, 128, "bigann1M", "L2")
|
|
elif args.experiment == "deep1b":
|
|
run(bio, 96, "deep1M", "L2")
|
|
elif args.experiment == "contriever":
|
|
run(bio, 768, "contriever", "IP")
|