From be1242775a6e7c025c3ab48388d95bb6a5377d8c Mon Sep 17 00:00:00 2001 From: Maria Lomeli Date: Tue, 12 Dec 2023 09:51:05 -0800 Subject: [PATCH 001/206] Upstream changes to big batch search (#3170) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3170 Logging info, adding to heap and wait_in and out times. Reviewed By: algoriddle Differential Revision: D52034667 fbshipit-source-id: 8ab864c5c43d534d094c6e81bb810c74e20c9ac2 --- contrib/big_batch_search.py | 51 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/contrib/big_batch_search.py b/contrib/big_batch_search.py index 6b0fd36e91..440a538c15 100644 --- a/contrib/big_batch_search.py +++ b/contrib/big_batch_search.py @@ -6,6 +6,7 @@ import time import pickle import os +import logging from multiprocessing.pool import ThreadPool import threading import _thread @@ -41,7 +42,7 @@ def __init__( self.use_float16 = use_float16 keep_max = faiss.is_similarity_metric(index.metric_type) self.rh = faiss.ResultHeap(len(xq), k, keep_max=keep_max) - self.t_accu = [0] * 5 + self.t_accu = [0] * 6 self.t_display = self.t0 = time.time() def start_t_accu(self): @@ -74,11 +75,12 @@ def report(self, l): f"[{t:.1f} s] list {l}/{self.index.nlist} " f"times prep q {self.t_accu[0]:.3f} prep b {self.t_accu[1]:.3f} " f"comp {self.t_accu[2]:.3f} res {self.t_accu[3]:.3f} " - f"wait {self.t_accu[4]:.3f} " + f"wait in {self.t_accu[4]:.3f} " + f"wait out {self.t_accu[5]:.3f} " f"eta {datetime.timedelta(seconds=t*self.index.nlist/(l+1)-t)} " f"mem {faiss.get_mem_usage_kb()}", - end="\r" if self.verbose <= 2 else "\n", - flush=True, + end="\r" if self.verbose <= 2 else "\n", + flush=True, ) self.t_display = time.time() @@ -293,7 +295,7 @@ def big_batch_search( ) mem_tot = mem_queries + mem_assign + mem_res if verbose > 0: - print( + logging.info( f"memory: queries {mem_queries} assign {mem_assign} " f"result {mem_res} total {mem_tot} = {mem_tot / (1<<30):.3f} GiB" ) @@ -312,8 +314,8 @@ def big_batch_search( ) bbs.decode_func = comp.decode_func - bbs.by_residual = comp.by_residual + bbs.by_residual = comp.by_residual if q_assign is None: bbs.coarse_quantization() else: @@ -327,11 +329,11 @@ def big_batch_search( if checkpoint is not None: assert (start_list, end_list) == (0, index.nlist) if os.path.exists(checkpoint): - print("recovering checkpoint", checkpoint) + logging.info(f"recovering checkpoint: {checkpoint}") completed = bbs.read_checkpoint(checkpoint) - print(" already completed", len(completed)) + logging.info(f" already completed: {len(completed)}") else: - print("no checkpoint: starting from scratch") + logging.info("no checkpoint: starting from scratch") if threaded == 0: # simple sequential version @@ -414,10 +416,10 @@ def task_manager(*args): def prepare_task(task_id, output_queue, input_queue=None): try: - # print(f"Prepare start: {task_id}") + logging.info(f"Prepare start: {task_id}") q_subset, xq_l, list_ids, xb_l = bbs.prepare_bucket(task_id) output_queue.put((task_id, q_subset, xq_l, list_ids, xb_l)) - # print(f"Prepare end: {task_id}") + logging.info(f"Prepare end: {task_id}") except: traceback.print_exc() _thread.interrupt_main() @@ -425,18 +427,19 @@ def prepare_task(task_id, output_queue, input_queue=None): def compute_task(task_id, output_queue, input_queue): try: - # print(f"Compute start: {task_id}") - t_wait = 0 + logging.info(f"Compute start: {task_id}") + t_wait_out = 0 while True: t0 = time.time() + logging.info(f'Compute input: task {task_id}') input_value = input_queue.get() - t_wait += time.time() - t0 + t_wait_in = time.time() - t0 if input_value is None: # signal for other compute tasks input_queue.put(None) break centroid, q_subset, xq_l, list_ids, xb_l = input_value - # print(f'Compute work start: task {task_id}, centroid {centroid}') + logging.info(f'Compute work: task {task_id}, centroid {centroid}') t0 = time.time() if computation_threads > 1: D, I = comp.block_search( @@ -445,13 +448,13 @@ def compute_task(task_id, output_queue, input_queue): else: D, I = comp.block_search(xq_l, xb_l, list_ids, k) t_compute = time.time() - t0 - # print(f'Compute work end: task {task_id}, centroid {centroid}') + logging.info(f'Compute output: task {task_id}, centroid {centroid}') t0 = time.time() output_queue.put( - (centroid, t_wait, t_compute, q_subset, D, list_ids, I) + (centroid, t_wait_in, t_wait_out, t_compute, q_subset, D, list_ids, I) ) - t_wait = time.time() - t0 - # print(f"Compute end: {task_id}") + t_wait_out = time.time() - t0 + logging.info(f"Compute end: {task_id}") except: traceback.print_exc() _thread.interrupt_main() @@ -480,21 +483,25 @@ def compute_task(task_id, output_queue, input_queue): t_checkpoint = time.time() while True: + logging.info("Waiting for result") value = compute_to_main_queue.get() if not value: break - centroid, t_wait, t_compute, q_subset, D, list_ids, I = value + centroid, t_wait_in, t_wait_out, t_compute, q_subset, D, list_ids, I = value # to test checkpointing if centroid == crash_at: 1 / 0 bbs.t_accu[2] += t_compute - bbs.t_accu[4] += t_wait + bbs.t_accu[4] += t_wait_in + bbs.t_accu[5] += t_wait_out + logging.info(f"Adding to heap start: centroid {centroid}") bbs.add_results_to_heap(q_subset, D, list_ids, I) + logging.info(f"Adding to heap end: centroid {centroid}") completed.add(centroid) bbs.report(centroid) if checkpoint is not None: if time.time() - t_checkpoint > checkpoint_freq: - print("writing checkpoint") + logging.info("writing checkpoint") bbs.write_checkpoint(checkpoint, completed) t_checkpoint = time.time() From 9a8b34e29546eed1eec23c8147ad538aa1cd34ae Mon Sep 17 00:00:00 2001 From: Maria Date: Mon, 18 Dec 2023 15:09:31 -0800 Subject: [PATCH 002/206] Offline IVF powered by faiss big batch search (#3175) Summary: This PR introduces the offline IVF (OIVF) framework which contains some tooling to run search using IVFPQ indexes (plus OPQ pretransforms) for large batches of queries using [big_batch_search](https://github.com/mlomeli1/faiss/blob/main/contrib/big_batch_search.py) and GPU faiss. See the [README](https://github.com/mlomeli1/faiss/blob/oivf/demos/offline_ivf/README.md) for details about using this framework. This PR includes the following unit tests, which can be run with the unittest library as so: ```` ~/faiss/demos/offline_ivf$ python3 -m unittest tests/test_iterate_input.py -k test_iterate_back ```` In test_offline_ivf: ```` test_consistency_check test_train_index test_index_shard_equal_file_sizes test_index_shard_unequal_file_sizes test_search test_evaluate_without_margin test_evaluate_without_margin_OPQ test_evaluate_with_margin test_split_batch_size_bigger_than_file_sizes test_split_batch_size_smaller_than_file_sizes test_split_files_with_corrupted_input_file ```` In test_iterate_input: ```` test_iterate_input_file_larger_than_batch test_get_vs_iterate test_iterate_back ```` Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3175 Reviewed By: algoriddle Differential Revision: D52218447 Pulled By: mlomeli1 fbshipit-source-id: 78b12457c79b02eb2c9ae993560f2e295798e7e5 --- demos/offline_ivf/README.md | 52 + demos/offline_ivf/__init__.py | 0 demos/offline_ivf/config_ssnpp.yaml | 109 ++ .../offline_ivf/create_sharded_ssnpp_files.py | 63 + demos/offline_ivf/dataset.py | 173 +++ demos/offline_ivf/generate_config.py | 45 + demos/offline_ivf/offline_ivf.py | 1036 +++++++++++++++++ demos/offline_ivf/run.py | 218 ++++ .../test_data/IVF256_PQ4.empty.faissindex | Bin 0 -> 16564 bytes .../OPQ4_IVF256_PQ4.empty.faissindex | Bin 0 -> 16891 bytes .../test_data/coco_lang/IVF256_PQ4.faissindex | Bin 0 -> 22856 bytes .../coco_lang/IVF256_PQ4.faissindex.ivfdata | Bin 0 -> 360000 bytes .../test_data/coco_lang/IVF256_PQ4.shard_0 | Bin 0 -> 138612 bytes .../test_data/coco_lang/IVF256_PQ4.shard_1 | Bin 0 -> 138612 bytes .../test_data/coco_lang/IVF256_PQ4.shard_2 | Bin 0 -> 138612 bytes .../coco_lang/OPQ4_IVF256_PQ4.faissindex | Bin 0 -> 23188 bytes .../OPQ4_IVF256_PQ4.faissindex.ivfdata | Bin 0 -> 360000 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_0 | Bin 0 -> 137755 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_1 | Bin 0 -> 137787 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_2 | Bin 0 -> 137771 bytes .../test_data/goku_lang/IVF256_PQ4.faissindex | Bin 0 -> 22856 bytes .../goku_lang/IVF256_PQ4.faissindex.ivfdata | Bin 0 -> 360000 bytes .../test_data/goku_lang/IVF256_PQ4.shard_0 | Bin 0 -> 138612 bytes .../test_data/goku_lang/IVF256_PQ4.shard_1 | Bin 0 -> 138612 bytes .../test_data/goku_lang/IVF256_PQ4.shard_2 | Bin 0 -> 138612 bytes .../goku_lang/OPQ4_IVF256_PQ4.faissindex | Bin 0 -> 23188 bytes .../OPQ4_IVF256_PQ4.faissindex.ivfdata | Bin 0 -> 360000 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_0 | Bin 0 -> 137771 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_1 | Bin 0 -> 137771 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_2 | Bin 0 -> 137771 bytes demos/offline_ivf/tests/test_iterate_input.py | 132 +++ demos/offline_ivf/tests/test_offline_ivf.py | 545 +++++++++ demos/offline_ivf/tests/testing_utils.py | 180 +++ demos/offline_ivf/utils.py | 94 ++ 34 files changed, 2647 insertions(+) create mode 100644 demos/offline_ivf/README.md create mode 100644 demos/offline_ivf/__init__.py create mode 100644 demos/offline_ivf/config_ssnpp.yaml create mode 100644 demos/offline_ivf/create_sharded_ssnpp_files.py create mode 100644 demos/offline_ivf/dataset.py create mode 100644 demos/offline_ivf/generate_config.py create mode 100644 demos/offline_ivf/offline_ivf.py create mode 100644 demos/offline_ivf/run.py create mode 100644 demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex create mode 100644 demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.faissindex create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.faissindex.ivfdata create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_0 create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_1 create mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_2 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_2 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 create mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 create mode 100644 demos/offline_ivf/tests/test_iterate_input.py create mode 100644 demos/offline_ivf/tests/test_offline_ivf.py create mode 100644 demos/offline_ivf/tests/testing_utils.py create mode 100644 demos/offline_ivf/utils.py diff --git a/demos/offline_ivf/README.md b/demos/offline_ivf/README.md new file mode 100644 index 0000000000..df848ba0ab --- /dev/null +++ b/demos/offline_ivf/README.md @@ -0,0 +1,52 @@ + +# Offline IVF + +This folder contains the code for the offline ivf algorithm powered by faiss big batch search. + +Create a conda env: + +`conda create --name oivf python=3.10` + +`conda activate oivf` + +`conda install -c pytorch/label/nightly -c nvidia faiss-gpu=1.7.4` + +`conda install tqdm` + +`conda install pyyaml` + +`conda install -c conda-forge submitit` + + +## Run book + +1. Optionally shard your dataset (see create_sharded_dataset.py) and create the corresponding yaml file `config_ssnpp.yaml`. You can use `generate_config.py` by specifying the root directory of your dataset and the files with the data shards + +`python generate_config` + +2. Run the train index command + +`python run.py --command train_index --config config_ssnpp.yaml --xb ssnpp_1B` + + +3. Run the index-shard command so it produces sharded indexes, required for the search step + +`python run.py --command index_shard --config config_ssnpp.yaml --xb ssnpp_1B` + + +6. Send jobs to the cluster to run search + +`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --cluster_run --partition ` + + +Remarks about the `search` command: it is assumed that the database vectors are the query vectors when performing the search step. +a. If the query vectors are different than the database vectors, it should be passed in the xq argument +b. A new dataset needs to be prepared (step 1) before passing it to the query vectors argument `–xq` + +`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --xq ` + + +6. We can always run the consistency-check for sanity checks! + +`python run.py --command consistency_check--config config_ssnpp.yaml --xb ssnpp_1B` + diff --git a/demos/offline_ivf/__init__.py b/demos/offline_ivf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/offline_ivf/config_ssnpp.yaml b/demos/offline_ivf/config_ssnpp.yaml new file mode 100644 index 0000000000..690f0de156 --- /dev/null +++ b/demos/offline_ivf/config_ssnpp.yaml @@ -0,0 +1,109 @@ +d: 256 +output: /checkpoint/marialomeli/offline_faiss/ssnpp +index: + prod: + - 'IVF8192,PQ128' + non-prod: + - 'IVF16384,PQ128' + - 'IVF32768,PQ128' +nprobe: + prod: + - 512 + non-prod: + - 256 + - 128 + - 1024 + - 2048 + - 4096 + - 8192 + +k: 50 +index_shard_size: 50000000 +query_batch_size: 50000000 +evaluation_sample: 10000 +training_sample: 1572864 +datasets: + ssnpp_1B: + root: /checkpoint/marialomeli/ssnpp_data + size: 1000000000 + files: + - dtype: uint8 + format: npy + name: ssnpp_0000000000.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000001.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000002.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000003.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000004.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000005.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000006.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000007.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000008.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000009.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000010.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000011.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000012.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000013.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000014.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000015.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000016.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000017.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000018.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000019.npy + size: 50000000 diff --git a/demos/offline_ivf/create_sharded_ssnpp_files.py b/demos/offline_ivf/create_sharded_ssnpp_files.py new file mode 100644 index 0000000000..7967fbbbac --- /dev/null +++ b/demos/offline_ivf/create_sharded_ssnpp_files.py @@ -0,0 +1,63 @@ +# 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 numpy as np +import argparse +import os + + +def xbin_mmap(fname, dtype, maxn=-1): + """ + Code from + https://github.com/harsha-simhadri/big-ann-benchmarks/blob/main/benchmark/dataset_io.py#L94 + mmap the competition file format for a given type of items + """ + n, d = map(int, np.fromfile(fname, dtype="uint32", count=2)) + assert os.stat(fname).st_size == 8 + n * d * np.dtype(dtype).itemsize + if maxn > 0: + n = min(n, maxn) + return np.memmap(fname, dtype=dtype, mode="r", offset=8, shape=(n, d)) + + +def main(args: argparse.Namespace): + ssnpp_data = xbin_mmap(fname=args.filepath, dtype="uint8") + num_batches = ssnpp_data.shape[0] // args.data_batch + assert ( + ssnpp_data.shape[0] % args.data_batch == 0 + ), "num of embeddings per file should divide total num of embeddings" + for i in range(num_batches): + xb_batch = ssnpp_data[ + i * args.data_batch : (i + 1) * args.data_batch, : + ] + filename = args.output_dir + f"/ssnpp_{(i):010}.npy" + np.save(filename, xb_batch) + print(f"File {filename} is saved!") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--data_batch", + dest="data_batch", + type=int, + default=50000000, + help="Number of embeddings per file, should be a divisor of 1B", + ) + parser.add_argument( + "--filepath", + dest="filepath", + type=str, + default="/datasets01/big-ann-challenge-data/FB_ssnpp/FB_ssnpp_database.u8bin", + help="path of 1B ssnpp database vectors' original file", + ) + parser.add_argument( + "--filepath", + dest="output_dir", + type=str, + default="/checkpoint/marialomeli/ssnpp_data", + help="path to put sharded files", + ) + + args = parser.parse_args() + main(args) diff --git a/demos/offline_ivf/dataset.py b/demos/offline_ivf/dataset.py new file mode 100644 index 0000000000..bdd96a463c --- /dev/null +++ b/demos/offline_ivf/dataset.py @@ -0,0 +1,173 @@ +# 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 os +import numpy as np +import faiss +from typing import List +import random +import logging +from functools import lru_cache + + +def create_dataset_from_oivf_config(cfg, ds_name): + normalise = cfg["normalise"] if "normalise" in cfg else False + return MultiFileVectorDataset( + cfg["datasets"][ds_name]["root"], + [ + FileDescriptor( + f["name"], f["format"], np.dtype(f["dtype"]), f["size"] + ) + for f in cfg["datasets"][ds_name]["files"] + ], + cfg["d"], + normalise, + cfg["datasets"][ds_name]["size"], + ) + + +@lru_cache(maxsize=100) +def _memmap_vecs( + file_name: str, format: str, dtype: np.dtype, size: int, d: int +) -> np.array: + """ + If the file is in raw format, the file size will + be divisible by the dimensionality and by the size + of the data type. + Otherwise,the file contains a header and we assume + it is of .npy type. It the returns the memmapped file. + """ + + assert os.path.exists(file_name), f"file does not exist {file_name}" + if format == "raw": + fl = os.path.getsize(file_name) + nb = fl // d // dtype.itemsize + assert nb == size, f"{nb} is different than config's {size}" + assert fl == d * dtype.itemsize * nb # no header + return np.memmap(file_name, shape=(nb, d), dtype=dtype, mode="r") + elif format == "npy": + vecs = np.load(file_name, mmap_mode="r") + assert vecs.shape[0] == size, f"size:{size},shape {vecs.shape[0]}" + assert vecs.shape[1] == d + assert vecs.dtype == dtype + return vecs + else: + ValueError("The file cannot be loaded in the current format.") + + +class FileDescriptor: + def __init__(self, name: str, format: str, dtype: np.dtype, size: int): + self.name = name + self.format = format + self.dtype = dtype + self.size = size + + +class MultiFileVectorDataset: + def __init__( + self, + root: str, + file_descriptors: List[FileDescriptor], + d: int, + normalize: bool, + size: int, + ): + assert os.path.exists(root) + self.root = root + self.file_descriptors = file_descriptors + self.d = d + self.normalize = normalize + self.size = size + self.file_offsets = [0] + t = 0 + for f in self.file_descriptors: + xb = _memmap_vecs( + f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d + ) + t += xb.shape[0] + self.file_offsets.append(t) + assert ( + t == self.size + ), "the sum of num of embeddings per file!=total num of embeddings" + + def iterate(self, start: int, batch_size: int, dt: np.dtype): + buffer = np.empty(shape=(batch_size, self.d), dtype=dt) + rem = 0 + for f in self.file_descriptors: + if start >= f.size: + start -= f.size + continue + logging.info(f"processing: {f.name}...") + xb = _memmap_vecs( + f"{self.root}/{f.name}", + f.format, + f.dtype, + f.size, + self.d, + ) + if start > 0: + xb = xb[start:] + start = 0 + req = min(batch_size - rem, xb.shape[0]) + buffer[rem : rem + req] = xb[:req] + rem += req + if rem == batch_size: + if self.normalize: + faiss.normalize_L2(buffer) + yield buffer.copy() + rem = 0 + for i in range(req, xb.shape[0], batch_size): + j = i + batch_size + if j <= xb.shape[0]: + tmp = xb[i:j].astype(dt) + if self.normalize: + faiss.normalize_L2(tmp) + yield tmp + else: + rem = xb.shape[0] - i + buffer[:rem] = xb[i:j] + if rem > 0: + tmp = buffer[:rem] + if self.normalize: + faiss.normalize_L2(tmp) + yield tmp + + def get(self, idx: List[int]): + n = len(idx) + fidx = np.searchsorted(self.file_offsets, idx, "right") + res = np.empty(shape=(len(idx), self.d), dtype=np.float32) + for r, id, fid in zip(range(n), idx, fidx): + assert fid > 0 and fid <= len(self.file_descriptors), f"{fid}" + f = self.file_descriptors[fid - 1] + # deferring normalization until after reading the vec + vecs = _memmap_vecs( + f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d + ) + i = id - self.file_offsets[fid - 1] + assert i >= 0 and i < vecs.shape[0] + res[r, :] = vecs[i] # TODO: find a faster way + if self.normalize: + faiss.normalize_L2(res) + return res + + def sample(self, n, idx_fn, vecs_fn): + if vecs_fn and os.path.exists(vecs_fn): + vecs = np.load(vecs_fn) + assert vecs.shape == (n, self.d) + return vecs + if idx_fn and os.path.exists(idx_fn): + idx = np.load(idx_fn) + assert idx.size == n + else: + idx = np.array(sorted(random.sample(range(self.size), n))) + if idx_fn: + np.save(idx_fn, idx) + vecs = self.get(idx) + if vecs_fn: + np.save(vecs_fn, vecs) + return vecs + + def get_first_n(self, n, dt): + assert n <= self.size + return next(self.iterate(0, n, dt)) diff --git a/demos/offline_ivf/generate_config.py b/demos/offline_ivf/generate_config.py new file mode 100644 index 0000000000..b5a12645ab --- /dev/null +++ b/demos/offline_ivf/generate_config.py @@ -0,0 +1,45 @@ +# 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 numpy as np +import os +import yaml + +# with ssnpp sharded data +root = "/checkpoint/marialomeli/ssnpp_data" +file_names = [f"ssnpp_{i:010}.npy" for i in range(20)] +d = 256 +dt = np.dtype(np.uint8) + + +def read_embeddings(fp): + fl = os.path.getsize(fp) + nb = fl // d // dt.itemsize + print(nb) + if fl == d * dt.itemsize * nb: # no header + return ("raw", np.memmap(fp, shape=(nb, d), dtype=dt, mode="r")) + else: # assume npy + vecs = np.load(fp, mmap_mode="r") + assert vecs.shape[1] == d + assert vecs.dtype == dt + return ("npy", vecs) + + +cfg = {} +files = [] +size = 0 +for fn in file_names: + fp = f"{root}/{fn}" + assert os.path.exists(fp), f"{fp} is missing" + ft, xb = read_embeddings(fp) + files.append( + {"name": fn, "size": xb.shape[0], "dtype": dt.name, "format": ft} + ) + size += xb.shape[0] + +cfg["size"] = size +cfg["root"] = root +cfg["d"] = d +cfg["files"] = files +print(yaml.dump(cfg)) diff --git a/demos/offline_ivf/offline_ivf.py b/demos/offline_ivf/offline_ivf.py new file mode 100644 index 0000000000..a2babd762e --- /dev/null +++ b/demos/offline_ivf/offline_ivf.py @@ -0,0 +1,1036 @@ +# 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 faiss +import numpy as np +import os +from tqdm import tqdm, trange +import sys +import logging +from faiss.contrib.ondisk import merge_ondisk +from faiss.contrib.big_batch_search import big_batch_search +from faiss.contrib.exhaustive_search import knn_ground_truth +from faiss.contrib.evaluation import knn_intersection_measure +from utils import ( + get_intersection_cardinality_frequencies, + margin, + is_pretransform_index, +) +from dataset import create_dataset_from_oivf_config + +logging.basicConfig( + format=( + "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)-12s %(message)s" + ), + level=logging.INFO, + datefmt="%Y-%m-%d %H:%M:%S", + force=True, +) + +EMBEDDINGS_BATCH_SIZE: int = 100_000 +NUM_SUBSAMPLES: int = 100 +SMALL_DATA_SAMPLE: int = 10000 + + +class OfflineIVF: + def __init__(self, cfg, args, nprobe, index_factory_str): + self.input_d = cfg["d"] + self.dt = cfg["datasets"][args.xb]["files"][0]["dtype"] + assert self.input_d > 0 + output_dir = cfg["output"] + assert os.path.exists(output_dir) + self.index_factory = index_factory_str + assert self.index_factory is not None + self.index_factory_fn = self.index_factory.replace(",", "_") + self.index_template_file = ( + f"{output_dir}/{args.xb}/{self.index_factory_fn}.empty.faissindex" + ) + logging.info(f"index template: {self.index_template_file}") + + if not args.xq: + args.xq = args.xb + + self.by_residual = True + if args.no_residuals: + self.by_residual = False + + xb_output_dir = f"{output_dir}/{args.xb}" + if not os.path.exists(xb_output_dir): + os.makedirs(xb_output_dir) + xq_output_dir = f"{output_dir}/{args.xq}" + if not os.path.exists(xq_output_dir): + os.makedirs(xq_output_dir) + search_output_dir = f"{output_dir}/{args.xq}_in_{args.xb}" + if not os.path.exists(search_output_dir): + os.makedirs(search_output_dir) + self.knn_dir = f"{search_output_dir}/knn" + if not os.path.exists(self.knn_dir): + os.makedirs(self.knn_dir) + self.eval_dir = f"{search_output_dir}/eval" + if not os.path.exists(self.eval_dir): + os.makedirs(self.eval_dir) + self.index = {} # to keep a reference to opened indices, + self.ivls = {} # hstack inverted lists, + self.index_shards = {} # and index shards + self.index_shard_prefix = ( + f"{xb_output_dir}/{self.index_factory_fn}.shard_" + ) + self.xq_index_shard_prefix = ( + f"{xq_output_dir}/{self.index_factory_fn}.shard_" + ) + self.index_file = ( # TODO: added back temporarily for evaluate, handle name of non-sharded index file and remove. + f"{xb_output_dir}/{self.index_factory_fn}.faissindex" + ) + self.xq_index_file = ( + f"{xq_output_dir}/{self.index_factory_fn}.faissindex" + ) + self.training_sample = cfg["training_sample"] + self.evaluation_sample = cfg["evaluation_sample"] + self.xq_ds = create_dataset_from_oivf_config(cfg, args.xq) + self.xb_ds = create_dataset_from_oivf_config(cfg, args.xb) + file_descriptors = self.xq_ds.file_descriptors + self.file_sizes = [fd.size for fd in file_descriptors] + self.shard_size = cfg["index_shard_size"] # ~100GB + self.nshards = self.xb_ds.size // self.shard_size + if self.xb_ds.size % self.shard_size != 0: + self.nshards += 1 + self.xq_nshards = self.xq_ds.size // self.shard_size + if self.xq_ds.size % self.shard_size != 0: + self.xq_nshards += 1 + self.nprobe = nprobe + assert self.nprobe > 0, "Invalid nprobe parameter." + if "deduper" in cfg: + self.deduper = cfg["deduper"] + self.deduper_codec_fn = [ + f"{xb_output_dir}/deduper_codec_{codec.replace(',', '_')}" + for codec in self.deduper + ] + self.deduper_idx_fn = [ + f"{xb_output_dir}/deduper_idx_{codec.replace(',', '_')}" + for codec in self.deduper + ] + else: + self.deduper = None + self.k = cfg["k"] + assert self.k > 0, "Invalid number of neighbours parameter." + self.knn_output_file_suffix = ( + f"{self.index_factory_fn}_np{self.nprobe}.npy" + ) + + fp = 32 + if self.dt == "float16": + fp = 16 + self.postprocess_output_dir = ( + self.knn_dir + + f"/dists5_p5.{args.xb}-{args.xq}.{self.index_factory_fn}.k{self.k}.np{self.nprobe}.fp{fp}-shard" + ) + + self.xq_bs = cfg["query_batch_size"] + if "metric" in cfg: + self.metric = eval(f'faiss.{cfg["metric"]}') + else: + self.metric = faiss.METRIC_L2 + + if "evaluate_by_margin" in cfg: + self.evaluate_by_margin = cfg["evaluate_by_margin"] + else: + self.evaluate_by_margin = False + + os.system("grep -m1 'model name' < /proc/cpuinfo") + os.system("grep -E 'MemTotal|MemFree' /proc/meminfo") + os.system("nvidia-smi") + os.system("nvcc --version") + + self.knn_queries_memory_limit = 4 * 1024 * 1024 * 1024 # 4 GB + self.knn_vectors_memory_limit = 8 * 1024 * 1024 * 1024 # 8 GB + + def input_stats(self): + """ + Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). + """ + xb_sample = self.xb_ds.get_first_n(self.training_sample, np.float32) + logging.info(f"input shape: {xb_sample.shape}") + logging.info("running MatrixStats on training sample...") + logging.info(faiss.MatrixStats(xb_sample).comments) + logging.info("done") + + def dedupe(self): + logging.info(self.deduper) + if self.deduper is None: + logging.info("No deduper configured") + return + codecs = [] + codesets = [] + idxs = [] + for factory, filename in zip(self.deduper, self.deduper_codec_fn): + if os.path.exists(filename): + logging.info(f"loading trained dedupe codec: {filename}") + codec = faiss.read_index(filename) + else: + logging.info(f"training dedupe codec: {factory}") + codec = faiss.index_factory(self.input_d, factory) + xb_sample = np.unique( + self.xb_ds.get_first_n(100_000, np.float32), axis=0 + ) + faiss.ParameterSpace().set_index_parameter(codec, "verbose", 1) + codec.train(xb_sample) + logging.info(f"writing trained dedupe codec: {filename}") + faiss.write_index(codec, filename) + codecs.append(codec) + codesets.append(faiss.CodeSet(codec.sa_code_size())) + idxs.append(np.empty((0,), dtype=np.uint32)) + bs = 1_000_000 + i = 0 + for buffer in tqdm(self.xb_ds.iterate(0, bs, np.float32)): + for j in range(len(codecs)): + codec, codeset, idx = codecs[j], codesets[j], idxs[j] + uniq = codeset.insert(codec.sa_encode(buffer)) + idxs[j] = np.append( + idx, + np.arange(i, i + buffer.shape[0], dtype=np.uint32)[uniq], + ) + i += buffer.shape[0] + for idx, filename in zip(idxs, self.deduper_idx_fn): + logging.info(f"writing {filename}, shape: {idx.shape}") + np.save(filename, idx) + logging.info("done") + + def train_index(self): + """ + Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). + """ + assert not os.path.exists(self.index_template_file), ( + "The train command has been ran, the index template file already" + " exists." + ) + xb_sample = np.unique( + self.xb_ds.get_first_n(self.training_sample, np.float32), axis=0 + ) + logging.info(f"input shape: {xb_sample.shape}") + index = faiss.index_factory( + self.input_d, self.index_factory, self.metric + ) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.by_residual = True + faiss.ParameterSpace().set_index_parameter(index, "verbose", 1) + logging.info("running training...") + index.train(xb_sample) + logging.info(f"writing trained index {self.index_template_file}...") + faiss.write_index(index, self.index_template_file) + logging.info("done") + + def _iterate_transformed(self, ds, start, batch_size, dt): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + if is_pretransform_index(index): + vt = index.chain.at(0) # fetch pretransform + for buffer in ds.iterate(start, batch_size, dt): + yield vt.apply(buffer) + else: + for buffer in ds.iterate(start, batch_size, dt): + yield buffer + + def index_shard_and_quantize(self): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + assert self.nprobe <= index_ivf.quantizer.ntotal, ( + f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" + f" to retrieve {self.nprobe} neighbours, check." + ) + + if is_pretransform_index(index): + d = index.chain.at(0).d_out + else: + d = self.input_d + for i in range(0, self.nshards): + sfn = f"{self.index_shard_prefix}{i}" + cqfn = f"{self.coarse_quantization_prefix}{i}" # fixme + if os.path.exists(sfn) or os.path.exists(cqfn): + logging.info(f"skipping shard: {i}") + continue + try: + with open(cqfn, "xb") as cqf: + index.reset() + start = i * self.shard_size + j = 0 + quantizer = faiss.index_cpu_to_all_gpus( + index_ivf.quantizer + ) + for xb_j in tqdm( + self._iterate_transformed( + self.xb_ds, + start, + EMBEDDINGS_BATCH_SIZE, + np.float32, + ), + file=sys.stdout, + ): + assert xb_j.shape[1] == d + _, I = quantizer.search(xb_j, self.nprobe) + assert np.amin(I) >= 0, f"{I}" + assert np.amax(I) < index_ivf.nlist + cqf.write(I) + self._index_add_core_wrapper( # fixme + index_ivf, + xb_j, + np.arange(start + j, start + j + xb_j.shape[0]), + I[:, 0], + ) + j += xb_j.shape[0] + assert j <= self.shard_size + if j == self.shard_size: + break + logging.info(f"writing {sfn}...") + faiss.write_index(index, sfn) + except FileExistsError: + logging.info(f"skipping shard: {i}") + continue + logging.info("done") + + def index_shard(self): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + assert self.nprobe <= index_ivf.quantizer.ntotal, ( + f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" + f" to retrieve {self.nprobe} neighbours, check." + ) + cpu_quantizer = index_ivf.quantizer + gpu_quantizer = faiss.index_cpu_to_all_gpus(cpu_quantizer) + + for i in range(0, self.nshards): + sfn = f"{self.index_shard_prefix}{i}" + try: + index.reset() + index_ivf.quantizer = gpu_quantizer + with open(sfn, "xb"): + start = i * self.shard_size + jj = 0 + embeddings_batch_size = min( + EMBEDDINGS_BATCH_SIZE, self.shard_size + ) + assert ( + self.shard_size % embeddings_batch_size == 0 + or EMBEDDINGS_BATCH_SIZE % embeddings_batch_size == 0 + ), ( + f"the shard size {self.shard_size} and embeddings" + f" shard size {EMBEDDINGS_BATCH_SIZE} are not" + " divisible" + ) + + for xb_j in tqdm( + self._iterate_transformed( + self.xb_ds, + start, + embeddings_batch_size, + np.float32, + ), + file=sys.stdout, + ): + assert xb_j.shape[1] == index.d + index.add_with_ids( + xb_j, + np.arange(start + jj, start + jj + xb_j.shape[0]), + ) + jj += xb_j.shape[0] + logging.info(jj) + assert ( + jj <= self.shard_size + ), f"jj {jj} and shard_zide {self.shard_size}" + if jj == self.shard_size: + break + logging.info(f"writing {sfn}...") + index_ivf.quantizer = cpu_quantizer + faiss.write_index(index, sfn) + except FileExistsError: + logging.info(f"skipping shard: {i}") + continue + logging.info("done") + + def merge_index(self): + ivf_file = f"{self.index_file}.ivfdata" + + assert os.path.exists(self.index_template_file) + assert not os.path.exists( + ivf_file + ), f"file with embeddings data {ivf_file} not found, check." + assert not os.path.exists(self.index_file) + index = faiss.read_index(self.index_template_file) + block_fnames = [ + f"{self.index_shard_prefix}{i}" for i in range(self.nshards) + ] + for fn in block_fnames: + assert os.path.exists(fn) + logging.info(block_fnames) + logging.info("merging...") + merge_ondisk(index, block_fnames, ivf_file) + logging.info("writing index...") + faiss.write_index(index, self.index_file) + logging.info("done") + + def _cached_search( + self, + sample, + xq_ds, + xb_ds, + idx_file, + vecs_file, + I_file, + D_file, + index_file=None, + nprobe=None, + ): + if not os.path.exists(I_file): + assert not os.path.exists(I_file), f"file {I_file} does not exist " + assert not os.path.exists(D_file), f"file {D_file} does not exist " + xq = xq_ds.sample(sample, idx_file, vecs_file) + + if index_file: + D, I = self._index_nonsharded_search(index_file, xq, nprobe) + else: + logging.info("ground truth computations") + db_iterator = xb_ds.iterate(0, 100_000, np.float32) + D, I = knn_ground_truth( + xq, db_iterator, self.k, metric_type=self.metric + ) + assert np.amin(I) >= 0 + + np.save(I_file, I) + np.save(D_file, D) + else: + assert os.path.exists(idx_file), f"file {idx_file} does not exist " + assert os.path.exists( + vecs_file + ), f"file {vecs_file} does not exist " + assert os.path.exists(I_file), f"file {I_file} does not exist " + assert os.path.exists(D_file), f"file {D_file} does not exist " + I = np.load(I_file) + D = np.load(D_file) + assert I.shape == (sample, self.k), f"{I_file} shape mismatch" + assert D.shape == (sample, self.k), f"{D_file} shape mismatch" + return (D, I) + + def _index_search(self, index_shard_prefix, xq, nprobe): + assert nprobe is not None + logging.info(f"open sharded index: {index_shard_prefix}, {self.nshards}") + index = self._open_sharded_index(index_shard_prefix) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {nprobe}") + index_ivf.nprobe = nprobe + return index.search(xq, self.k) + + def _index_nonsharded_search(self, index_file, xq, nprobe): + assert nprobe is not None + logging.info(f"index {index_file}") + assert os.path.exists(index_file), f"file {index_file} does not exist " + index = faiss.read_index(index_file, faiss.IO_FLAG_ONDISK_SAME_DIR) + logging.info(f"index size {index.ntotal} ") + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {nprobe}") + index_ivf.nprobe = nprobe + return index.search(xq, self.k) + + def _refine_distances(self, xq_ds, idx, xb_ds, I): + xq = xq_ds.get(idx).repeat(self.k, axis=0) + xb = xb_ds.get(I.reshape(-1)) + if self.metric == faiss.METRIC_INNER_PRODUCT: + return (xq * xb).sum(axis=1).reshape(I.shape) + elif self.metric == faiss.METRIC_L2: + return ((xq - xb) ** 2).sum(axis=1).reshape(I.shape) + else: + raise ValueError(f"metric not supported {self.metric}") + + def evaluate(self): + self._evaluate( + self.index_factory_fn, + self.index_file, + self.xq_index_file, + self.nprobe, + ) + + def _evaluate(self, index_factory_fn, index_file, xq_index_file, nprobe): + idx_a_file = f"{self.eval_dir}/idx_a.npy" + idx_b_gt_file = f"{self.eval_dir}/idx_b_gt.npy" + idx_b_ann_file = ( + f"{self.eval_dir}/idx_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + vecs_a_file = f"{self.eval_dir}/vecs_a.npy" + vecs_b_gt_file = f"{self.eval_dir}/vecs_b_gt.npy" + vecs_b_ann_file = ( + f"{self.eval_dir}/vecs_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_a_gt_file = f"{self.eval_dir}/D_a_gt.npy" + D_a_ann_file = ( + f"{self.eval_dir}/D_a_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_a_ann_refined_file = f"{self.eval_dir}/D_a_ann_refined_{index_factory_fn}_np{nprobe}.npy" + D_b_gt_file = f"{self.eval_dir}/D_b_gt.npy" + D_b_ann_file = ( + f"{self.eval_dir}/D_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_b_ann_gt_file = ( + f"{self.eval_dir}/D_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" + ) + I_a_gt_file = f"{self.eval_dir}/I_a_gt.npy" + I_a_ann_file = ( + f"{self.eval_dir}/I_a_ann_{index_factory_fn}_np{nprobe}.npy" + ) + I_b_gt_file = f"{self.eval_dir}/I_b_gt.npy" + I_b_ann_file = ( + f"{self.eval_dir}/I_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + I_b_ann_gt_file = ( + f"{self.eval_dir}/I_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" + ) + margin_gt_file = f"{self.eval_dir}/margin_gt.npy" + margin_refined_file = ( + f"{self.eval_dir}/margin_refined_{index_factory_fn}_np{nprobe}.npy" + ) + margin_ann_file = ( + f"{self.eval_dir}/margin_ann_{index_factory_fn}_np{nprobe}.npy" + ) + + logging.info("exact search forward") + # xq -> xb AKA a -> b + D_a_gt, I_a_gt = self._cached_search( + self.evaluation_sample, + self.xq_ds, + self.xb_ds, + idx_a_file, + vecs_a_file, + I_a_gt_file, + D_a_gt_file, + ) + idx_a = np.load(idx_a_file) + + logging.info("approximate search forward") + D_a_ann, I_a_ann = self._cached_search( + self.evaluation_sample, + self.xq_ds, + self.xb_ds, + idx_a_file, + vecs_a_file, + I_a_ann_file, + D_a_ann_file, + index_file, + nprobe, + ) + + logging.info( + "calculate refined distances on approximate search forward" + ) + if os.path.exists(D_a_ann_refined_file): + D_a_ann_refined = np.load(D_a_ann_refined_file) + assert D_a_ann.shape == D_a_ann_refined.shape + else: + D_a_ann_refined = self._refine_distances( + self.xq_ds, idx_a, self.xb_ds, I_a_ann + ) + np.save(D_a_ann_refined_file, D_a_ann_refined) + + if self.evaluate_by_margin: + k_extract = self.k + margin_threshold = 1.05 + logging.info( + "exact search backward from the k_extract NN results of" + " forward search" + ) + # xb -> xq AKA b -> a + D_a_b_gt = D_a_gt[:, :k_extract].ravel() + idx_b_gt = I_a_gt[:, :k_extract].ravel() + assert len(idx_b_gt) == self.evaluation_sample * k_extract + np.save(idx_b_gt_file, idx_b_gt) + # exact search + D_b_gt, _ = self._cached_search( + len(idx_b_gt), + self.xb_ds, + self.xq_ds, + idx_b_gt_file, + vecs_b_gt_file, + I_b_gt_file, + D_b_gt_file, + ) # xb and xq ^^^ are inverted + + logging.info("margin on exact search") + margin_gt = margin( + self.evaluation_sample, + idx_a, + idx_b_gt, + D_a_b_gt, + D_a_gt, + D_b_gt, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_gt_file, margin_gt) + + logging.info( + "exact search backward from the k_extract NN results of" + " approximate forward search" + ) + D_a_b_refined = D_a_ann_refined[:, :k_extract].ravel() + idx_b_ann = I_a_ann[:, :k_extract].ravel() + assert len(idx_b_ann) == self.evaluation_sample * k_extract + np.save(idx_b_ann_file, idx_b_ann) + # exact search + D_b_ann_gt, _ = self._cached_search( + len(idx_b_ann), + self.xb_ds, + self.xq_ds, + idx_b_ann_file, + vecs_b_ann_file, + I_b_ann_gt_file, + D_b_ann_gt_file, + ) # xb and xq ^^^ are inverted + + logging.info("refined margin on approximate search") + margin_refined = margin( + self.evaluation_sample, + idx_a, + idx_b_ann, + D_a_b_refined, + D_a_gt, # not D_a_ann_refined(!) + D_b_ann_gt, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_refined_file, margin_refined) + + D_b_ann, I_b_ann = self._cached_search( + len(idx_b_ann), + self.xb_ds, + self.xq_ds, + idx_b_ann_file, + vecs_b_ann_file, + I_b_ann_file, + D_b_ann_file, + xq_index_file, + nprobe, + ) + + D_a_b_ann = D_a_ann[:, :k_extract].ravel() + + logging.info("approximate search margin") + + margin_ann = margin( + self.evaluation_sample, + idx_a, + idx_b_ann, + D_a_b_ann, + D_a_ann, + D_b_ann, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_ann_file, margin_ann) + + logging.info("intersection") + logging.info(I_a_gt) + logging.info(I_a_ann) + + for i in range(1, self.k + 1): + logging.info( + f"{i}: {knn_intersection_measure(I_a_gt[:,:i], I_a_ann[:,:i])}" + ) + + logging.info(f"mean of gt distances: {D_a_gt.mean()}") + logging.info(f"mean of approx distances: {D_a_ann.mean()}") + logging.info(f"mean of refined distances: {D_a_ann_refined.mean()}") + + logging.info("intersection cardinality frequencies") + logging.info(get_intersection_cardinality_frequencies(I_a_ann, I_a_gt)) + + logging.info("done") + pass + + def _knn_function(self, xq, xb, k, metric, thread_id=None): + try: + return faiss.knn_gpu( + self.all_gpu_resources[thread_id], + xq, + xb, + k, + metric=metric, + device=thread_id, + vectorsMemoryLimit=self.knn_vectors_memory_limit, + queriesMemoryLimit=self.knn_queries_memory_limit, + ) + except Exception: + logging.info(f"knn_function failed: {xq.shape}, {xb.shape}") + raise + + def _coarse_quantize(self, index_ivf, xq, nprobe): + assert nprobe <= index_ivf.quantizer.ntotal + quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) + bs = 100_000 + nq = len(xq) + q_assign = np.empty((nq, nprobe), dtype="int32") + for i0 in trange(0, nq, bs): + i1 = min(nq, i0 + bs) + _, q_assign_i = quantizer.search(xq[i0:i1], nprobe) + q_assign[i0:i1] = q_assign_i + return q_assign + + def search(self): + logging.info(f"search: {self.knn_dir}") + slurm_job_id = os.environ.get("SLURM_JOB_ID") + + ngpu = faiss.get_num_gpus() + logging.info(f"number of gpus: {ngpu}") + self.all_gpu_resources = [ + faiss.StandardGpuResources() for _ in range(ngpu) + ] + self._knn_function( + np.zeros((10, 10), dtype=np.float16), + np.zeros((10, 10), dtype=np.float16), + self.k, + metric=self.metric, + thread_id=0, + ) + + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {self.nprobe}") + index_ivf.nprobe = self.nprobe + # quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) + for i in range(0, self.xq_ds.size, self.xq_bs): + Ifn = f"{self.knn_dir}/I{(i):010}_{self.knn_output_file_suffix}" + Dfn = f"{self.knn_dir}/D_approx{(i):010}_{self.knn_output_file_suffix}" + CPfn = f"{self.knn_dir}/CP{(i):010}_{self.knn_output_file_suffix}" + + if slurm_job_id: + worker_record = ( + self.knn_dir + + f"/record_{(i):010}_{self.knn_output_file_suffix}.txt" + ) + if not os.path.exists(worker_record): + logging.info( + f"creating record file {worker_record} and saving job" + f" id: {slurm_job_id}" + ) + with open(worker_record, "w") as h: + h.write(slurm_job_id) + else: + old_slurm_id = open(worker_record, "r").read() + logging.info( + f"old job slurm id {old_slurm_id} and current job id:" + f" {slurm_job_id}" + ) + if old_slurm_id == slurm_job_id: + if os.path.getsize(Ifn) == 0: + logging.info( + f"cleaning up zero length files {Ifn} and" + f" {Dfn}" + ) + os.remove(Ifn) + os.remove(Dfn) + + try: # TODO: modify shape for pretransform case + with open(Ifn, "xb") as f, open(Dfn, "xb") as g: + xq_i = np.empty( + shape=(self.xq_bs, self.input_d), dtype=np.float16 + ) + q_assign = np.empty( + (self.xq_bs, self.nprobe), dtype=np.int32 + ) + j = 0 + quantizer = faiss.index_cpu_to_all_gpus( + index_ivf.quantizer + ) + for xq_i_j in tqdm( + self._iterate_transformed( + self.xq_ds, i, min(100_000, self.xq_bs), np.float16 + ), + file=sys.stdout, + ): + xq_i[j:j + xq_i_j.shape[0]] = xq_i_j + ( + _, + q_assign[j:j + xq_i_j.shape[0]], + ) = quantizer.search(xq_i_j, self.nprobe) + j += xq_i_j.shape[0] + assert j <= xq_i.shape[0] + if j == xq_i.shape[0]: + break + xq_i = xq_i[:j] + q_assign = q_assign[:j] + + assert q_assign.shape == (xq_i.shape[0], index_ivf.nprobe) + del quantizer + logging.info(f"computing: {Ifn}") + logging.info(f"computing: {Dfn}") + prefetch_threads = faiss.get_num_gpus() + D_ann, I = big_batch_search( + index_ivf, + xq_i, + self.k, + verbose=10, + method="knn_function", + knn=self._knn_function, + threaded=faiss.get_num_gpus() * 8, + use_float16=True, + prefetch_threads=prefetch_threads, + computation_threads=faiss.get_num_gpus(), + q_assign=q_assign, + checkpoint=CPfn, + checkpoint_freq=7200, # in seconds + ) + assert ( + np.amin(I) >= 0 + ), f"{I}, there exists negative indices, check" + logging.info(f"saving: {Ifn}") + np.save(f, I) + logging.info(f"saving: {Dfn}") + np.save(g, D_ann) + + if os.path.exists(CPfn): + logging.info(f"removing: {CPfn}") + os.remove(CPfn) + + except FileExistsError: + logging.info(f"skipping {Ifn}, already exists") + logging.info(f"skipping {Dfn}, already exists") + continue + + def _open_index_shard(self, fn): + if fn in self.index_shards: + index_shard = self.index_shards[fn] + else: + logging.info(f"open index shard: {fn}") + index_shard = faiss.read_index( + fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY + ) + self.index_shards[fn] = index_shard + return index_shard + + def _open_sharded_index(self, index_shard_prefix=None): + if index_shard_prefix is None: + index_shard_prefix = self.index_shard_prefix + if index_shard_prefix in self.index: + return self.index[index_shard_prefix] + assert os.path.exists( + self.index_template_file + ), f"file {self.index_template_file} does not exist " + logging.info(f"open index template: {self.index_template_file}") + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + ilv = faiss.InvertedListsPtrVector() + for i in range(self.nshards): + fn = f"{index_shard_prefix}{i}" + assert os.path.exists(fn), f"file {fn} does not exist " + logging.info(fn) + index_shard = self._open_index_shard(fn) + il = faiss.downcast_index( + faiss.extract_index_ivf(index_shard) + ).invlists + ilv.push_back(il) + hsil = faiss.HStackInvertedLists(ilv.size(), ilv.data()) + index_ivf.replace_invlists(hsil, False) + self.ivls[index_shard_prefix] = hsil + self.index[index_shard_prefix] = index + return index + + def index_shard_stats(self): + for i in range(self.nshards): + fn = f"{self.index_shard_prefix}{i}" + assert os.path.exists(fn) + index = faiss.read_index( + fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY + ) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + il = index_ivf.invlists + il.print_stats() + + def index_stats(self): + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + il = index_ivf.invlists + list_sizes = [il.list_size(i) for i in range(il.nlist)] + logging.info(np.max(list_sizes)) + logging.info(np.mean(list_sizes)) + logging.info(np.argmax(list_sizes)) + logging.info("index_stats:") + il.print_stats() + + def consistency_check(self): + logging.info("consistency-check") + + logging.info("index template...") + + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + + offset = 0 # 2**24 + assert self.shard_size > offset + SMALL_DATA_SAMPLE + + logging.info("index shards...") + for i in range(self.nshards): + r = i * self.shard_size + offset + xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) + fn = f"{self.index_shard_prefix}{i}" + assert os.path.exists(fn), f"There is no index shard file {fn}" + index = self._open_index_shard(fn) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.nprobe = 1 + _, I = index.search(xb, 100) + for j in range(SMALL_DATA_SAMPLE): + assert np.where(I[j] == j + r)[0].size > 0, ( + f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" + f" {self.shard_size}" + ) + + logging.info("merged index...") + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.nprobe = 1 + for i in range(self.nshards): + r = i * self.shard_size + offset + xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) + _, I = index.search(xb, 100) + for j in range(SMALL_DATA_SAMPLE): + assert np.where(I[j] == j + r)[0].size > 0, ( + f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" + f" {self.shard_size}" + ) + + logging.info("search results...") + index_ivf.nprobe = self.nprobe + for i in range(0, self.xq_ds.size, self.xq_bs): + Ifn = f"{self.knn_dir}/I{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" + assert os.path.exists(Ifn) + assert os.path.getsize(Ifn) > 0, f"The file {Ifn} is empty." + logging.info(Ifn) + I = np.load(Ifn, mmap_mode="r") + + assert I.shape[1] == self.k + assert I.shape[0] == min(self.xq_bs, self.xq_ds.size - i) + assert np.all(I[:, 1] >= 0) + + Dfn = f"{self.knn_dir}/D_approx{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" + assert os.path.exists(Dfn) + assert os.path.getsize(Dfn) > 0, f"The file {Dfn} is empty." + logging.info(Dfn) + D = np.load(Dfn, mmap_mode="r") + assert D.shape == I.shape + + xq = next(self.xq_ds.iterate(i, SMALL_DATA_SAMPLE, np.float32)) + D_online, I_online = index.search(xq, self.k) + assert ( + np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size + / (self.k * SMALL_DATA_SAMPLE) + > 0.95 + ), ( + "the ratio is" + f" {np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size / (self.k * SMALL_DATA_SAMPLE)}" + ) + assert np.allclose( + D[:SMALL_DATA_SAMPLE].sum(axis=1), + D_online.sum(axis=1), + rtol=0.01, + ), ( + "the difference is" + f" {D[:SMALL_DATA_SAMPLE].sum(axis=1), D_online.sum(axis=1)}" + ) + + logging.info("done") + + def split_files(self): + self._split_files(file_type="I", save_output_id="idx") + self._split_files(file_type="D_approx", save_output_id="dist") + + def _split_files(self, file_type: str, save_output_id: str): + """ + #Output in directory dists5_p5.eng0-hin.OPQ64,IVFauto,PQ64.k16.np128.fp16-shard + This method handles the post-processing of npy files to have the same number and size + as the number of files in a given dataset. + The assumption about the input files are all of size xq_bs except possible for the last one, that can be shorter. + """ + + logging.info( + f"split_npy_files, output dir in {self.postprocess_output_dir}" + ) + if not os.path.exists(self.postprocess_output_dir): + os.makedirs(self.postprocess_output_dir) + + I_files = sorted(self._get_output_files(file_type)) + + num_input_files = len(I_files) + total_output_size = sum(self.file_sizes) + last_input_file = np.load(I_files[-1], mmap_mode="r") + I_dtype = last_input_file.dtype + remainder = total_output_size - (num_input_files - 1) * self.xq_bs + assert ( + last_input_file.shape[0] == remainder + and last_input_file.shape[1] == self.k + ), f"wrong size for input data file, check file: {I_files[-1]}" + for i in range( + num_input_files - 1 + ): # check all files except the last one, which is checked above + I_matrix = np.load(I_files[i], mmap_mode="r") + assert ( + I_matrix.shape[0] == self.xq_bs and I_matrix.shape[1] == self.k + ), f"wrong size for input data file , check file: {I_files[i]} " + + output_files = [] + + current_input_file_index = 0 + current_input_file_offset = 0 + for jj, current_output_file_size in enumerate(self.file_sizes): + output_file = np.empty((0, self.k), dtype=I_dtype) + while output_file.shape[0] < current_output_file_size: + still_need = current_output_file_size - output_file.shape[0] + I_current_file = np.load( + I_files[current_input_file_index], mmap_mode="r" + ) + max_we_can_read_from_current_input = min( + I_current_file.shape[0], + current_input_file_offset + still_need, + ) + input_chunk = I_current_file[ + current_input_file_offset:max_we_can_read_from_current_input, + ] + output_file = np.vstack([output_file, input_chunk]) + current_input_file_offset = max_we_can_read_from_current_input + if current_input_file_offset == I_current_file.shape[0]: + current_input_file_index += 1 + current_input_file_offset = 0 + output_files.append(output_file) + logging.info( + f"saving files: mm5_p5.x2y.{(jj):03}.{save_output_id}" + ) + np.save( + f"{self.postprocess_output_dir}" + + f"/mm5_p5.x2y.{(jj):03}.{save_output_id}", + output_file, + ) + + def cast_to_uint32(self): + self._cast_to_unint32(file_type="I") + + def _cast_to_unint32(self, file_type: str): + logging.info("casting to uint32:") + I_files = self._get_output_files(file_type) + for I_file in I_files: + I_matrix = np.load(I_file, mmap_mode="r") + assert ( + np.all(I_matrix) >= 0 + and np.all(I_matrix) < np.iinfo(np.uint32).max + ), ( + "Some indices are less than zero or exceed" + f" {np.iinfo(np.uint32).max}, canno cast to uint32" + ) + + filename = I_file.rsplit(".", 1)[0] + np.save(filename + "_uint32.npy", I_matrix.astype(np.uint32)) + logging.info("done! casting to uint32") + + def _get_output_files(self, file_type): + return [ + f"{self.knn_dir}/{file_type}{(i):010}_{self.knn_output_file_suffix}" + for i in range(0, self.xq_ds.size, self.xq_bs) + ] diff --git a/demos/offline_ivf/run.py b/demos/offline_ivf/run.py new file mode 100644 index 0000000000..dfa831d6f0 --- /dev/null +++ b/demos/offline_ivf/run.py @@ -0,0 +1,218 @@ +# 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 +from utils import ( + load_config, + add_group_args, +) +from offline_ivf import OfflineIVF +import faiss +from typing import List, Callable, Dict +import submitit + + +def join_lists_in_dict(poss: List[str]) -> List[str]: + """ + Joins two lists of prod and non-prod values, checking if the prod value is already included. + If there is no non-prod list, it returns the prod list. + """ + if "non-prod" in poss.keys(): + all_poss = poss["non-prod"] + if poss["prod"][-1] not in poss["non-prod"]: + all_poss += poss["prod"] + return all_poss + else: + return poss["prod"] + + +def main( + args: argparse.Namespace, + cfg: Dict[str, str], + nprobe: int, + index_factory_str: str, +) -> None: + oivf = OfflineIVF(cfg, args, nprobe, index_factory_str) + eval(f"oivf.{args.command}()") + + +def process_options_and_run_jobs(args: argparse.Namespace) -> None: + """ + If "--cluster_run", it launches an array of jobs to the cluster using the submitit library for all the index strings. In + the case of evaluate, it launches a job for each index string and nprobe pair. Otherwise, it launches a single job + that is ran locally with the prod values for index string and nprobe. + """ + + cfg = load_config(args.config) + index_strings = cfg["index"] + nprobes = cfg["nprobe"] + if args.command == "evaluate": + if args.cluster_run: + all_nprobes = join_lists_in_dict(nprobes) + all_index_strings = join_lists_in_dict(index_strings) + for index_factory_str in all_index_strings: + for nprobe in all_nprobes: + launch_job(main, args, cfg, nprobe, index_factory_str) + else: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] + ) + else: + if args.cluster_run: + all_index_strings = join_lists_in_dict(index_strings) + for index_factory_str in all_index_strings: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_factory_str + ) + else: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] + ) + + +def launch_job( + func: Callable, + args: argparse.Namespace, + cfg: Dict[str, str], + n_probe: int, + index_str: str, +) -> None: + """ + Launches an array of slurm jobs to the cluster using the submitit library. + """ + + if args.cluster_run: + assert args.num_nodes >= 1 + executor = submitit.AutoExecutor(folder=args.logs_dir) + + executor.update_parameters( + nodes=args.num_nodes, + gpus_per_node=args.gpus_per_node, + cpus_per_task=args.cpus_per_task, + tasks_per_node=args.tasks_per_node, + name=args.job_name, + slurm_partition=args.partition, + slurm_time=70 * 60, + ) + if args.slurm_constraint: + executor.update_parameters(slurm_constraint=args.slurm_constrain) + + job = executor.submit(func, args, cfg, n_probe, index_str) + print(f"Job id: {job.job_id}") + else: + func(args, cfg, n_probe, index_str) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + group = parser.add_argument_group("general") + + add_group_args(group, "--command", required=True, help="command to run") + add_group_args( + group, + "--config", + required=True, + help="config yaml with the dataset specs", + ) + add_group_args( + group, "--nt", type=int, default=96, help="nb search threads" + ) + add_group_args( + group, + "--no_residuals", + action="store_false", + help="set index.by_residual to False during train index.", + ) + + group = parser.add_argument_group("slurm_job") + + add_group_args( + group, + "--cluster_run", + action="store_true", + help=" if True, runs in cluster", + ) + add_group_args( + group, + "--job_name", + type=str, + default="oivf", + help="cluster job name", + ) + add_group_args( + group, + "--num_nodes", + type=str, + default=1, + help="num of nodes per job", + ) + add_group_args( + group, + "--tasks_per_node", + type=int, + default=1, + help="tasks per job", + ) + + add_group_args( + group, + "--gpus_per_node", + type=int, + default=8, + help="cluster job name", + ) + add_group_args( + group, + "--cpus_per_task", + type=int, + default=80, + help="cluster job name", + ) + + add_group_args( + group, + "--logs_dir", + type=str, + default="/checkpoint/marialomeli/offline_faiss/logs", + help="cluster job name", + ) + + add_group_args( + group, + "--slurm_constraint", + type=str, + default=None, + help="can be volta32gb for the fair cluster", + ) + + add_group_args( + group, + "--partition", + type=str, + default="learnlab", + help="specify which partition to use if ran on cluster with job arrays", + choices=[ + "learnfair", + "devlab", + "scavenge", + "learnlab", + "nllb", + "seamless", + "seamless_medium", + "learnaccel", + "onellm_low", + "learn", + "scavenge", + ], + ) + + group = parser.add_argument_group("dataset") + + add_group_args(group, "--xb", required=True, help="database vectors") + add_group_args(group, "--xq", help="query vectors") + + args = parser.parse_args() + print("args:", args) + faiss.omp_set_num_threads(args.nt) + process_options_and_run_jobs(args=args) diff --git a/demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex b/demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex new file mode 100644 index 0000000000000000000000000000000000000000..9cd6a19c26bff31a24ce9430e5492069cc961eba GIT binary patch literal 16564 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%0AF73lUzgB0$dPaR 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 U^FRM`;D0g#x!F0n|C1#6UvuR9-~a#s literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex b/demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex new file mode 100644 index 0000000000000000000000000000000000000000..56b70276f838658f80268eb758ea74abc4d0fef0 GIT binary patch literal 16891 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 UG_1|xq{1^qmtyd(N>l%Zb9ab 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

6ZG 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 new file mode 100644 index 0000000000000000000000000000000000000000..5f2f4ba5a3a60b404c37001cbd8e21fa9e8fe719 GIT binary patch literal 138612 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ɒ)BSDltUTyg$I@z8tk)Q_~ruj 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 cb(n+oW1ww^VtjIJ-mf^czC3AxNraS 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 YUY~cTyS_L_I2H(|>(~Cy`Z!+yKdP(-Qvd(} literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata new file mode 100644 index 0000000000000000000000000000000000000000..4726d998866def3afe805d17fa3bec4252c8e68c GIT binary patch literal 360000 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 new file mode 100644 index 0000000000000000000000000000000000000000..73ddb25147a9759a5405221e0d09d097db6b3eb6 GIT binary patch literal 138612 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%0AWfW-zB!ojMP#qiw z?Ge~l;4mnOU^;=*;1)Q8Kyx7z8Ytow6gm;k+2HyBcoPi8V64Oaf4?XE|JOE{g@;vJ zW#{KFfw7>0+Ro2!fNzljMYtD%`==nO_Rb$q4*mowj_v%sDfkh*jLbxW3djzd-p(IC zsK3KMVB)LUPM-!ZMgBbp>*>OKUOxM@Ul@y{N1(jWAS^iDFk-8WrDLKeE}iBjGfKiPZVZrY<}!a`|x_a%yn}N(7o?rospN zDw3wB%i)U*o@l{`=rAF?t%AwubUH|e;nqc`Ey3OR0OSD%|NB6M&bNRj$iW=Ee*&+d z>xJM0up0j5;lCc-0?AZ%?tUKL3$Xzr@E-;LJn$O|=7LG^DF~lm;co`r_a{wqOf>vK zZ(^&ET28u7Dz*EWWQzW8f}c+5j+IVVyv-~o_$6JL8U2iWqWoPe_xaD~ICK6ql}h4c zBQ*IwxL?Y)x=K;i+*#SXe~#9u-&^s(75}Qjeodz33cJ0t2TX>Ivk7Ruq#R8|{iP%Y zGPNpfQ^Ht1R(aC2j*#yoU1$2?w#hFs!=(CD%#=Azb;7R7sZLYDTPjQhef=o3^Zl!$ zr{mxcFblpt(a$^J0=Ns_3qc2X7l+r=@VFQLrr?hp-Wb4x;5wKHf8W4XcnpU(Jtg!7 zoW!PIfKO%kltf?egU;w93%vD%tDq4)(!k>@c&z8K*uPPhdVfqM)#kG6@40%aROS~# z7tLjCHX~jV4+^|r;JolzEXi&;X7u86!T5`#5B?lki}f+yZd!kqLQ&~#?N;Ug_vSPD z%e>jIxZM8uDZ6HC)o^nXcTy%rd^jilV{>YB-xVD>^RtI?m}-c|eFk!a{XX*eIV`&< z_;(8rJJ!UcN7US{AvP+`W|I9_sbQ&0503KGT&!?ru+%90@q)!EC7tABlCw#KB8cPn_opyRxTz*;{yaqq3DqNLHfl4nQmmV9GUXs)aL z9cCi2Qc&UF8`+&cs`1XepD^jqJ?HqnM~F;LZg6*a?lDJC&w+uU8e9j0M#4Mat2uwH0g9rh26%Vtz+^bTiQb+@Zznfz#( z^ySot%x9Z2$nRu3R|ReD(mcgr<{WgJ@@LJvMem_rRkQ49qa@3OrNd(h`u^zyJ;nh8 z9weO!l4j#ci=x)6QR3F+JbA~yx!Im9r+J z+FiW^%bTTs4LUmpCAeOEk$NyckRi_dYQ-_R0nqks(f!MO|G+SlMX`b~{~--2@zot^LFE@+6Jn}f%Zg?nHgvOt3@ zw2Qyg9Nk@e;qPH{^=iKlwl&JkJeAV&{8hoVZ%;8@QL{RIRTo@AsujED;E+~f!t334JE7s2nyf(o(_fD8m712S;l4t@mxg1h0K8?GON%y8}t*L~m= zcmvM+L1yfO8(4>(xQv}}!JF_MbWz#){^G%0@GbZNzjq@>mZ*`TJg^aDLZ*n3DK@Yb z90o0swdbHZvKEGn%_3VbkS$MSD+6@vX|Q(bSfPwPx%cd+oIQURl2mq;jvd$?^XpoW z@LQ+iCHg$0(oSwY(XkcJlG_eF*T)R0caJVCe;gv$TN@|CK)*i~$cU5|2Pf16l3>4zIR zQ{7*m2zM9v+6asGeCiZS7Uu9g)wzB1y#UvA-%$?TIu||njLBVJhRM2gv)^Tx(UW|c zKN%CVJMD{sUe)Kz?KS+-rGFf&(*rHWX75P)b79B#~Ou;g+A1p@h`ms63k-HF(2Jh4!FcTEO=gK1F zj{e_!1u`RVOUTl7TTPTaYi4(+@%|NS1Zf98|AsQCVZ1zwe&)3yt76(lZYQ**fj znJfEqSKd%96}Nl}Th~&%k*Bgqk`%7f^ul4vsF%2{8u+?gU5eqa^&4%~R{6@mQR2G@`yF68JNn1fw&!JajO0?3gdcp7X%j(%XTo+CHkK?~&NKJroZ zFDKY1N8}|FWI`E z{-pqE%vb%n2$4fZw4{!n5#;K&)M8C7A-nH2YY}Rzzs?P@Z&KFr){6Z2vnM*=DZ;2^ z_IfzsI?;0n5%QP!S_*I6TMsLqwbzOun7 zj=REH9%z70M}RtdJAb?-*ae2cao}K>*aU;2eAkczX-B^<-Aj{Cj>{=|W+yX=qu=(o zGH1~@R0?%pyYTLD)bQ=9c<)PDRANIJQ5N%+!p0pP4uvm9;|S}MiiwIVrWh8ZX}vf4 zBkh(`BKD2FejT0pI_BQxEaK_W%upiPH~0AJ-m4K_j-DeNe`cp{HKt)^lo3At+~jUp zPg1E$L3SjOnIVuI*|7ujz$s+u1hUkI9mv5uQVt%)F6bgld$9`y z$W%Od0{y=M(jrU2;54{_>~Ns}Szs~vgY#~Bm4uqikvH^DNM&y>gB|b z)-wu@S2H=N!dbcRJj>&K zhMDbWX6l{?6R^)7HB5LRF7CM;Opr7$dua6A@nd`b{tc*>59kc8{Jr;d?e_lhZ&v41 zpKu18>^fs(Dt&rprQDL_nfyj?f-k2==1t_{zkgfR|G$>OP~?LV`3M8WkOP1CJ`c}V z;B^-~Hi4Y*$OUGDn(#USZ|d+yhR>h2;BNTS1tUNq_{#xl;86uz@B^&FCYWOr=DaAmgI_jf;d34+`&gi(l^|(I%^quXb zk-xI>S94lh#~SY>-uaNhaQS;}XkUHjosnqyxC@GPpKBE@Zz|uB&Gz8vUh`hcX!TC3 z3O^Op)BElHuV?Rh{$-T( z{v|7RKMamZ;P?XQite8WzoPs1MRsmPfVVpf?gQX_6t1J-widKPR~6xw3!OBE!+vlS zBtbWCfOK#h0FHp(Dm%ZP`(QgLiwsPn%Y5iC2eROUENp@t==3Nu@gAH3MUWA5uml_d z1=0CKU@vHltlR^04Eb#`BmG&d7Wt2#E;fJHHFNRSNZ0Qx!Lg=A9dQ*kr{|=dMq>jv ze!HynUtK=Bdg*}pA8T6zh4k%{z1^WN_H^?+^RZSwpWf3MxMHbVadeQ@^G{YC%by8b zg`%LYJ?u4emMk9{Pb$<$l&@#2?hPE|3sf1M8tfk}v6I_=r1WRhi|N&b+sTTzHq{F! z?Ny$%=F_~(I&avq`Uv_G25f&)G8z6*yNFx^_*o0Q( zV-EZbvLG+n$jdwAMGiSB1YaO8qR7iFkQ7^R5Bvg}A~%g-A#xyx9E^Zpz(C}}0l6SX zF6h87AQSR&2Kfj8D?l~)zXYDcW=QGo+-VSOze;Yntz&T84BV~@ z+>cJ}!Vas0W%jkYtv~->s&VBQ-Eca{-tO(K*DkZh_WL`l<&yor%U_#WjCz_M>AiR7 zI92V%a)OWyGS(lOjaxglzYEpPU7#xQ-ab^SKX#~x#Pwj88?)D%s-tD8 zv7}`e`RSN>4P%!t^IMcuu8S_U?us2^4j(K##jFJXE*o1`%hX<96x~O?s7}}Y;OAmz z-CU4J98ax&kAFsSy@0JpDfv^K8g(n$3(ku=8FLxCJnZ-Bw5u+ktyvdws}ra{^}<+& zvc&AnDIaVvv+z!K8o@zytO_0D#_zAR;V%Jv1b_AaeBwPOMc2-OXV5tZFdh61E~A5s z$bkyF*bC|+7k*$pXn{OLgG|_XLFAwc)IbMMfHcSf3upj-0AC;<50H;xP!KseqrG#l z51<9Q7yw=d?|{+hXe@Fy4B8@3RoH6ntK54d|I%L3wA$~vDk*$#?svqiMx|nYdx`D? zlXqUxA297r;AY;x8M2q+DDl~IHX58CPupCa`xEIi=QMNr^$f4v=grr2q6!DB!bBrj zKH4?=6qO!0PN3v0S(NE`sMtqiL(5@`ljt6af=k_-pnG!X17lRk<%kx-m0dm`kS!YL zX6b(AV9qb9a=L*#l0{fU`*~D$^IqXw+E+=6N&d8tM{HkXCl0=z^jfK#%ua$L+km+@d2-bhS+WrxT1q2LO7TJ z#o*!=_z1Ma8&Cu%l5k)L=3Hwglb?%~kojGF21d6H+fFF-6R{LP9_ar&?IDy36&3O6iB`r!CPe&HNV!UTVU=iu(L;d z1b1ix-a*fT;3gK#0%hRD3QmaN#0qowL}N%BGF25AZ+cBMJZ1x9KH8<~Sr3zB}xai8`w3UsgH4-)EDMg18%SDys5*yAXl&iFItvX$)%wDb7mvr}? zPt>X?W0ex^iT3lO!z%&Gv?eO&{Axu#S4@t}9qB!4NtC=Qm-1ubWK@SZyMM}2uM>kl zqN#~?Y(HO@d|`kSMmP}w-N9_!o(i{>!fnIAr{HDWnjW{V1{-keEZo!zH?#%)aJx@n zDsK1^w;BVP(TQc;tPMMK3%5!vqD}4>4at=jy-Uh7trG6U^Cj#D)%_-3f_DPGi*o|v z(Vvs0KDIA199vKx{yIZuC)D|MviMVD)iH`lBEojUa&F@2@?}A>y9Dhw{ zX1&PqDyWAXpBCB4yAp1x3fh4G{mp3q|7yieJHY|)INp>n>=gxervTKz4KIM>*c)ox z)CG(KrEybz-1O|Roj-psct~gG$2Hg;XXKOe-x~l5!NDJpH#1)FaoEFibCt1fcN3C# zH!|e!itMu&(z-?(bojR8xw(|CR_;szDw`5#EAH}G{q?kF50d_#gJId^=L$1(J)TtB z3h@tgw1#9x8}PR`QQ4G>efs$15p`43^rh*E=#vCt_#U%y#)i|>!r%huPX)nQ4D^^yHSWv9EZ0)_&N?> zpTH`3^MJQf@EE)`!Pm%F`OU)*C3|HjeXnGHl)qwWBVzNRU@`NT%E9yrw@XE*W|p2P zOzo?<{ON+}o#{UA+uXmzf9Wqyjx5%1a6QOKx=bsdo*BDbeO1V7l{Ge_dW&!CZktfh z@w&OK^sXuIl@YO#Jx}avS2FKESZF{;_Ta|u=)`UCG4|#xx)2F+Ap4zgl7ic(U}r|K zGv2s)8d!we6XEu|{t*rw!By}u97KV~;i3Sy&&6%Ga6@I>@Ml_~iSL^-JGp1J{L%^3 z&eF+Us$4Z{nrzp4n4i={@;t7%v2QK0hu~K4t9|s9`w5>`?J}WHj0{UOp<_HU$mhUb zsn7UrsM(HnHCamemVf}`U?js@m8J|`71ci9)ws%M-`dt>`g`n^yE_;qQblajenibM zR*|XFN9%Y$t)}&teiCjml-6>9t~+1TKVFq=C6(}}WNR7j~KxpC{OnL4NQZxPTr14SHb@>e2s~pgsCei|mRR5d8nk z8vGDOack{in2mLNOW@o6Wlz4nCfuX^T6OQ0_IXoReV3zGj-nY~PL`(0cUI|)#~)_BBFBOpN7@dY`gKxsA4jGt^R&Fz<*pYR zL6z2fh294k$fm71agAgsF2?<`rMwv+<-sxbJ!t-q=HDfGbk_mQ0hd7=bXgVNUEncgU>2y3987_H$iX~FiyV}KZ;^*!ybal)8*&ke&YPm!+vxT&*m_QE zJrD9z3O)nl&`&Befd&!&BRfsmGAGV?!G^z zHkrw;os@osjC+hJ-e#POENSqB;cDP`{Lyr?H`S+4-{|+fNc&{)_x$J;PO8B1`ec@x z^P%thla@ za)zz&%6E36@&T#H$wAZIfuk%$w|`%1n)$F#BR%LPS$R5p)aMb&Nbcak_?2ok>?W85-U3sR6+L9d8yOh{mywkiWF;Tmz@}WsrYwQn z$dV#h0(ODf$k0vHTFMfL=cwcU7!GLSVAWbG&z2(n_+gu!mm z1DQ-j_Pmj`Nbn{yHV<;){V4#e!M%DrnccwV#UgXdVByr^yaK&tb3q}76C%2Lf`842wC+Co87yhlaI&L}do1d?Hoe8F_=%u8fu8J{h@kcFpkstKpRKwY@B0j1&0 z8cYSh!Qme`ya+d;a8m)Az)28p9*&z&f=#%61a2<-!g5DI{dS*FEc2l2)L zeTB$nDLU5H^T!`$9g$|84k(x1{^GY7)Ft(;_3-VH_tG4X+Uf%`zH*lT8j%wn+wi5o znRVsl_tpUM#g41e+dq}rIeL^BZ)`BKH$OdZ{d`oyXL`#lX{3jv`q$B`bkE-^>!(eK zb8lq?J}dYTELxf6<+FAYckBfhM0R`}z+J7uD9{jh4hDPC$!6UBCb~(7PR@ca;G-Nq zjNoAi6hnu4!9BRYIqvTYzCmYr@a}hkOJEqf@);yXH^{(z&;(xi;KLatzd9K0b!nU{ zRBPC)z%twA>G|I!-+WSI4qUAh5%3!KV3~qr`=uQdT+TpGC25Uh%I3>sKUII5kCO9?(IpEd?ZqH*+cfs)*x+M&! zV%Wzh@FY5w2!_Ee5ju7gG)2ekz!k6*j?2J)bdU#KI{~MuLlWm1!#($;3~i8{4?j=z zHoNGD%*vE>V)|#8F-G)LRSwe*NdPq+Xkva+KanWqDm5M!VK( zqfpdqDxIlv{CLK3E#t10Bswzp3h6R;(H~_he(W8(;%Vb5w~x@fu%vxRNR@beuKdTh z^LrV~7X&WWtZ2w2wsT+X{!Cy}9Z(~aqCvuPXRe<)+3xiSy!{4E5AJkt7VLvBTlf(| z2gkt!@E{A)!NWz|KLm{V_ha~Qf)9T%9zF!oxx=6Y=nPhXV(?WBo`$ytd?rtTpDj=w z-L!|NdT`*_&i8AE&Afz8?uI`p_*(%RUM1{Pr}SY~N&P`g{;ATurEAmPmf#OVL`Wtd z_uZow5nY)w^Hk~bGeytH$h&-qY)dXO*@h{R_s9PUQ|GSqCJ@c$)zPhS;!!!tOWvA9 znD<74z9~MZQmeC0M)Urt*?eO)U0y?tIRT}qg?5b`0dcFRTJ+a`?=Y%ObCvB?3-vD- z1;U%M_tS)$+p90!+Sgz9o4=`5j`t z!^U=lwAfg6&=cOh!FQk(`Z$J-?SSVQcvOZzGWa8dFL5vu-oAn=@b(JSg+E)69UjL) zD|j3Nhe16-f(!22RK#8DP7DtVC`=6buk)5^RLkV5YpKVnmXbdp?cFcpWvS{Wa@|}s zs5>mqE01?Une6b#1DJ?6KBa!CZ;Zi|6gjr_ zHaG~^*WlU!j)TzQ8n746o#5O6&W+&O9&70lfmmc<8Qj7a zyhA3oz=PNV7i8q$f8Xmd-rY~&L1cyx+pG-+fTGv{bC43**$wg_JECAPI01e^mSl8x zwxI{4#x~F+LmJqGTt3$`Gr3kB_V%YT3Q8YyHO(nDsu!He*gxI(F^or6k?-*H^#2(q<(nlZWm!SmS#gJpqy`?lxY7v7VGGqZl1+7{8e@AjQ|TA$U{m3c(% z-t+hW{X1zz0?}<2bo&eZJ%+zlkPW`Pu*K!@q6QDgKv~?|9``1}T@T@2KIq;ixDR*x z2+HD(YXPHiuV#=L-4n!}7_K^Hr<#4NHdoNa_)$6@2auSQB&Gk zr#I%LZ%B>=ZH&se3jcUwmN&}Ir&gn^Imu~m9H3mKxe>r-%KwaU_r@xNGRXpiqUSrd z&*y8HU1Oy8Dcs$pCGBQsaIZdK{N16P)A6-}l*r_H83Dn&7sW)^WylX4z3SQUD!FC< zlqYU~1nbgT=U1?%C60^Rxq^1{(ea1xY5w~D|XILv~>V05Yy`~S5?Ozlm5}$cw%Ofj>Y!_&o@(rQi$jEIu!h!t)ZyfF4T0 zZzH@`qHq21+laTT1AGrApl^fV?yqK19)v`DZ+blF^(1)o+l{yBg@_n$zo%YQ5w+(d zc9C5)0lNh0o_Puw_3Ki&4qmf$TALjt!9UlBejD-^xrIY)E< z91m%6S*Yf!XnrKSCl&PpT>{$l-L{5dMGvj++1i2C@thmzosUXPPs_p=Q;am zN)q1lKq2^+1+_s-kO=+d057Ar55Qf>NdovAd6+>C7C}?&vmMBTe(ND0!Qd#k1rj1R z>)<)$g%&yC1a(1gFdm!%*TDzK&lvJDkG!xU7kpqlaxsbBT?aS7T-}||JQH9S_Fy0K zF$wm)6gq$A@3)H9-FNmIJ@L;xQ@a(?^~Z|)PmW1{)*X+ji9c2=^?!y~M&jT1_pq6) z7#Y@I>>jJX61aKw*5;F~@gN0{z1zbVB%ar8F^$w;p1FPfs!#Xn_fO7nN@|@>Idd!L zzkeuvz{;xs)ZfD_S#0lzv)R0+esg7=KRIe8-JM;(_jH-$k*?A$pa1?cM|og$;#7B! z$@zfvQ+EfiaWzc*$SSwNE}TFfB0+DFo$v1^XaK(Q#^M?;>rwjub28yqx{u;?xq(hlqVwsLAKwHyhE-jEzU4RA9*`RK9<{JGN$`#F{>Iqza?FBuDDhyc zb-jQf3R#lCmS|!_9PnA7734?8s=;M24jZ!#dLeuJkU3lMFSw4kX+N?T1Il1? z>OoFyj|ON1CW33ABQ~f8%*O^5Aj{vu0&L4qWcvWJ{RNrbkIddfHrf7t=D?d&3LZly z^}+j~4L&25fg^ak!jaW{kRDlm0`?)Zl*p_Wm=BhKV%RQyumPMU*v-pBL>kf3IGuli zDDDC=8PNrm+$KqfrVe%P2HL_|V$!u1wYdG<1aVT6deLUz)OwsFLdvAnUbQtjHzj{m zQR~=eqZTW3PbbPzwUJk*Wr{qvAcTsXTut@uf!ru&JC)plWVqIcTLrjehP!(38{8?t z1ubqLfSWVn=0`v^&WOyB zn%@_%$gejjGA2e0^Aiaj)|@A>Am0D+L)iDW@4nNEf9-n-Q}fF6n20LFm{qHEpPH{k zT~!Y&&+#?UT{o^09*~|^xy_K+{?{>4ZQOp+C9QI5##^eFOu;)jCP$J?k2&m3sH6IP z@fFD`3Te&W>+k(n?Z%uhgie?hhP>B$vm{BkVy~=S7`3*~^i%MKDc%V(KeZuavW^dC zyy&F3(9W(u06WmlnS(n&p8y|);1BRAI>-c1(qJn12=szK6?D-S90p7A`5+ozS3!38 zeT43jqig#>dUVVbOb1ipw+eox;ddI{lZNLk@G#zqcksIn9z=(3!}A2V1Uf(YmS+EQ z?KyD@`_udJDGxqoZvE2g<|5P>bgR`Erc2>JDJjd#;N6n<;qX`s%fK4(hx%ml%)W^5 z>i5&ywGT#|QwC(4zuERpX6_@L9b=Z&Hc5LNb^G$-dghsC@`SNP`&yIT1TVOn!vEUW zx8$(?og2DP+rlP45FOAbJDad}vV8E^2ui@?9e9jAwBwNnz7B%-K~s2$ z1dG5P@HPDK{OcX44L@V(-$C4e64Zo;%ODx<{|=is0g|I{N5EF}O$Xcd6a0qvSOE8r zN8cpSw=jd9@6(w2p)Jc@R)4vs4zuI?9c`=Z=tz!GK9}S?=4?VAX0MS-uqCO~;C0cM zh#{4g%6b33JmvWuuewmkH)P$i<`D~a$&M&<|@ke61tA^T-P3HtWbzBvQlg@vA8@? zHz~Tnn@q4sUJ>(1{lqm_duE*=8I!3#lc#tix8UtCyoG@E;0!$GqmR$PMerK@N}z9U z-~?EU{tbhw@L2=ig2x#2${ag-03Of5pAGtS3LcX|ZuDmWoQFqFcw7NL!Q*c9OA|iL z(6d}{34938#_+rkoA)wt~O(hcWsL@ zn++q$SBt%g2LJnyHf8E?Mm)dE{3c8IJ%7z&pL*w>E1IojiuN0NUY|Er815~p{k_!| z`rp4#E#|7shR)&eUsMVeJ$IS4zfgZa978djzuA;g_({)0U@455FYs8sa@U?5znT!{ zip+*V{!L<;^$7xN?T!7XcrD?09WJHd>e(RE%XEbg2%CiX>iDbZnlDAaH;`TgF$fH1j^v^NjDsygyR^{8*UH7 zX%6^nh~Q3eX3X}lzRu@H{qJV0``YhRZyoL1yw&ivC;N5chYm7D*6#Mo*7$R?>GY)! ztlNv@Y6jJASiVRodp>eq@l@)uhnpSmzGqa2g@%>Z}L1gW9_YYZYmIc-( zcWZ;L-;2)rWBFjKqx)gzNwSppkA>svXcul=?VifL($_v_l_s8L^?EX;`)y3F(Z=FUd7uXz zy2D)`cmxh<@cAYPybH3Ur^mrlpb{K+!|^FNjRoD|k_ry*f$DI17A~j26L9GXPQodh z?#_Km!6wiKjyup(i3gJ&D+|IjKKYZELKcs^JyogZ3X8}yd^OjqU-9Yl7@b>hObTW1 zp;V$?FS4QqE^oJTD+$p(Za%r)=N^-+aLMomcpmDsy6s>_p`oCp@hfu;%APFUqckx1a^LXR$vGi53ix{ItM;MN5{b_ zFa#d|!lNI&4S@CV_W<59;D;RdHwDAdwK4DreCWYPEcVh3clN;^^5CwY!ASj`?`r~F z#hq(8dn9iM?zZc?8po7Xzi4L3x|?`{W}d)EVkxEd$b3`)r-1k7Q|c4)@3ntsSvJ~s zD;D^lzSP1n#@;x0?0A^t*zHF7j`!j6m;ZM8-ySFAdB>7JRl_wOb>?vLo8Qk1?79z= z@^4&L<=vFam#~%=QyUMwVf^lDF3IS{~W<{TNU(9@CJI7 z0#7FB%?-SF8F=UR!kY&?5yO)>Xa@cT_0XS3;2eAsqDLg?jVgE!J}1zZ>+pDZ>$s>! zRp62~D@!*qm)|`9FUBuEBhqi~ZJEdGukn9aWjpcJF@wJ|`h{g?XiD#JcvWyQ`M~)l zry6mx`_E1P43CM=g?C?knV)jLjHF|wLxbyG_UmkkH)NZl>mIRlQs5jor#f&cyY>;C_>26|!Ze9@^gxM~6Eux&yS6HoA8KjttPXG?2=khn~VCT2;uc!1kuhO*=7F&B}8Y9(-cWVfLlV(Y)7% zdZd=M$qB!xt1`uC#ugg5M~4~usSdb1Me}<&Hque7H=5tjh&B5n)Z~3_Hk9z@V$=QW z{?l{^eWRwljJo#jCTa4H^Pis1_fBrf{aH{Y^1bXWg%&wkiF=Eb8{f?}&jT$NL~NIo zi?yi8<9xrG>ydwbCOW@FeBCQ5Yy{3c;3^qxhBG#}5(XdP-Fkw)?S?xEupQ)r8xwE= zj>6$)5Tu5iS#TXZ3s=9H~NfF0H})AUWJ#26N!J226)jo@4)y z4#5M^+hFI%L*Ov++CizQ%O@@Jd}DlHJ+}U_FhFIhJECh=D9i5u%1h6p?fbd6Z69b9 zn!aT-xb$^ak-hya6|#M350#f3N8|U)zI&Jh8OoGTdWZHcScG{0W+G5NC$B46`jjj! z(69Y!U~;U%sFYon+*`K+IfdfOf0T9J-%`wb9AFW4b%G%#W0N_iuR2Y5=!!|GhpwEO zvb8%rQeZC~Kx*t|HYf>?zu?gU9s|H)un^s>Mh7>rmzUAO0ZaX8-FeK2c4k zqEXi-NQf!w#EGNtT&yTL@hYStUED4`CDmTo{D^j_OnL9Ei+c-uZm$p}Ff)mVa%$*@ z{=Uc`;{WVTUe1rk{M8C_Vg;pef>rUADD(Ry6l_HW?U_ErWHp~{N*R4xn(FR1MZUPD z6;ts_#U*L--fMFk!W+^Tc}Z^h+$+xBs}-trR0>Xm&`ox{iGtv7IF5niC^)VIiQ!fm z9j(RQ#>4SLun8oD^BdqV&<}gejSP5!!EiqgN+Sc2;BW9PvM>R%Ap`Vq9{^G!1G|s` zM=%!L234^EPRPhb@CPV?P3Xf0u%PRLU>Q2kh)m5OOA2^v8IhrGbpN&EGrmxbTW0s& z>MYis*d)mL{8jCQs^zt{>&Pa(rB0B#S89lBrO(Y+RFRV%N@XN;Je~Ks`3aqBvvr}f zwx1uttdgdR?`^V1pC5E;hmyjGWUlaO8?VmYwI6lnb<2@nb?dh~?0A}AUBl=8J%OK^ z;f~By1^fhNASZ9| zdk=NwVi0sdJ{*t_O5}kTw1fXva2lLP4y55<1Dt|)cWglyH~~I_?@{;`hff0dQ-e1q zZ1zL=ss-8MZ8v{y`VUME|tZrl`*^EnDl;|5KIG@N!V4fw( z8}RG0ef7Wfd&QE%Om&1+X~AKHZkOmoMt%2OGYa>(AYu2f zZwu5iEU0P*lw;H)6$ORge$U$*%JEVBr!qxJG&4Wbvh>mlYmU87@|9`!tt)q{@#+gO0l*%5_-Ze@TL5m2*WuL^UVni?@Mi#jMxZ_D27jFJHG{s^z}FTihCUjBAO7_c{Ud|NJs>Z({2)Bq zg6?>8ccX^~^maThz^fp7C=c$ktBbx7Yr#5gmt7!2y~!o$`ee+I?9Z~$jKa&M2Jz|T zf@g`k*8^wUr$)`46Yl)#dwai^N=zP;ABaVFSsE9Zv)xHqTQ_CQvt?wG-#n!|5hXoMS0f|Cb#0yAG~>3N9-1D zZ2fO9Fvl~Qa1DrB^uo_+^yvwx1V61HugK1hoB$)hd+;RyUpesP3Qz3l6$L!Cg3;K` zzJI-fH&J-I2TGw|+xWbr0e=zjmWWe1)-$5!Tbrs%Tsd$)RnzjMZ91N`4&-rHKe8vnT6cCy)I&a!Lq=P^6k)nkQYU)vUC zOE&Iul?13Vl-BdRKAVFF8ua4~`j7}};ohvc_b=T07w#>EJDY)f@OeW8Oaz;7_d?va z7c|9v+0l#N;2ho~1>DyaTn9;U=i}(fSI|>u=dRkwJvZ+A#9-&==LEc1_~&{WK05ML zJIsigYSJ_&kQ6j-G&=E`@-DZ%bCl`o74alrC7q2=YA|A05!fazkJb)JXf#qwf90=u z+}V(D#z39tN0^uTf~IOLcZlnwjaEs0|`xQsSw(2<##q)EvniY8mINmiLpj$uuwWa#LevA05dsw=*Kt!EQq4pC^<(_*p zrqsh9{Wa^Nee~+c4;<7Wa;4nUXcm4^-KRk5mDDl|4>nE%q=v&0I3z}Q8sM-KdC6OVn`=_};ko!FyTLSiC2L;v4R?b0SXlQ?C`yi+-1 zs+1&(=sD$71gg&5=dH7jVM_YbdYG}kC~Pm?XXjO=(p0HGc}cXAG5gK_M49mKTQE0~ z&EsaRZIxVQvmv|nbW($Uqa=)7u|ezXuVega+uU52_$Dg#X?{WWf#eg!@JGTnTPfKu<6Yq=R!| z@Ce+?fZK3S4)-l!E_Q)dW#`vl0j3}e$B>0ya0}E%HhzO|kd19*<0i78s=M>Qs|{L$ zH%P9v3e9&3cWH*5S^V$6@ZM&sFZ4iz{9K!=9z|?Ri2g(4`IARg)sJ0wptOFV-9(wM z5pPK?MoQ_`5*fJEOcUHr+T^yV-{S76`qg^cahIEzW}{wfOVmLD!zS0F3oV_sQa9Yh z44P@$I^! z0l2w1ZmtE+{`)a*{TUqow~M%aH*WtNw{HR8fu;@O6J*8uF==6jH0F5)u4#Mf4l#GL zcOT(qccE7!aM@ePBEo!4QJAs8T*o40^(0yGfpbhGM^2hj|1tQXDu~Q6M9)HEiF##Wk;p4H$jvrNYA`m_zz)|oO{M><`DX;;4IPi`M z!qW=40Z)g~1tR!R2Uo$p@Dd3&gRkI80-NOpFTNlNHmegfMOQ9?9PqRXGQgKEXb;Z9 zSG3m12lcDW!RoGC6KW1tCF=fHmF|B36+>=2N2O~G@XVvs|5-E|22*+I|pA6K^=HgLXU{xjS-vG z2T%LqClCw)xA7M7z*i$Y(V#~K@YD|WVY4jJtFNFlyv@LqAUwT6pG4rN0&IbwYv@ru zXo)`UHQf2W7wT_pcd--a|2dUBTm8=Q!~FYeX&oEX53B3QayMu-*1E=L3!jhCzRipa z@2j~upH;oBm-9Ji*LK@>)4=lihu>>*$a6bO)d!aL#`YP4a&u6=m7jq(Id+L|Bm-VR%+v>k=b)Sv>_Went zPmsJm6?(lOKpEEN+6ZkrUo;?Kl z;I9v)fJbM1b~po{)?gr*0cyhMEASb-wxN$x@T(5L)!5B=^sx#23<|+BGyKYdTi`?Z zWkU~hKvnoQ1JA>^GJN}ivFKwwsEpr>M1o(zX7uqa`naKU|B$Zk0oUsf5`?HJKAr5m znHTIyU2X04aKrUu!(?k$#0HIU*hS9x1i^D26fvJgLMRUQP>P?Lwwu#0BeXevv)m<< zqFsfpEL4TImLkCVQwY(?PkED_H;%Pu#!&@qiX}}2E`|l1TWU}XxYk5;YANFAxwzuj zo^Cuu?i33lhR^qqor|}7^=|RtJ?c+|^tyurJ2~9|Rp4JA{;lA>5v+x8Pk3$y--4s? zo{0C50ej1W9FF4!6G!7J?jbL4ey2ple6asVtBZ zo$A5OlW}8p+?E`--2m^RL(AZPbcql*zln{!fo?Q`LU8a6H&4XPnQ(I++|&;wd%U$K zm9Th+c5Q@$VWyosGWW+a-A@1tfaMDdlt${WXlSbm26T}NQzX*9)+@HWo1_O7P5QpdA#eN*SVd0&$)fx@6YG^yXU!2 zH}5_DbD_|Fro4^Y-)}`O_f!7&TemQD=}I4J(R%D!ARV0-O&9BS-zZp&>c9UCVzqSW zr2^w3p;hZ|2j5$E#cjAu2rjyeutYGuUCwu0*7>&eLhSvc=ej-L-)iL>KRET?rHHQg zJN=nX{XzZ}{@)CdJ#YEiwgz1Tw%VPF-7&Soz_wXk? zhD@@Ni4yj~5&FO_xQ#s#!=6aP>(CgPcEMZ7Py*R~g7(PjFtQ4VHn?}>$gUWUK|kEV z0C*3s!3Nwxc4T}68COFsWNn6wWt9p3|3d*9LLux`GMs{sx2`UMMwaT8v>V4K?uc>=Uq)>gn*Pc;Z7UUB<^I8dm&7Yr~W5Z$+W6 zRGvGjkAaVY`%?yzt;cyr+!wgUW?3j^pD@^`*s^BFby~>J!<5$=_nCX(PvpS zXzp3@G0H!ypuWDM;PObI)@?B-%WL&AhiQkD;d03K?d`67#jQ{Qwt^C>X5*)PvsAc` zOSq4-=z|3Ma2dZ7iOR=_*6SCJKe38T&-G0Yj52v2oOsjGW?gFe*b;*ZX|L3USGmmZxwq{XNBep$ ztr+?~5enJ;+TYuI=2-mecN4L_Wg#tW&x9Hohah80 zWb6T_ktGwdI{~jibNC%9;TCv6R%FeIOsk<0vfaencn~|D3QdvuPh?twH}EUeLZ)Z2 z>-V9i%+9ROAnSZ+i)_o0Arp2u0m}T#N@eG-4}!Y5+m9JN_dMQgzOEn|w#s?9I+@h}!Rc%%ZnX|EmSjH)k&0O|pX* zjplZ1_07l#ty0Jx`!0Ew$|$JT>8pes!4vlsp`x%Btqo`UT?$WV4|Pn72=*Ds>UNlj zxV0N)AKMbTCEn;VEbdLSs?jN1d*mMYzRoaXzBp)1YY?#CbL(Gux5ik*9b z9JP_(A>{WP+F}<^BbQakhg@V~Fy7I4xQLv-;$1C4E>_qzR_s~>oPZL@D;K6ACuZbi z2E*Vultpgb*i|v83t5n-66}U1*i~iZ><9%cs345?}Gw>~T?lSIZKjcMbd$3z| zPzm?+2JUDQGF^vM$W{Sae!|ZABf|vP3e%9CBQlD_J4%2|E3&_K^n~d zAuNV%XFqI2_J1#PyfV(3f?G(~r=LOQ(7Q_upPlE%J=z&@yq zj-^2dbn7U(B?uQF6YhL1?9;x$J8<5vsa`!xwQkRA(M2QAUU}5;O^BRM4{aJ# zx!>eC6x;6{k-aIb^rqj@{mxfijHRw<&>8c+`=LOv6o1-jl0kD%*<&;Wji zXVLjpbbJHduEv|z0uQ3&TF?k)|ND7#Jpsz2<6q$zWWXIYhy3XL2Hb-;EdyF8@8nd0 z&YKYApV#Nqqb($K;Qvn4qO&=E%Dk8;-%|8Mp}8LW;y(A(`9rJz49QO_z6*G)ltz?5oOR_%Obb!FBH^Ka0-lowLzm1Gj#2M< z%)xfOHE4Q|df0ryfQ{z~g(@ra?=n)?6Ziho*8k+3QhIgqUPWfa6&KvaDRgQL%Ai9o z=!!79;efl=4a?C5BiyrmxBx#Q+ihe^j7+_eT{E&fggd1T+mYpNWT^)YkySC2#GPt} zyvVKsjzL3Ymx4Q01V@okDzZ7Ox|5YjeSi_e)iICT#Pa|BmgSjTk_Ycg`+nMMO6y<6 zK~tUj*Oc@V3qSjPDd~^9k{M+mjOGSb`RMQW5105!N}gMv>2qi@ocGZ9E_*4zz%(EK za6J=+ucm_gUl@EF4h_=%^xVKCXiQJ1^0`#5|LJX)$tLA*``;RwR(`gledezuKuqd+ z{ofB9mE%do?g$k`n^AHp{c7xLzX_mOu2^1X;$jiA}Te|~@# z$oUOCjT{5zcXG+oNS+rXiv$%m4REU~Z>; zw>agEXQxW#hfWV_SMM&pc=gy;jl(`~C%)qar_Fv=uvhCcvF|0iz555hr#0#6z4GKl5o0%YyTMmfqG1$HZsTwb!g)i*KCFG8g_V>(Ws( zdfdtOi*Wo&R`W6!f=3WbMK0(qwZsh33$KTCD(Ig}8l6 z{T)QJbM2WPjYW5EcPD;j>B()Yqe2)zqXO#xspihlu|?NNK@ZCZnEUA7xsF;={X-iJxo$-xM#B2 z@a611WVem%xUhQxFbkeXrblsOzroXZr|XbuA+n4`mZy=WEHZ3|j>u9L+4;jzWcUDP zB12{DstR<449K(}G9ufvxYfIn@fZ}x4!=gWvB;!Nb*HOaa8j1@Rh{3+-zMb%%Wl$F z-)M!;N3gPC8??3BQgIZ%)bSUs)BO=b^>o&9p>eR9e4rlumcS+ z4_!ADj>>){A1`5eDlWhKW=GmnH_fH4&mxyJxD($wT_`c<{&boc?WDKsKP3z}1>HGaBA&m>Oe2H03K?2P1Dmr=*v($r~FdVZa!FPfI zx;q8;qr2ZA89FQq>5;)DWbhhYjKpktFjHZ86SED2j50eNjDVV$ZG^(k&!@vTN;`i{ zgLlJ4nnu9*uw@%fcl_>H3aU%d{lc`gCOSvyn1wFuiqbg?F#Rc&qF=tCMc>|5VL)TX zBycK*Sv1MZxbM&OpAV8lKEA@28TEZMnG2-~DOR0s>H1JsI^8Oep(~dZa{HjESzac% zx?UG(A7V^eE%e>7eIM2aZ%K>v9TdR)r{QPJUmTrQgYRHH zJdRv+;B9m}6?3P+yv-mh=Bo#9K^b(M0CU%d&M*wlz&FTc1)VoX4)d75B)a|!QX>y; zbe$G?a4GHNF$YiM9j9`w{&Pq8N9x&u*8zTEjR7r2d&6azuf1^68G4!G7Gi$Y&f(&a z(CDCMnN@BcMT&Vo+34qAo5w#ycoUyK?@=GW;ySr2ig(=7UwvNQ(c`0~oVa~KwdCu9 zmp4*Qvr4kQSlK)-AF);Y{xa{gix)J1?TS#FACWl|6i=upW4Smha`C0)>Q6H@!jlci z;}5h(E@PO#CvJ@a=6?hGP!1EY4O-Ij=9^zcQ6<8_rhKzK@;Rbp}LdP7~6)RSlXj=K0I1ibf*Nh zOP?nla~^fl7AT##az&yox$4GYHL*lkHZliat9oOm>&N-bdbBh;zEa-gf zqBwn4iELM?I3Z2;e}C#pep;uKqD0K<8*~EP+8UiTW!hr)w=Z7a=soQt^7n9KS1UvIcDN*c=hTC-o2wxe{CK38-?Bk3k3rKPeq1H0%&&Ge0n6r%p;5ycLzPk0yJvX1NxQLh^{cK6RmAd z1?Wy1R2c@%ku0z$XKyvvlG=JMRP+0m-nnVF@F~`MCThX1X`NdB75EJ2FJfKd_8Jt-4okN>M^lk^7G>(J;}Nw4E4bq%B6(XlOxF35Lx*kBW`5m ziEM0;MJ4uBAA5Qi7C<*-#Dq+mp#`!iLk3KkH9KZ!4j(`P>}?hF#lA+sHb{njb-*nD zU=MjPQ&E@^NasHjbUo!~oe{-L3YwE?q1vv_;gh z^7Cr%6t?@8dxw(*pBCMb2;};DWFR$^Jmo~(;n6$(Nwc2=rKMEz1b^;%EL>iT{gS~x zoyOioVsDexv+*BgKs}0 zqwm(Zh*$q~y4Rq+o3n&zzD`+~I2ongL7^lCr^`2#B_ zQ8f2IL@tV2XpF8J7&wi^a+`Lg8v+_c|Ft_N1@l*PFzTOhn z!>$!SO!MD7YifHjT5j_2)N1^~Jt<9(sWUNFIAcnf(x!uxOz`;Z5JBTog~u$!;~nj%*R>`6Ja zN50v}_iFr)wo|3MujO=CM_6>rxqnMga8C^(^cpJmcb}gR>w7kzmdD2u&Y1I#*y~i# zaRbQ*a@%*F$i6$X>No#9JbhX-FC!tYqtf7bc)i&1&I}2Mu#Y)o53B1(Vo7@!zsrd| zYpl+YYW|qvH=F)TG(O<)(D!FUd)tTRMVg)!<^^PQ50?;ayES|nKNWVk_XWA^ChL0G zQd)L6^Rut%66HO9-7Sg759W0QxGN&(%g8wq=D-!??T-As;8%DM_bm*0cK-Vwz+K}) ze)=#S`F(|3xOcqRLq)g`IZD6^iM3_$+Lv{>xZq*;)3P@#OZOj&Zb~bM~tW%%3+12$_`AMEM=R)#WMq=`c{qJHT)mG&Yry7&d% zD_GR_x*eiXm|Gc{-xPWyD*m0g!|%BG!?*K~@NF#^x0Qvv{aPdV&?fQ4T1GlzOUC2A zcHg(!g>mWVBOT?BWAoPXyH@l3r88Xog`Z4^|Gq_6-+sA#@1Rsxl`o%Beb?q#b*ESBA58O$%oE?cU{Uz>yGUyAnLH7q zuJv!|SQk1*&%QIWedt;h%tYrT(WNO!h3-(pEVu_9ih`Z!iVZqa4gaDeS8&G)pa{A$ z1ewv5ZdiiO)WTkLX9^vOLPwgQ3*My(_#EA_L1!p&*RI1DxC?hq7v6x2umkrm5OaMvE9OON1hcnRG)ptduAGqPs&kB`ir9woclBX7)SEWc6TSmhq__-bB; z8iAV4jCs`L#1)qA7x(PPZ|u_hI9M(4(f894zbT8byA~__kxCk{r`@) z*5r>iaibg0pcy)%jZVm;6BS%Lf6sSue|97DN@PrgjML#TGS2vS7m(p1vO9&$RNyQ! zi$P{Lu<^0m%aQ*t_4`?Q7Fp9>!Sk*ZBgQlowK&KyDN z&;6H2o`2#C!|rk-pKHj&3p*)=JOq)$7x)+Rx5Aw*f_1PB9zZ_zPziZZAcrcbiag?A zB3y!paGw=m1dM`*kmDufXaK*$5jX+Ok+UOqFb2{i_g~N&dEbMz$o(01a36M$1PXPi z@r-SRJ$M;kJ$ra1T{U+;<0;i|vbm!R_D}OVWynv(n`Px{)shSTPVtTD4s6P8zYtiN z+#E90SCTMn4d59Mjdlh!QL1{M$GfaU9y$k8ApUZJrpIVdiTh6cbNI&N4713 z-E4}-0@&zt@4mTdAyXxpHnf}RhgpEQPL?Ex%=&ymF!%-j*PuE6``j-9H9)9?@8 zsR(5702z2-m!4pUT#-c=c0mPMkm7dHp~FXDFuaRQN|4Dgq(e5V$Yk~F!#ZiOOkT-0S+E>jtWXnH!%Ny+QAYf)u z)qg*0cx6DuWZ4Ug+S$-vJFcoF>s?j9io(rZC!&HQUVpmsOO?36K{cZ)p($g3ap7~3p- z5E{o7apxUp*w2HZl@FID%rckWhljr72u`gejY%D1FOBx9;|yP%;);G37BLs|7P)T2 zA>>PmTgVR|Ksn@l6DGlFp$2xZ0CvEaxV5uz3~%2YJb>Of z!iU(|O!OoeJ^75Dbif(di@uOxcaK08I0`e+r*@c(UcG@=a67LtqFFDfc#J@+Jk#;f-_ z<;~Ox$7kgt*(y7dOhuJhwy!~%9Ovw(8eV#QCdsrNk%?|n{rS=;jNpc%J;^R*PL4e$ zZ$FahE%;555byqMoq6XZPAaRPV;_ zrrBR+pSn>MUllqg{kpytm zKl|x%<4rV!{lqy{5*bo8tDs|pROlEtZpTq{O9AqtQ)l5%-0_F#STtOQ2hpu4*aCBL z=atYgZrmDDbmt&Ca|{l_1$YLxhab1+7`pWf&ceg!ng{HKjrb1x2|dxp0yqf8(8X_X z9TKBk67V#-^9YW>ZAgwzormh^Ryj1ot@DF6=-4&fxGcB`!@`P5t%f@fa6MRBuggf5 z=G|M+J98}Y<_veT`!IX%Eb(Z8rzLs5O*m^#|(9?SmAU znN!nZ^zB~>+L05x)`z4QGm^{{a1=gd=E{t!7`K1zYBU>BzW&y))1JM)yq?Q8dBBb! z*_4d4g5yT^cHhW>D2fBhEBUDuQR5+*n<3d;y;fE!eTvsB2bpiAC)z8AmopI8NqGeS z>}*gB&NU9H+#U$>k5c-GTgHK&O`>P3@CbUw!L_r4;ZO;E@`8_{C~jIj{DXe+p;tmM z0yioQJ@Z7*GGPr2M6Yzwt5MjAK82w#f#|_FjK>?74I6R0ws51$aGToTDthw_-yh$g zDsIvodLxK_$U_TQ0&5^Gdh-gsAw*9&ZMDXOuNil9@A;d2U~X-NNAQtY_UARR$+4ts z?AIPGPL)1>65?if_`$Wq-YON8VT9dw31`Z^8)N86NaN1UaYTel)`o7>>Nt@J0>7 z9OOR&8<00I?g<}qcY(~vG2q{~3v%;^G{~J`WV@FpxTv48%P8dqr*L$S%TnjO<>0wxkBr|UQ)Og1g)E8i zW)NYAPaxArkPTTD!Y23@SqdS;0{9&}O@&PNAk%JSNr@eHgEjCx-hy}VH*P)`cDfP@ zpaY^%4%%YJ=in}MgBx9lg4F23Q@9QPV#jZw6Yh{3op_?Ovn%V64jtjbZcD;Icn9CX zd)0RSx~u^m-3R*lGIJWVGn0PTj{6gk0JX9Fc2MRM)sP>o)P!D72ZeI4NwP} z&m-#yWX*z%xsdTGWNMB({RED~@5uNUG8ROJ{g4D1vLZ8jWE2RSahJW3(O=wMJ7hwR z+4JhZIBR_==vk@HSOTx+rzjhmXibqV&W!!c5Awn<-#OSMLc~{c>qY5=_*~zt$(IY6 z!iou`Mn6BkKJ(R+l(LRBM2y31-1or>XHU&g;TfV;Hp-g3asC72q`sf|c=h%~5Q_%z z&3QzR+js@9ml{848TZ;Y@qkE$pr+Ph?#u_;<~83;%un7`C*M8jEiL!ozmVC){ZyrLQqBKQjP zAH@8LZM#Q_dCc0ZmoId1?9m(L9UHwze7aI%a!i4b_ZmeMsdrF@{hpyxo7rcZp}8+cJ$3+Hy2ySqz_-`QBwJ6D`v9z7Dl#j7PjdH zT%=Xi$8FB{XBfyYQg97vQFEq8F%ru}UotrnS50xEqnUh9gMy)BKs`x~VXc9Gp&iNj z@0GXB?;CKXM%U~66>u<<#LqJ9>$xY!75Rgcr-e%44b{5c$=Dy$<_iWY4n5BdUmmjC ze_=tXPp-e(fUT<~XlXFR=6y1u-rj_IE0II?WDdXGYgt2-te4i681@~K9oIm{;dqmF zBU5i=`Wl+yF4`eu1!Nl!4d1T@nQy>t_zIbh!EWsD2)u*+J%P-< zka;0=LFSamSP*`MVaPlgF2OBio{Y>DkhO%uPWKg|37kRZrML(6xC8NB8S%QUaWg`R zT)`R%w?_C{jkdJ37@5Acmq-7haxc(XRC`d+Csp=mL#JP;(DN=$l-~2sC#!dI!t(Cu zu8YkbdSvid{JqYngN23fFZXQjW4I?2d9cXm+q=%kO&8}XVKD$;l)JkwcKy3y7!Uv~JtT{L|$)uZUg#V_27sp^h=>G)PK zuo+3QYVbX()#T2l`uscoI;5dAb{_ICzC}9><#O-KBf4I?`z32@W+=e~q z(Ha!Njqrsp(3?Bx$wS_3^SXA@QC!OXIBla(DK5pH!^v86rO2RKsDG#ky-B z_Zvc1(~+Pob(z{zjRBw1=K>XZf(RAVNY44|&9V}QNxoFRkhJIE?um~a1k$oo)sL=J z1$ysJeXV?+D9~=G>c^lwDe>KO*&jXEK2bmVNW$hz5M*)l#l(fsJ3ohd?gytdaU<_9 zumiRs-!W*4H^2{)BHw#39nM1!TIa5T)j=lJ> zaMe+&(SSvvo5zIW(%y*N;=XQwP;K{X+SBY(V!9*FTJ~hFOm;6jXq?rhv~Iq5BIZmk zqI0pP_mUI)_9cmv`G+h+y%3PZSp47qRd(-i6=AJO9%a49geY^fnm^Y2j zIl!Lp{M?WHb4;a?g3pIy$<2#9m)_W1{uMgJft?P5Pq5Pm*>}39i`_NH?h;@Z#~?ql z(u0zCmvfL2@xLr^gUOJ=Da^hEs$iGQU<&*L6|q}h_~(vkWJZC^G9VMOBSUujuoRLa z%d0RH8UBVr$W9#D-GW4+qw*8qhW(HI&Ny;s^@rR-RQE1Etyyi7_rrmHZIgT_3fwJK zN*Y~1=2R2j{XTqwJNH-MSm*S)k+xsEcO_&Hyju`CwX4laUMAP>i(llp+lel}y?%@H znndp=1xFS+T=u-P`Qab^L*w4MjpMU#dRGH`XRoG4eDt4h$vR&hl@VTsd_cQ=Og4|AF2Y2JP5@W~WAU|^ShOEf35;npkxS=PJuLzXK4nBv4kPErL$L`%j z?!?H`9eJ7}&vE3bh8$TjcV6tyOLL+i&C`KlLbgQSOxk*Sd-nx!-x|4QKyR(0syXKO z_3&wO3QcDVQ>s4!wb~XLY{ut48ft0OFdVW~o1!>n#UA1Kv61Gpf`atPYt4tfS*;~L zPX|e8j4KtK+w0?Et>R0gZe!PZ@(0&h%sCmR!$PQqdC$X2%vla|PR3j((f=UKfe^pm zRG0;2@#}pLP2_iS%vRjd8NDop%P zCW+Mby10|3O%>^J+(pN98XP9t)(kP{68IaEaqP_J9@IepJ7FXCfCsq{p#P`v%^(UD z;Su!Q1jfQMc!T8OJoexd@@;_Ek+TO3gDr3m_J9vczxsJP-k9`rxo;bif z^kog&;=X->U2p}eqfeyhj|^OcXVD{7?At3C;q0);Cr&jwPiA8ALm;9pkGlBBRd*4= z1^&d{AH}0qB1+v@Kb{dhn@6s5>zPR2l7rEQxN0$ndl4r2mCvYkjvkk6IeN>X?-yaI z6s@dJ>4i}PftY+D#wb6{oa3KFa?@Ci7lnzOb1WPgX;&PWt>muI6z}C@k%$xUOgx(- z-yH9lcmaAB@ohSC|dYa_#*28juS6YXIr- z&Pl+>=+7T~yOg0viP-Zc+)Wkq$Q!*miJmOuPFkZUH}Q?q0Sl04G;%zN{ZE18$d3a# zO+hu}6^lLZfiBx6q>1IClaKX!#QG%ZmFg}>Ha{t~_3-3g;CR|JqhjRnJMjsNWUczL z21~L?kBO;RiRYG{mg%yH24}5+7I~RKk6nWFM)q2Fk#8%5q3@=tp|QR_lk)9LCAF*G zYX-MP92HB;W>}1p+S#^UA1Nv+KlXZfle)8e`VASjX0s`nX6`0^YO_~a zpMb4CaX+!u@67rG`t0sElSx~wlSnIXc!d!dmb^M@uoZZzzT;zyn&Wq%f}`$JgILuH>+r9`^@JykG&F; zLd$gWDJz==+i}l|iK8a!6G2u z6ZAvx*3m0V?6wv9wF|wng+1uk8Vtp5A3)!>MCDl2g-EL&(`UPS(`Jv<3Wm*=&^4y4 z(Pg}TtQT~;$LAD}7v<>KS7w5j36g}J9qt($Yy5;?Tcy-0ZZoEY7E=2^^%A%<<#XxR z>s2A8k_5whUy3A0!%ci9AFfhoW!BTCCz&u1y)~dDOI?#X{-My7xVhD zEqq%dEz{7YIeW&V`m3+#ueXK{W*Vx1j6`_;c7~zwTbfD_5qC&%7jCP;r$uHh4clpR4%>lM^(GjtVW#kT zEYOSGO_nj$+>4ovJL}2VXGZ-i)?6WE=9J;bE(|eWztHW=CT~&sd5nkRqLVDg^DFbd zGuL_6?XK+pa{hWmqpCS;`q;U{+Zh_}H+WATWVU17ZE*LTjOrx1c@Nz*W+(Xn4{~(# zIOK*@=;(WBkFE~kZYra*;kb{HuoRv|cb~zJunzb03_2|Whu|!{jIPh3({%V&ae=u| z8QqRXxAWm+bXpUg_Jdc@&0KWvE;?6*F15ow=#nV9lL$r7Ayb$SM_?7YM5eYg-^;f* zWpk;Mb^bUH7Q_n(y$~|$rPI-myh3HtDl14^dY)P$=FbryNjX6YI$c+4r!!2(LXH%) zeaB)iF`pI|i#v8%T+K3qdO&xDMmP0PnGwGfA2X2_ADttE0PP-Ungqu<$rbUl3@)-R zu3rB9G}m;sO)jShY%yrl>%|KSQWx{bc(Uw`r*^q|$hb7%5M3_aih$`ZX3-_Vcg${r z(zh90j_3)p-LlgAsDvX8E=#>+0ryBZn3pXX>pZ0v_`qJmvfl#Ae*F!^&k$;}8S^mnnYoEN*kC{()qi%2XMlQT1 z9vLA~Kl3NpsOodHv7+@6ehZ*gvn8qR|O2Hy-u|53-e6xzi!q$?pgk?o{ z_-3_DDJ{ec7%cRgG#js{u9)92c1K3x$Vd~}R3nq$$if3zupk3B7z*D&J!CQi1(3}R zWK)3*<}q_3?B*DD(i1b!#mrT)ixil(0xW~Q*vamHv&Rf8ZaayH6}fZ^8uxh7icl_T zo9^mk@Kj{hG-m235Fcp~aJT-Y$@1!5tP#6dydL|zErBDVpInGkdP0n;%zMch&&+|rYnpAwWqx9g!aZsIxIL>|mn z8=Ao=%vl}tb%%18^I6RG1?IXRU8YBOPvAyH!8a*Cx+agOT%2freQIh_c9&g9eJE>kx=h6Q|=>0ZKMNWpu!5wbGL&$>=d5}Xf+?+cw3GPN-IZy>TIm09< zk3H#!8OUuA&cFoRra0s&h&&G>&(F{e`*H&}suey)&KbB(Q*a#`A@`@XCgTl6Lgb zS`+RkuRY0{E2C7@k0+LYn|7V`d>H3j%9hw*GHygtai>@N zzn`edU7p2o8Q0P>wN|flc!WFK>+fY=AMndDG!CMkd>kHg`+HCxvF8uxEE5tTMp3`s zN%hQigVk(4gEhZC>%Rf-OdH>r*miKli}9cfI#2*zcn9avfpv5s3pbDi9f*ccp&52I z4vxb#?C^K&a0+hWBn-!Q&==SVU!p@nxRp8Z5IR!=_nQt4;RbPh+4I>5@+qE{+f5CvM>2Wdv)`QiU2^etC`+V$sBqE# z*w#nZUBBPhCfs~fIA9#fyRh)!^+H|rfB(n2c8)mV_@eyCXw@E#pLU^jYZGmh6_$(I zzj><z|*Gj1qGzyA<==wu{uFH4|EyC};yLiD5xDxfDy&gZPk6h+Sn&@UUvh+bvDD)eg*I^iyn;0@D-4loUR;!SITO1N7Quo137 zCiK?)-~B>=e?mp{wHcP6mou;s{ak_@a0?QkuY_ z-9d?L7f7qKL`a)iZw*(6Ouu=U?!f-e?AFQnfJ;HKgfZ+rvgJHXO8I2PRsy7XS=TZS z`K5)F$;p%zexVLZs@>#{3&}5K+sT6%xriVaQFsdPkRI~U!JO+c=Mc=97;`-eZD9cR zUJUc5#C~gH?lI5~b9Ta}N0LeH!yzg_78(K)3}-FweBS?Qo&i-u?5a_6Up-;yiAUFBr5O^c4fuJcHZ6_x7~BNXkfM%+9*(ps`vWd_B-)_ zcJ9-LqfrcvX1V$LM-t+cF1#p)0{A$na+rK703LiiL}YgVKD{C zCOP39b1_s=lQ}C->t?Y-=h=6%(SZrD8M{D^?w^NlFb6Utqga@RtV*CDc7g|4B|tf3 z757ivY7*S&=dcoXK{E=)ltwVk;h4PsHQ8r@KMe^uPtU*Wf@oWBM;m-25lE{+n_kEx<|HN=-W z_Wbx3Wcfpp{K6-1-(Q4>tjSW$P5k{uZxf}Q2|DwsY=29ti^6V&2GV;$k&0;wYqi%o zBNgxZd6-_e(zSY#zQ%t3UZlysj8}##!zHy`pPYOyrn1`vR7Uz*-h0F*E4!@dcTkkv zF;hd8%+K4};zya{v5yO;N7`L5NRD zEY=>&81?v%#mZA5HHSy^7o@h%xF)=0;LBaepUnw;N9Gk4NzU+)(Kz`5om*+9n?rIx zqkTje%Z;`-T1x^Wg5G*8I!+0LXDv$K=F@Bz#8Pih-iESzbft5pWxsGvID}LrP?ygv=`-J#NMeH~>py3&>?$X=mDM40S$B@5Jo_MbRi8L_zSJj1tGk< zM7RmV9un~xDp55P*Q6}RUCW1qb%ifxsl@I2aGBxHEKTp<24AoEQjz4UhGnX%pO+<` zbM8wl`yeP3y?>^(>fw##&{xh&kH?zmq9|3L2M^}KW`{%*bRB2fd^%w^RWNDa1Na~fi9eeJm`cB?!Y#>;D8SJLO-|- zXV3*XbU+PWMHfb41UeClPW*x1=tc_e!FP0m9htkqZ^&K|nO}yv*nfUxod_e4c{;M> zM3&6h=W8%jac4(rpqJ9lAGad&YGmFG`S1>u{asEBGV#!_FX}QKFJCq&+-_BWYe?oX zllZ|P*rZ>qN$dkVz5t^Emd<0jePjD`a60 z-LQ{($fN@HA)6b>A{WvjlNMy4irIU>B={8mfHBBs3_e3fU!X9u>4NvPC*qvdtS#D} z>aRu^4+^z>otYo@S=0IG`{=?;rrU={y&a?OS3Huaw&;nGsqkg49*kt=6Yr@!s%DxK z!?et^S6X{X=7xTZEV<}_A8o7G(qZeUPLT~UIr3PcbK>vk?`=7bEfp{1eWYKDx}et6 zN5$kQamK_kJEHMs+`jThtXJ)}R`?|Oe;uW<-IgP7z4}?uI`0{!_{vKr#{sz`MXv*j z)-Dqwt9ACB-W^3I74Q!%LPk{BuN0_>y{blbQ?ML+^#_t*zgl1oGVOz-|3s!lxT!uc z9edRUkKuNnhK?{3et{aet+DVWJc@mELDlb`TJ`;h4^&jo`;VJ)F) zkAnPpmjQt^iWWh$)YiDT!Kf9H-veG2j8QQ$k&y|mk5(!+1-g0@g|rgaqjHQa^cQnJ z3KqDfh_5<3Q*I0_m3A(f<*diL`?h%c(e$nhb>)mxDm0C9k(GH9!0ONLI-#N zH$xB#p(l@_8~T!m8{m#U$Ot>w%hHv)%h5Q8-18L}aP};;sxEt1e^Dx;vgJc>&rvJ1jwoz79*p}$YxPt=hv}~EL^a&%D=VkA85U*&rEnkHZ$*`X7f~DVxDGey*K%cYSZiVHepegszLXzTXD2sw3~V=PVqL^obhdb zB*THuItM<$7TgROaUP6P$DJF!i6zDj(fbz__}cY z{vXnY6*r7q zceW9>;BCE*`#KEGF2FCTEd}Cp?6G2!uf}4jF}FKVD)VJ|UY4cmmmULIGqXiy5gw z0?aBf{?1{uoYeKo&bL1Zqj)#-{zub!M{}Y7e;gr|5wfyMGDB8&*_BXs5|WG}vMZHP z*)k#|va%B*n@Cp3UXi^clI(up^Ygs@^EkTW@OnI-&-ds1J?Gx*zh_zbS!+M%H?PSL zdBHUWNdwH?thS$!IM5dk&3G<#`d6&92oWH-bwrvkvP2iLJzuv1Z69fmX*7f^r z)P*!X9)B5JnD~`&XeCl;NMR@`Bk{0x+FbM+1_~hOeZhZ-gW%!8RcE?KdidB zfBb2lSBUp=jkD!1rK%SL!6nMyQ&+w2#*c|RDABY7w9Q}^o%I#Pg+bb|Nzc0FW+ z=do`EAT2s10=@>D;p;c{juqW<2k*jH1Q-k6fu~Gx30>;Io@K)i7drG99=yRfAOk*| zw1T(cDG2VO2V5on1!B|f$QLYc;te=i{M%KW5G7s zzto#6;JQ7v=Zr-e+hv+j1*+p{L(gc=58pzD%Z~_P$EF z#A$OS+*R}Levkd24mLFc zWQW^jIF*J&4!F7jM|^P83BH6IHaM{Z$IvNhxH$wT;ot@s3r9rg*cXr%+sOn6*TGbf z2)EDw&jI)bx8Jz*J_N8>zF7E1zFU_Ag%cC<}>l zjF0R;6?QGEx8&|C=BUOs?Ykv%|NC0*(u>3n5#7k4OWkZk;yXhfmHF>0s0&xhsqb1= zNJe$9-@Q`T&l=hOioJby>yGxLa*?=G-$hFP#z~rtM{DOXG`Wkc#5~CN>Xmf$ijum& z6;&Fuaev2E_OfY=kTTD%3p4Nz_!v9_M-t#I@G)FTz?BSW1>Qt2^Wbnl99Dq6ARn9> zVMjILHVjVn{@YQwOu}xKf+JuK`gaG8ufVAh7z*x(V@tR_jo#IQ2I!sTx!t=Ep5LVc zoUVegtNlwGz4wzmdP-{A^0o6{eUaWa%DbEOs5^e(ende_Tu5hM$IC~Rl}lltua?AF zTwLAgj#}NA7~F_VY3>B|BQ-=3mR(r@T#?B)#u;GM+r@Bok<-rG3@_3MS`|Ip4!{_zCSD~ z%;aKR@5{LROP#fyzkWO)DyrCUgRdO;@`N8Ba0Z^XK}~qMfIV~vRpG}O%mZuT>kqge z-qOHd;6eDi3BCdQL1Oqj0G5HDuCe}gMvHM}>2 z>hP}%-(SJ}p>Y}6m0u*{S2+pUd#k)n?$ewtkhEsjlIA;}7q2EGW%A9O-md7kgyW^7 zte1L^n*3W%_KTE?`d$8goQL#wOTT+Wf0?u_$c%p82j@W!yrc2pN#ueVdB}(FKJX}dss*19L09-vK%tD;D+Ul@!g)nsYx8`0uU||IXEkX=cZ4zA?JguPxMdHbs)h z_LazJ@E958T#*v>v8!ZjI2U_qYJcuVlV%L#Vn!ijv*xz8Du4E=>{-K|oLiS=>d2$D zTm6{~511HVYPcu4#oxapbBt%nu=TQ>43XwJ?Yi^6%tE}SMiXpHkAjEtD+sUjxLfgF z6*YC%2_s2AG8yc1 zD`)}Fi{KIXjRo!Dl@&fOf%@QIa0#9n@i~bR`@9EzCxY)-_+0}DvBQk$>ved)12(`v zC;Uf)8pwe?Xox%%fLoxx{H|wp^jaUZL2e#`Vc=fmNDbsb&tHQ{U>Vp34k2%kkux&v ze->B*PJmm;nYa4x_xB!@*Vz5K3Oua0;QQg9d_7xy#sR0bx0JM-v!B^Yv(82C+&%n0 z_MEM(s~TmfQO3=ehsRk8dT&ui8m~QKV4J*r`qgBM*yWK0>b5uc#I~z=oew3G>wllV z?IiUkBYCG+{jG6Ei^PvKUiy;8ce1ZPQ)mk>+@oi`M%JDE_ORBYkw<^&r}^?Lt@j(u zFI)&``&$2zO5Rp%t(PVB@-SbxAzx#p^DUlJ;=|;O&#Ml*Y*d-N*s$9_hD|wyY-#fD z{w%iOLogduMaD9au_4eCS$YQsB2)LUAx$75vPFYzy~LZ5j!pRi(&O`;7Wf94yMfHT z1ND$OU1UxSS-S}yL)J!+EqeLgpN|7H0E56=$P^{AWP*$oAtNH#9z*ae*p6(hBNNoR z!*XGlPZn#-d=vN}cU{U^R5v>Hfw~ltw%{Tul)bqus9;p4G zdoZ7wYs8Z?s+}AE^(67kTj^mBX~SWu#Ji-$x$!4*MU6?jUU=LpU%7mv;F8R( zHfJfCp9YsEJr7b>X{6qH{3q=Gkx$x}HTy_U3i^F8;V^wEqsX4 zM866AVaW>0i_MyN@*p`nqLR2Fg>^wHWnC>={LYC9XF2(FdhKKi5$Sn$y2}f-cV~yN+gZ^MJxCDA3M={_qNQJHP1e3u`$wiszPjiU>iqu8`^!P4 zZqwov&)O1m*1C~|x6VD6^dBy63EkxuPX z{>?xaFcJCr3O0i`ktZ_b$Qhggr;(=~);>6HG$-!_Qo0J?J56rr*W0*-a_OW&$rRF3j5mP#sX^ z&CF0uh_<&O@w=czwrQ*3IpE*yc_z@+yY3d{Q)9acGJA?tpXe+X^@s#B{vZ4rnWc^5 z!HZNHByIL`wR03J*#UtI-aj=si3bE9dNv&Rxi4t`IK`l*O13>!ExCV@oB!+SNperJ z+Gh(lC%LK8IQNF`KO3<4)vPK0K!L@ST`HCRt%ZaFAwBAuqQ40PLUq(Bw^Zq#j*-;P z`SB+C3)nIWWvHK(yM)XvgG|VZC72B!M@H^|_rXn25t;GB=b(RJIx=K{tPo&BhVWK# zBRl>e2Qu^re1HrwB17IF6S9+v>~wZ@OdW({CIZvudf0L&h3630jj9&eocyOeFPgpJ!EY!vK9x@Xzu=XjV31_YHn<( zH@3d#7mDjX5PYdZAoFtU^PtxyY-G!Y>V8F$6hDjJ3)L5BKRghZ$Kzjo>gJru<+;pt z{p_^UdH;MPmW`zPKiu9qyyaJ9e7GUKL;Lnuk&-zn_7KzO%pzpvrTVW+DNfJL(r=i~ z4a6-3m~2TsuaGruI6Xu$*HbB%(G$rN5IEFOzrK7=XfXDs&FfANU#YObm{+H7Zm=3OJ?* zFWn@bigbFO?WN*Zr=^tn+j$~;kNDK{gmwo%6_)vg?{LDmn&mQMR_pigBF1+nSw~hFB@9`HD6xjWm0=_=LPXan@3m=J~BD@r%y8`fX z6+DK|nGbOP4e&JX?~OZGqJy)b6YlMXdtb+$vp@&jSG}uxEb;gL!QofLe(lRFp=V3{ zKjp>~)M}`C7(WmFDZS`I@M~v^?0S%El)-~&ei;B)@vD>+*#dG^S-60 zy`E*MnugDZ3wPxK4RGIhunCO9y_Z2{+}jHzLw_XDn>g?jJY=IU2G~|Z++7HF_rbkC zr8Trq7@2 z^|?<3HN9iDuS>{60!$LB24Zeq_S~|5+Y$4rG4%WX`G%%rN;|8vB-k-MACylSQOGm)wpAO*TGiR`a}7jb(JY|jiB02fzrdvh=X9Y_N|pab&AK0mVW2fhIL z;p#G6vB8lDXbBFY8{^<1wOwb@a2Ej%fIe^;iFe8Fs^Rw{6QeW%Q=QXImzmPm?ybkD z=}L?S$T@r$yi+>VbSJm$)~TL${;kq^|5FVt3v7BjybSDOLXsYjsC30wn-6VPEwEXQ z@~tow@k%kBJaM^=Gfk?aTk@3sGMTeYb-L)1Guh!+f-fbjah*JCTkePq>vrzck>q z2b=|;!7(A;r4^7Et`CBO;7j!F7dVG3oQL}_;4DarK2n3HK@sfb2aw^v_X~Z!432}g z$WQ<%gA4_Nv0xPXyMpYTKz90&5k_R>J~EPuObnyP$I)Y9WaIN(rT2A`t64s&;(M(| z7%P)(PW&AG^r&x-KxM0f%>xb6k$)MV2>RI-Mk{?)p2X%TjaxJjbHx@|&3C6(CG9lS zHHeX0l2tq*Hg8XO%uT;=?SdPV_v0%K>iiE!th0l+E z-0Bl}9ewfyn=dv=$J-0^#xyIfj47v%*Z-LyC{~zAoV!i<&FDDkosDe%@xZ-{&Rce* zVHsxL!ydK)qfvC}-y0l)@|sXknC-ddLrD zjgVP8KkZqA;Eg7W%tv1pgmwZ*{7zoIaW-Vl>{-UZS+A&}i}JibR{ z+wJL*xj)Yff8GqfW;mJCyRk6wAmESrXn(EJq1U!!Ctpnxk7uZ~-WU+N$k?}-`o32| zwWK~(Vf6WpXO}qfc_9d#0IA^48T0^I(6g6dJ=g)3!m$H3whAPJtuSU?Z(AH2)Jdo%X<)wx}-Q{XHpjyy=I z?f!AE3%fjxd<=lk_R4D!Qw-BT5llYiIeT5Pdh4LUGH;8*w}N2~^9(!lVF6znf>t%= zV_Yqw3WUj`>XY(j%KJDJYLWw=`KYKmCG#kYD-YixdXhfLVR1}exlWy&_6xzdix2Ot z#0x4r+BZf2`zO5Sy<|S8vS@Q=FcPGsj62k&emh=EFs!Jwcut8xDDc>gAR_HgB$F<6 z9Ftaw6Uqi=8N|f$Gqx^IxRcF@7vJuwd-ho+897)1+j)0?9zysg0d>Gwa0P6~o4|`) zbb>X=$1mhS2|194e@ie0JP7aV_{^q_op=E6l<;Z`MuAn}BDf4PU>|~!12OsCpDP`F zhFo-l9LNJJc3}ejp9V+aJLJOd-=`FwNw5QEU|-_q80#~gmlb7FJq{^`A1iGhvb&|q zbwtdHR^Ib$D~QkTN;Q3`({b9q?e)@FTewv7=J75*nn;EN+G4Eigi|5Qp&pD$Mr`NBZn8U9PxB(8J?;Y^20k4|P+z+UhT zdT)TfzXjv*dF(8_?|@D4Oov|E!)p$DoC9x?c=Mmb(`EQs0?pv*4;YC4CZWHhU=4bF z1ijTnZ|lKE_`C;?-!yi;eg}`-(;PLwL?uFg`rDUp~)y z{gOqZ`qhcpPp<3)=7-L9bI?=jtFzs9sdcwFVpWh%Q%kSncC14ENY!0KV%05+5GD7g zkx%tC3v(G&u0Jt0quFye$Mvj?%^@C>pc`*QtdfsNs?Z#{tf{T+$aKU<>^0gRV(}dSC;nfH&F%d<%C!;4Ta9 z=+LXMgGsV`s#s*DBrc8~bJWZWE z*NRI!4jA)F{bcQWlJjA(SkTcRB1qRPLFm-W;(15YT1kDKlvxI&k>+h9&v_BOay7Od zKRc0!o++2_g_BWBl}}tAhz>N|w%}#_^ON6@Y5k`A?^Hn(nNkPQzcb{LqEb}%L#6EL zjmOlboN~wRE{##4R}tV#a0XQ2+s&N~m=2bLYsf$p+>67#3iultc#jOMf&s{aFtQK; zhJg#{AvIj;fcoGokQk1c!5}aR&duPQ63)+HZxumb^tc)s$UC2&9X z_bpgvMLsy-Aas%AQBd+@5he zU|U~;C2&3o-hf+2P!x_&gD=5aZ0;UF`H5TTe|A0dvWmg# zlJ~(gFKgV6)6@L5S|xk^mMM^)G<-HPpE7eWSiAbl=Yy3!Z>gi$D)ceMGUgf6t9_pa|9QuVi(=^fbQ+HzcXIC$+)}b*2qJN~+fh!BTkK5n*!qpQvY5;pc zX*ekaJ>bL~pLb&6L>IlZ0?(tDHefV(9DVe}R>xzLKf~QUY%VX{#e*v7+X$Efr!(l= zNA&GGNRFPVfLFj*pd*~S!toEhn_J*PxaNiH$KZ1~-~XR;a2BLR2BeY`$crY0;tB|v zZ_jgVvJ?#SO3xBTt2=N#wEdk*k(JGBZ_j{mmFnF6QYP6UtJsN9mwu-8nwWpA5*^r7t-)lc41p7ZhPf=BI(Z*8_FPs*8m zIA*?8IpadfGb3?=0!}+X2DqeyGY3!x?i@jDZ0HrZ`3N_j=vglK2Rsc|55ZV48=H9w z?&827|7|6lUBYJ?E;zFS{n5{DP!rB*;p{Ek=)pxVsByfc$ZpCY*+#fskV>5GivWps zw;D-Qi{@UMM?v;6v1AkZX=-&bq!;vJ%AOyOSm1Y#0%0XTZZ}cp&EA{rw712c61-2QG9)82k=~ z!p}S?hb|GqQyRQvz=JAw@HyVBI^6#O?kvcg38;W>6oIrE<8w@bkNZTuMmxkle=F6>O7mf9Ig+YVf6nww&5;PPu-Pg7_tk!p zfz}h@pGOxMnFl-m!`<>Thel7%P=0RwVNjD+t`pK*&i>`s zOO^nFP|CnJ+hUaS>ye}x!J_cz0&l0_D<4~E1aIb`5PIbaN@5G6!D4tk0Dq6cX?PUH zyCwslWnebEeg-?Sl_v1(0lq`;XwbI~@GJcHVmk$qg9Uh=hTk>#O^4TG@Y({e9PoM$ zJc!LR21h^-_O%^lLY87n*$0R7!$o{(nuHa?TdUqiXMR)c znFu3XEsi{z+m!KsHQnl@j>+PUeKBT~iR|E4%(zA^FQZ7$)9 zDIH$RW6P9z1iw=a@*@&fkB8VFA?%+kF?-*j`}22mm~dEaqC&(`daL{<(y@HM8_#}c zYB~H${V0hpo(E09D!$!L`oi%(INlGYftqmJ3hJS=KHwL)?f^}(rMKYn7#s$Hgm7sK zcS>-T1)hPkMmX!lc5Z_%_}__-zyfqz5H7RfQV=c&z*#u-K{pHFZW266VoKCLX`$`H zMLkYiU{Cs2$U~&?lg=UiDR+W!o6S+`Oj%`@hfKs0Z@Xwh{g}H$pF23RjfEzE8>i-U zw5GERKT7>qBEgs=VwPI;ty{V=#6_Q>pwO?+!IdpiuOkWoBSPJi{CgueFw{w0CVKTTz&x1$9uIksIHeUB!G``Mhj zgKnn5UnW?Cu9Cp#C2$k|WYAR&umEI$PfKtNq=eTi;4ySI3Ot7HI)T4ITKHCnXJ^nK zybtf0;C*y88NRFG+XtQ{;8he}yTDuUy8;HmYYTV)UAzYdgBGTba}!KF{isZ22a_F1 zq6P0?6reJECU=&ew0K@RxzDzO!h_t{O74R6b@nt}O;!z77J(GT$1jfdgTGK!@F_b+Q4ALNYx$@FDT@V;!{jJx1Jo{A?F|NEF5 zo$yF3x>$sGyIJJyD}Gs`fiW?ae74HZQSS*!zV_r;XJX#sPk!LqCaj@)@)|o?!ZY%9c593P0%*4XZ zyM4H(ybv<{#oV<>Md*X9{L0m`M0K&MWCPdLXD5cbJ>5KBaE#yh#-Y^R`P8kb`c3nx zG-tP>Fwc?vkh8A+QAEcXs%u>&AB;LE}YxFPY!qn@303rjV$~E z36Y6LaN|s?X^h!K{C5lL`d+TFo3R#S=Xw;BvhE+BP>VaBW7|_V(NyMIx8MEv)A}8y z1l|}f?|t7Fk5RfvJTtk+rOMJHA*AW<#@*C){NjVl7n|;t&o7$ZHP>M2wK;aKbMH}# zhs`y(@>`Ebhdfhqqlw zW}{Ve&OC+xJ=kgw&f%i=KevQsI!ShS_-HXls44?g=z4QJ!s?z~k zjo-i6?U&-}B6Lal?ZTz!{`(&g*Bzj*q0GM8l1$NCw-R{Ow%?bHNSfCq zxjjRqYLxeie|I3I=gvO%Alo8W&-pBU)!Eqx85uthk$n-AvJMs!-G6SsW1{ce&Yr`z zhg#bGwx61iQ4`q;6$k7r7<0%5(0f@^l-1pO=Pb|Wr%BkKAe*wF$#C#c;7;)LerfMf zwTCrB6!c!&?-=%1AW2D?B9&LI!f$ip&daenvbTtY5fkOu|z-QSM~DK&S$eqtv}t~~$1wuY;d|LOJ$ zk54U|JLwa7cT20DTk^Gx0@v$ojYkF5eeak#lO>yj8>KFHy^Bc z^KKmcN^9cizZs(cey~W0f{8)?SnwN?RQIIT4dyV+juuL5`@tlX6VwvvtG;eHT4*Ea*Rp`wgtJ_#=+Wl4F z0a2jYxk)N^&DAuSpH)={kuUM+}#hX1M|?KSlo9E-Dt*rtME3`p)1nocD>wI+vQ8}hQ{vKG>mi$ z-S<}NSMM4dx|+D3yF|^*b4t2hjX_d^fAxx+ZMb`wwZv;p6BqXf2gF2F?HqrI551M4 zvH#zHF~*2inBM4+jPyNPcS|*Kc501Nj-@=OFFm~Vhl%~6_Ei?UZ|g2bAK0(D>)a#0 zOnOOI{UwWg{b3nKGWrU=dg?1Lcv$Z<@1tkaH7ca1xwYCSc*`|jRxMsVHl^qra088XQT&uwq;`6Ku< zO4!b(t6XvV->doZzJc-LzQ2W;OFe}*jdEMu;b|UzE}}Djpdjv_4IYArMNkX(&ceO> zaJL+6PZel^J0^kuKu2s)Iyw@DyHetwJ>VbE0r%a5cZ3Y2$6dKVWl#&$1+)6 zWgb{<>Y!o_4>dm=-jTw1pqPAvtsFCCEs|ohceg4yKC-`EL z`={4rI|-SA#r{h?r9z>>YtQ?rHqx8+ZZ7%-uhqyAGS@W=4P6MBhzg&ujvEWySDY|s zAAO*M?{I^k#%qDO;76@}X{~jcw$kAjZ(j9luqf67f$r#fBy{M|Nlw>L*Z!xlz}HRa1;GeKyRwin_2KTs0gnU@LGW0tbu#b zpKj0z-XDR!U^lq^-|wSG??5~FcZB~AP!pbG;CBiBYSEV&0Tq^DN~-$jeBxwD&Biv* zTkZXWl7w&0zY%Ph3lcYKCbpQOdgiJTP{wHzNWpueX`Z|>`kAtZUmA&h<}Hd0l&t;WwHdfP}n+~K~tS?h1Yh0uYPXD4xHcd%J-Wo`7@p%zBuT7B^WpT2E zp_&)@iKbwd`>%oon}h;cDAV4^spSOm%0=_+dT0lU;O`Cg?>71*0*_}wSNJ@P{gZ~b zATSYp0&hFuIe5|s?}H@xjNk^6z+*f-9>pHEfl2U}1wR$&>nZu&pXU@jy$0*>rfvWC z`479c0t&*{Dtw)Sua&NY;>kngD#uF56v=*H<`x=alu_>|XW)4*PWNfq*?X!}WiN@p z^05=)EIvoyi*pcueoW%fO)XCGk3h+@LzkLtQ|;JffS}R{?MdpSPHUOkm(nsS`4&3z zo%BR{=!^&W8q|ghN08?~CtwO#2_A$i(-XTtJ2MYQm2&y)JARp@>yX`uMn<1f)P_u7{d^EYRxX$t!+K6Y=W=6}2` z`k^J7C_ndKB3IjO(NjfE`Yw@DVfna^C+_kaOhl&l|CeQK&}Xn0_nHSUA-g)*9&@k) z_fx>V9Kmw%IyNU2dY@ZaL8D>*^S7s7&3i}CHdDJ|UXESp+=1%FBCsspqq>_YQDXR4t7hA2< zHKRJKBaD;=9EY03EgZv1&TEfpRhRi#IIJglDQ%cb5V(_vYnTKO4YQJP)wE=a-?^tE z`spx}Q(b}IS>>nzz2Pll1A_IV9G@?lOPr;wQ({4XUV--L4#B{tsoX?f zsyD7#Us0z?%&EriFg}!~F}i+pya!{}`*^&G~cjWCq#Izc8pSATKj8jj< zJGNVGa~8UZm(iYmU3AFehogkD{<1zvTO^a4$)QtrdcP>0-9DeRFeqVIa9g3*V~l#w z%jQTcXYfHAH>AVuj^Rc=$gm1Ft_l1O1|!pZaGMm+6q&We&-@;nHGz!sVym*jW@NPx zo8^w|g@Y$?6Wi*{rz(TqiPm2}`DiSqez6UsyvP&bl|NBWnxgTH>aSjGgG;ah=5%2yOI!Cy(bNrKM5XwL8q=B-os7To+087%xS ziy#{^DF-TpYM?2|&bQmC1>Bt(cV`jU{r!Eoe-YkhK6ntq-47s>ipbs>WG@!?4nf8; zaQ8j9`zV-&yQ^Xwj$soDkVV1syWfWyXaoAgM=m%IFQV~!XJo$1TxE$k`c{8a;IP|= zwyZ+~PCG1vn{m{?EWYcPoNr`Ym8)mzi|!U{^C)86)Kh2aWRIiIEv*;t%kHH9Z1p*> z&z|Sy7lCBP{DFQ<3nHUc6bPmdQO^##knMx{%HG>$vYR+}8~}j5~YdzKiHS9qw$6&VK?Oac>t; z33-1GZh%tQgcwjAKJ3BQpcCHwL68kSDTTKi@DhX`@WIPPFcDk^HLxMS!PjSZy|sY+ z@T3T4V?%@^UK?7)4H_%v=^Q5RHnP6aQ`z9q`p2*?>Z*ytfGOWEpMPY8p`Au4ac#F1 zLWk^*b;(k4`Z(AN;um;f%o*97SYuE3BCyX`uKl5FcRd!`<7OsF;VBw zi5ssrc}D(897y@#!v5riI{AD^&xwgBVSbIltM;}!tJcT6wj0j||FFCLUjN*iZ~8p) z@7&a$g?CWYHL_x{I;hGm6GsC960>$812Hj(X+j;D~Bb;V{y`Ul-p9ed^9dz^%x)}v-fSbrf zJT|fnoB$7?!}md3WP=5nNc!)cL5F)l`Z@mdmi#pyFN2x_Px1L(iR2GHaOv6@oA|<_ zW-fn@hpf$~tIvj;$@I-^Y{P64?8Q%<=X*&JenEQtwmRwF9Gn0BYj${@RTkAE)UEcd zC}`Mr%PQUDm}m_?`6g9uYB7gAB->m~`eOLauo2Hz+9z{rv>HvOI`%<^q$^|Oq1>5| zYT(rZpT9VGceCpbzZcNSG0+yCuES3)JbVW|;DHVvJi)JEA2udmxbqTdh&zX%dj`03g8J^yRRTt#gJgef&)D5L;^R9%YagJl*uW?8WPR~z z<7Srlbmj$a$-xVB^9g*ZUn82%B(C!=|J$D(T> z>x>o8ww--iO|f8BpUq5~fHhZR5{2CGPdm=(PC%`{&+KR3k@LgK^1Tq zT!Z@wyrb(NE3#k<)_{@NixZRTWn?wM*zV^JW=eE9cOkyp|(kLfpj6Wf?0H!5L)i zLEOqv@aD2~{K-}kef`F}?2rFRx^c$bVOe=7V$k07h(Wf6?nhy{G0XcV5BB7G`f~YH zXNHsI52y>9?i#rLF)=A@Vx=2x7IpTTWi@qOyZiDD?*rZO?+kGS_mGhZWJ4L5cmO^_ zHok!z$VeUd7o^9&GhojTgR#hp7P1nKEGQuZEO37p%mK-e1y|4qnP>$MX|tWqdJlFzg8~B@-Zu2Z7-!| znRKGVV%fAG|6R1wH=$&9cATIW9!#ebr@o*fU727N_B~b6#gKnbxQH1|{*FbyLGRSx z7tBnA-OPK;4^#6xQOh*b9G0kP8i!-3I0XDNYSrPxS=R+XMvlM;byepA@C7cf_??zmVa?WW!%mN z+ytX$-f*_qsP!&hYt(K!#zzy~*iy9p{F~s~bF$N~$L9%(W_>F*GQL>e4ST1%O`N>; zZ-l6-+-9_}e)`G5#(l$%v3pK@n6Vz_ES(+EW>4%bVInwJy*0-*YMe%@yO~oj*0P`| z|1qQb*Vlz}FTOt}8;wmXXJFs`I{%^nNQnI=oUemR3@J zepvRk`a*Y%k78P9`Ztjcf{_O;$G@u9TXQZmC4TFU%Jvm`bvtpqx#|{iG{wTGT+Tt~ z#ix_He~(%pY2vF|bFrCR8{+Wwiff!Mx(#p9;0>N#U%c=b2Hu6wk02la?w=B$Sf@R=djL z!Ebk*=ia9sq@Yc#s((NGp<(m0w4hGLI9ce(G)dQ2$@80U({6VXzfbse{S8U~@K(T= zYavY^t9yO(b$^{kK1M-Ot1+gNB{NVy%j!<;V}~)8^Jkn z6h0l`vkNqaucPqA4_4yNLAYZp?w8$2I?dbUb<3Xi^N@Ana~85!;j4nB6Kp?2YZ}#F z5DQLwsl@uWonN-gryFjHBsqOchjJ?@lz2giHg)4??9=5+_n#N!fnlPQvr16G;Wy$O5moK!6#rkNRCc;fD-707MKa1!HreH zAl$eIU2sRXcfjEDyFW)VZvWA*UNJRkSo!xX8O_0JZ@mOkYwaV6EjlZ2Y>B1_f{BFB z-3Uv1eDL}qwPzf(qfa>g9-NH~CE~nxvZ|5TbCi>_fZvvLee^NMi-XpRWz`uptBGH` zWvd7#^X2z*k9zv+7wl`)JETbT<>diFXzPdqVAdOi2R-e;k3Q3rknTd{X)aB~nYPJqLp6nfwUH{8g-EF8%q z=RF_|_N@nwM3L`jU<^Jpw1PayeHu6nS3z(SkNt{=8%yleeQ*?HgR8ILILL*)>Htrp zHwtjrgI!t$N#WG_B2((J27{1-i`?cL*RJe36_39O7n!@R3yZD`TWpq-=xsk&RQb3) z;%3lV$nC;vY1J`s%I#l5!j#d{xP!-!Puzxoa;g4#M*L};TNP@XE2!0rKI>LmldNjq zFjm_o@K)Kuey>XL=8GG2FF!t9dS2*C8!>ugX7He!;YgvSRp0fg(sC|6oz^4A2ZWOT zsLb54&mF9rx|wP2d~alB%1I;N$)<8lkKt)P_UaEP2CtOxYJje7!ski&3sfWKOJyMVo#1dqa>0%!@373h`{KG(Q_RPcBW{06RrP4L+do`z2* zbkYM}pMX{1S9o3pi{ZKJ!fuBj!S{QO-LEU#T1)DOj)!eMOaB(%p!p?b znoIuE=kUFBiTZ9+n?>hAyh*BXdkk(3L0LGC18d;g2`)c^HQ+Lw@?lqP@m6_&1)w~- zJOwJD(^tT3?CVoxfgM@6{a+@)A!K0u z8Jd;#4v21krQ?qNx2aSX_R8X3>w{+{J9JLP(FMX%8}!FrUdZMTWP4a_g+FAz@;#Ey zAn^53qe1cO_j=@*fA$U}^;7&2{@v%HdM-we@Ne6LV~soI3Z})hE^C`oPG>4~5|^Tl z6w7@cGD`&f(As!EVD3~_kRKl-PIR}aN0GIq=jht%AVoJx%V=;KWP#H_^mz(A0hiaon{YS>cfZhM8T3~I?$$wW^t2X?g+orb3kJKu4UihW z3=fNLE!LFwT7k>Q{;yY+Jn-Y?<`22G6 zG|@8Ybh_+Y>x{g_pI#Yf(mk)8-uC^rIPq4x+wbeOjG!QGw#;hIz`1wwt0TcYmVS*} zsR4mSLxSm?ar@N16{bDmi?=5_5==p+nsK}OR;zuWF%UCA;X3KM7xn-(qzWO84 z{f&tWk9WkcS+9Oj)AyJ^$ha7h_+Il3*$8F90fGw=dwPAx0FS$-j~~t1n;|t-&iiyLZpS-Fa}|Lfo+rWJL!~ z;htY{&w1Rl9@%HYJw?DXxT`;Chx<-|7jWl$xGOt4L540I1sQSI6x?+Tyn*`$AiWNTGbOY{g1W{QcN~(ksh06({6x$>e?8 z$Gmmqor(65^#0}c#ZK94MOzXFc^PASt&5}9g4Ud)1pf_vAKRfX$!V(;^HbNYQWJip z`vG^mfV){CrzFUwKelHc!r?na9{eFL5G4y=I{_>3ox zJl+8%u@zDvJMMNGchg4>NqC)DRII;O9Se3EJ~C{$Y!$G5Eitw7jnzo}ul@W}r$Tiu z>Ww|kAJfJYWQ&d*vA9%AEZdoG$sm7pv1^(*C_+~tQEEJUe4sr=fTe0Lm%c8^(GT(` zj=IaHa2mG{&oHjZ6B}Kk7&rPga>1#L6?eXj_xd>Q-Hf~rg0i^(EpQrlUj)N&|F@tD z?yUv-f+3(a^4PN;R7>;b_>vLAd&^^i25no+;Pw+NB zPQkKbjm5=xfYh=y&bd0JUre>6NH?tcFtKv4j`G__-v|hnI&RQ!$FPk1_Oc{?*AWv> zqoE5c?Izyvjn*TI@6nz2ixGESY$NB|%;h2O`fcYb2Var!lLn@s7cJm*`1yc6Ujx6x z(?#qLJ-is;{zl+O&>bE$u}6uxeA>xSdhBJoCwkXl*Nalx>BS>N}$LPRkIKZj#KYLHkSvAy=~w;3g;gus5w z3C_nKByFnJLgk2-$1Ja%^?l`Vzs{f8rLcy!Ax16QO3 z&kc_(N}iNcN>hHs{aAU;iqE-V@7vJ|&dDQXb;B?6@eUm2+5P_G_;%Rjf2l{_%y}tb;D~nK3h@2?^!Sslt=$O;Q10fe?s3D!E*Gd7Q7+9 z`|}LK?VU+57%yjOvv;5>4$4GJR<3*ZIGpS+wuaxtdTmoniy%(^f~e&)xVoRR4*F^}vZra4nVQ>*j79-)J+Qtr)~n)VlML|p!+ zYcqX)w?*wQpg$+aC%Z&Gdzf{m#N@odqW;|W1u>ne>Ft}d0e2fJgXKI-B~A4%?qm9S zK$G=M&uup5mSB;&MPI3hEgWz>1c!U!>;^aq^1#_WFcNHrvlKW}fU|bE=>iwP^Kf+m zWPr0~IQxJNtOiFwBD`T7;1f8T2I=8$FC59Dn|h!JI+_D&!;vT4q%|JR&z?;np?Jfs z*z`DsZj3^RfS)K`?_F}MsQm{enlZi$M41$s2D5$_6r^~YRs6nObZTsP?lj|_sh4v! zN2SC!$7zOiOsmN2g42b^HH1=rW~c1^_!W+MWipSowC*AE)zs(zM4^;nBOu`ykYY{| zbiu7S*hZmoI$gB%NP^LIc&? zuWydg**Yo|p#z&O;zyE}$1|e0jkIVe0*6WS%NQSP8fM-EfypgKt>~nA(yaxX> z@O>VB4Z$d|1U!OmRzrusg67DBH%Nk9XdoAY=<*Ht&x3bCbhHE%#TJ{Ot6Au(8~jti zJ2N&}81w^QqqEPEhX~|g1>A!UUjlj1DsBRs+m(R26Kx)Y+7WEad2f>juR&iP$gg2rP(+QB68IPpBIR2T?i+AIM^0 zCyHmIPiPDkBc?DYJ~l-e=rrn<%^j*+t0p;%PyK8qN6e_JgguP zE=|J9C`*`W>R6+3n0h}O3o^ll44enEKw4xX16%^PKv!gC0hB~GT9E~R?7AwlPz3fM z6IsZ_A7tVkHbM>=Fb55g1s9MW8PGxo&Z7I_U=C=DEL4L(Ku%=iB(mXxOuPVDkO?tl zKo+zIXFz3Sf&0SlJ7NKjgKQeRzi+I;DBNokeN@(x(V?8%P2%bVt<{z|?Vi|i3)+Fb zgT(jtYDo+!FcJQ=5T|P}6Spi?7^I&yccU@dE8*s1;qtLh$%cE|={T3sq=R`w9bMv} zJv+lyl{1!|X0Nq}ZnN&WsBxaaWbZ?ohe|s7oeHuJJ5B@KZ5DK9?oMq-qunB|S9qwn zxO1`7U!BrYl~gJ}A7!Mh2l3jd3E3-00bSt!W*-xh%GcoQ`7InDdO&ugF{a?u8E zffMlG3IFc!KM9V*yA1rDMYnB0SMV1Y2EUX`O0_-yd&BkFKX(*HFJ|g?g=ZdqPwdUG z?){SW!&p~Wi&y2h7dgMROLIO&6!}I_hdm2*UEAmBG8FvtZ<|-d>2~FGiFT5j(2mRw z{TJS$uC33q8M}xQ4u|jksnx5R;FJ|S5>a@pfG&Trn5{9mfWAm6Ttda3l-f1T*363S6n7t9L*dbkYz^19Rb$15rZdbI!>OKbfByaJn|qKVThYdCG{(jLc)Ze}o z6vp;?Ec8LghmMz z6%mqbl0-=*NeCI0o$>#@{_c8my>!ll^L=0UeSf~^!8wJG$NI;W-ny|9HPBF2-5UCL zBE6x?A>ML*`DsJ%RF?Oz>V#+Eb03!Kj4v<-J z_vRPj-T-|SL0@G-U(gP{{R=Xnw+GSJUi7sU{p3S-4kIfXU@ho`?0iN>T#ykuWWo;A z$D7WDOmHF#PRPJ@FaqxDKw@OzH!?sE_m@Fm^tTA^GqBI4pd;K5z&)42?!ESZPq*|h zeICR)5}>X4C@@sU&)bEu__mO7+jDE5M>6`<0p%8^A=Nt4^VXS?eKI=6zU4v;Iai$7 z|M!Q9$|f?qNjBURW|w1hS<&;hF!g^+M(eb#mG;U<%ZIPVoWb`kyQ%4Umz)1>#u}5D zi!hbe>c}L?x}@8|8Au4+3NJg1lvNyVA9epH)Gd-{yT!*W@aP%CGy5Oc9Jqv}KUvSg&uTLN! zoQQ(^;U){zgqv<~2fPngws6!9TA_!maCQQ`54OQsH2TO3XAa}H zgJsxaMYwhLS`s*N$$#Xbc%=)Od?*c-rN6HG=3N)vGxDz5Zk+pQ3RMi9`Nf@*We$_+ znq0PUKl;SbKy$@~%!JqQ;ZboH$5-;okEIz)$(?@dlRs*5`SB=Ff1l_Qm5zYF2L-9@ zd9l;m$^94mR=It?al&Nf-ZdoDgJpvr<~xc0iN!`(*n2`-&e=sZ3mu0 zaPMEB1@2srz2m`st-+JHa~JL`kGuBau5Z9-+?Nygb3!*pz`CQw=7meg!={3|UCZ=J zU%PR>0`@0%xD zeSal(s#H+lok%2Z>2;W6^*8HBTdq{olxx(D`eV+8>=(!#9z7(pk^a_6d90Wr{&|JKiMCPh%~)0C_8)qRf**X!#wseD!T)Y+K<`qcitC$rBxj^ zV?IUwHSCAP>&{|5?oL4!HGK~gHTFX?o`N>0 zi+U`Zn#9|u@;&>1A6{g&_9I|3KWjf&b*qT$S!6hiKkdoO&rYbb%BwA}RRvUUe3TPl zyZz_HW=?CwmFH45$if)NjJMSbySxB8BLjtC1Dx-HOJcaY2#UjDIamX}0r{}glyH~< zcL{Ju2Uon{7wp0$xB+&_vg9oWqA> z&Q^(5-sNkqxRUmBahXRXWipsnzEsy4zq|_6HDO*0g@+stIQ@^>enSymo)5y?|!SQN>fxcJw z@3K5oOQ}tM470+u5*4g&Ai3Bq(Lh;?s>gkt5BTbq1pQ|^%#u|>6{I?I_il?eVrg)pu znNu-}mNo@!G7P-uWH&VBR~zHf~(39hD}fZQ3BH{<5hj)nwnQz}0Z^Jk!Sx zCAzg1C6#nl72g-cM(0;}j#&;01buwL4}V_ZRqzfx)_~>s_eEoPbq2f8$2|1$A^06U z0?$_9JCGaRQ}F#M8%#zHo`I|2G;$$>Ty%oo=<`$LBpLaL!LCXo2W{XPziyCm)a#dgSCRdYuolATK=N3D69D59*@-5y;h9skOPM+nXgZf$dZPjxv zrOAj`R9aemZiww>-Ric$BX$+}c4?MpWvohc*#QcSQO_-8!+j+KOW!F;$Fs;UWgU=U zppmAv(SIl9oIDyV-p?U*v_F)#DffVaIL9rs4@qp&OC!{h{#>Vnjgnc7HkH{F?#?kv z8^tVdY(|Ok?{+~PB*rF)fRxBiI_QB6b%Ni)Y0wp!Qpfi%PGo2WtV4Fhk)07R4%u-- zRvN$>Wab<)vI!C)8_&TV&;XgZ0#f6xeTR$)AtP5oWn`iPnRtjyRDiu;EHd&23_wQY zkO5(2pa>aotuIZUt$fomp8j8x({SvVL;1|8Tjh66*K1!BsKQI<_Pw(qtbH9@pA>Vv zF#hS{vVir^KW^90-I>lHe_)VF)GRvuFzzwy%X*sBBh!zwyO*_BitiNHJg#<6Ay$}X z?Orba{U%@Zmi?4LG+DS{1ov2SZS2^QN`|uJoF99BWE2!7Bv01UEPh*cZ)c8hdLlne z_WE4)d^vSw9z3TC?0SC;c7kbwyT5-O{&|FVe=Y{qkppV@_V~9QU>iL9!t*V#2JD5` zQE&%7xzYV0be|e;12Y&1zX#ye1Uw7Q!t+n?Hz)w_U%_a2e+Tc2@OuSb`QULH9_P>L zjh8%c*62}mbLcun8IWW|#pD>47EKi>N>8I~OS&MN#8&p4(70E=_pFc<`?Yu_6S}!m zeFx$g9$cHVa!^{3pHk{$;qaSc%f>7ct`C);H*ZMgaeVbf+3R=JN-2snMWqY!EGczxA*xZhtabwuq3J` z137~I0g^ZgmGRNGG&jvL$cVB)A*!dbc;PEiTO?bI_+(OTOKc8FL2 zD1fZQf_2~}WaSMq5{r!Vf}gM@{K(2FY{ymb3FwZj{07tUeZm6EZp9KQ-8P&21ns?3NDYqB_AA?gY)1+I3?5Db*un(fIi!KXM7ma2yTUG5S)M3 zwo+}?Y_$KC*bS+$1)KB@)&1VpCw#^G6OOa>x9z81Tkw`1X+BB)iDZ%P%lHjC>bysH+HxhXn*hp)hQXe|0Xr1@AD!bVtwAaDx*x8>(N|-*u!0K$xDWtS z(MwwN%^7`*f{S_35>CE>b6_nTk-&`!`s9b($AWLbEx4e-?G4c@Z}2mF%D^z!f$?GM z2aoz+yWOd)J5yzuwI21w=vMgMZHw&l9|j}tvOlWpSLP}_|0Jbxgqh{f`JAI|R~9Yn zbF!62&4SM+vOF1`em>e*ovkohHpD8`uf-}ioioU!thDy&Q?`Xk%+`m2#-6(->shx0 zQaW>4k~hrGPj4z{Pd~du-*L`@B&B~Ngv+Y&bk*P}GndlVtsyh!!RFUy)jfebpDRMl zyz(+Xn#=}UGI5w$bGdcC-wD4nBsXzx!z3XC4%a|xq20WF1%1)SAUHM=-Tmv9aGL^J zqJLH(H=K@x-RPYFHoFiM!*=JOhZ%5x>)#fmZxbL1oYRB0U=OH*ESv{Nz)EC72kyMfJDg5ksULa_}pb(!OekJWZ41N z-RMH7b!wiv?<)&(73T8MqDUFAF3s5zrK;J9jZc@mPSIi^vadK>XRJKSZC~V5a`zS) zL4n-A)?`H^7Q%HYW^SXuIFieE*qw>`$;e}rsE^bIJ03~&8qqCZr81yodOcHY5$3`5 z%gsG$I@_s#gv=mi*iyH4&`JMGy^u)uXsBEDu#Ox*!TPu=M?Net2`?mMKF>=AxT>ouRw;Z-|Cb2fkD z5vhA+%Qdo(F%m9sf;DySy3tY$m?#;%J!1U7{}-!T;w`?@Ntu18U53p}#Nbd1efEb# zA~+NS6Tn7WE$Z-Fl8y*Aui{(FBxak$O}KV$Rz;d~vG z!W(b_ECj8w1N-4#2%9essv-l%AQ!Tr1zrXFkcl-=5Lx&Pw(9S8nTDYn2t%5nD<__N@69s&iOTzix zBfi=@W;MIX7KMux^phN>Q|@qhmZELy8Pid$m=Re<@a{yINIhlQy$6%3Kbk2?-B(Gg z<;N!{i~o}Ps8ruSEHZs4#IfX1+tS|{nd8kGlt=%Z71;d@&%kl8UugIDzacy9$c_z| zkE}cbIgycAup3zk#@kQ;GGZ5ek(DjH6{N^Y6v&LMEQ0HxA~Nz88L>k)gs=nQ;3M!G zSaW>$^E4wP@yNz1xDAqHH^#tDycJ7e6f*P&Z-Xqd^9bZbb{LS6lb{Z$3yQUUS}zvy z8780l73r*QmFPzDC%@QFqGx7oxQt5EtBuBgI)ZO5B#P3*r>%ExozKm6y@y=Su6dtc zb`+J~p9j6Fb!me3evjjiH4Z-*tK-s^t55Vek$qiMJ-dC}*5hfhn{CY46jR@iY1`a6 zlfQ``h7u!Gr{x}rYI>BFk%W-MpVnV5E&3I4oiw+p3va*>IF8*QhkIU-1nyJ8T=1Oe z?rnwOz7_6?;hX@@li>O>_P_}JuLITLRu`-Q#o@XH+s}^P2Y`p*_&?ADu3O<$817i% zZW#>M-u>q$(cNVi+^m4T_RqSyH8upEbub(FY2J2Tv*TR&K-$ohGj>y8>g@Y&bB!|= zjbhuP4O364gGe@#uBcwwcUjY(b%U>*s=+Tkwr9e~d}eB}GmEtR;9HtU>Crx6y5}~JKpfKDT!Q}wxhVS{LaLNh_ z!>KeF0)BzpP`J$iHPB~cxV{F?fSKs=4P>APJ+*@SJ75la%Z4nF>g{Gi2&@IkkqusO z9oz)}_h)1Ok_;8DFqMkP@Kq{Y=J2Pfe-|v4`|ecI9Fs3k^%KS<%?hcm#9Ltr{p*r( zPuV2nR#O-S&62^W>cA1I!JooNlVW|Yd7b-QT=SXBc9GJw%7g*5nlaXr z#DvDdb`h09G!x=x&12G1F`~=Ckr}sWucyc`cV!%4nW_(#qA8h@BH>FD?|XU_d)|ON zEMeF0BNvn4j_B^^&4h1Rc>W8L!Lu`1hy8vB(xKau;50h!i5xf~2UkH&>qkR{&FxgF)~La_|#mfp<=L_5))<9r$*JFV|q#BMyO^UnZDY$){;6g{he6R1#&Y z&yg80JBwQKvnHH6wbeH*p)g9evmx2kEJaq(vQ$POizZ(s5 zt25G_P?V)~3eHf}uTv+FGg}JMK3{qJ$T?QBVwM1NLFP<$5qZVe&XSv!QFW{4<3~d? z#m+G3l(78Hp(_0G(oo`!Df&jZcl-q z!Qqa6HUEP2|pb0V+oeP ziwwGE1xA7W@MQ@G_1#b)3)8$s@VRoZiHk;EmHTTOT_rOPU8Ou*PH4R*W z;-7B6`KHz2yg&2KSMJ7in@g{Mz47krdGoyI)>_TRu=)P}6i+68+&vC=Y{cD;A=k%{ z>mB4;8ynUEegG43*ER4a?syovHvlIo?rB^Z4$a^l(o%+|wH@ z1X+>mEYJ~mP6XZW^*?lvJ`-PiAt<+m+qyIhF4HGT3GH6)mz9Z1 zf?SF8tiBy2wbxQ@HCgj|v31F3Uud_ z4k^wb)|2j_6*N7f%5Qb@X{)aR(UL6hNqz?6J$gpGruq`|^xu@Z*{({rJ6vVAKihGc zm!x2+R_za*sKSLC_yx>C<^!=Qd*Fl-3`6!Gg2`|*hs=M&t*dcs1Kiplj0L~o_UyR% z0(b{EuK*9?*4wykAZ|;D+m?VgaAQy0Sj^?ipZuubnu*1sOddqrbmTUN)r5=E4+;KE zeHzR2L{49@R_bvf!y(~&+qTYBReV%me@o8J4IX}U=<L)gTi;rURwvw)z(dl^_McU*U%fr(Yj0c=!tLWo(Yh(-@HxDSoMH85Vp0En-=EDd) z3OE0O=h2r+&<)N;;EV3U>$nZ3Z8}2XK*M7hi>3rywf#s zXMuMj1r8<97k~8SBWMqY%y3u;mVo?l8Up5l<6yGM+#yFd3Ar(YdIxK54-dZkR3C?e2GwMmAVRR5`3w*k|WtslAL>{z(Z<$K^R5Vb$|~6jM$IEBHrw zJx&ktiP&1OQSq|epQl!!qmo;uD>=MHn(q*%=FabRNl?S9bwZO%wnV0y(M2TW1jSP0 zYMG{=&ps1NKdO@{YT?VDOvzLgZ2A3$&r+=_SCQ!-VB|m1FUO5c_=8yjyP225mMFIR z5x4=`AX^JyJN9A@+y)hpHB(R-nR5m6!4IH2GDwW<#UguqkUcJZM`S?eDF1CWxb<&W zkSQ;)3M9j3(}M@V3KiM=ePQQTe);_-9h3WRFRy15J#9e1SEj7!ozJNr%|~s&Qqk+l z);CwH{^$DQ!J_IV#%__oqzXNSs*Kw|@h>wx z{IJSk^Sw&%{? zh#km;3(C*yvy*p}Tu;bv1yLCZyV?dzIIEsA7P6H%ZBSs;uNbZp^r_>@s&1ZV1=$Jl zPl+V2>S*pUO|!l@V@2^^QAu}9N!jAiR((&*TAe_Jb#QR0^p?5!NU$Z(<%{Qv&MUcp z^$xQ>VI5?-BokzDuPK;@Q1Nd!$yTsgo}`O;6=zn+9;qxBO2#`{B$s_eze`liMk`Bo z?ydi&cb`MTdCW?IaxZPaWx2P4opHm7fur-_Q8+ROSHKVGbtd{e z3Z8~D8Mx|)qe-v@eccCVCg58*Q$cSf&{umf1^wIxui!l|1?NE$^pg!N1D}D(=wmkC zf)`*5sEB?NBO6p;C-?>QKsH2>jY?!<6qG|Y`gC{qjSzk8=nx~~ozOJ4_fy^*qj7-k zq!-_b0*@Al|1>(}cvoAD1o-1l#}qWnT{Jmh;%3roL^?%f8Y5@OL%b>&eZkg4L)Ev) zv~7;h$k)e%w?J-!Fh;L1;P;h_GTy!#eub(ud?%))G_+5s8n<|`Xlew+DZQ|DQaf(% zBzez7TjnsYf@Z55b!ecD5b-^lyLRjRxK{Kq+`4M5ph=hZKC+ptJJmY|&z` z7}3f_J=I%mR^^!`V*lOHPdVOddtN+iqL(mJ`}(){7peC4(3id(V3~hu+}D_LQ-R{^ zTdDJt@4K{Hb9v$-Ry3wAy__)g9=s?_NJmdYn$P)Xee2pdf>K@yH6UhNB z1qA)`d+&u55@_$#i&Iz-evcp4tROl~5*?>N(mb=}kWb)sO!J||K%tFOO!%JR`Kdi# zMLNjSGMIqRY=h5~j=V%52XEk;3ZKai?`;Z1^=kZzVOno58{ttc%~j)bfBj#S zwZ+u~?t$T&py?c7luG78rw@*MaAdD+YA( zF7ovnY=)Bp2y1nZE$yZ`bBPJ%07D_mZJOKHtrmlw5n zX@$<-27iP7$TOq0r8x)725Qe{a_)=gIwkFkslsq-OW~(Q>Y??t0|N~k(Q(-;MaQf*#vdrWp?s(On{Py(jwhqBf+TKz zo3ifL+q7!4td@65zfP2GzIzn+Wq>&2Z+rBeoEnYrE5-~XYac16mFo`;G}5)S$^Uv( z)_I$@zpH#UeCH!|%koXyxTgO9t->|ou_9xK^<&tE3h))Sp#rWM;II(x%0OYfuK^$_ zoUVbJpe6R#7_KWpKJ0HVSPu7dpd&IMhzu~GpV7#|W3Ucvg?l#ia}Mq~;JzGmg5z3n z7>tJVZcrF*)4(t|z77_`aS15Z(V|@L;X1^s|7JYpe}6!ZmnyGlh&p%k&B?vXoE@if z540Jy%h`6vQ0u=L=2U<9$2(xYr1J2kdY`HGp;KO@ZM3TGX-qDWZGT8#CYSqhx6o;J zKB{UPyW?f6kwqP#m%T(fHqGv9ljzmqJbY`Fx%$2RrGYg5sEIV!wObOZC;z-BRZsD= z6WU7axWF+4(g-hbKp(nAQ3sBLk<|=-w|vF-H-!% zcsGLg2k&ee}mUQb_ev8MA=yBRkyVK)N{E^T!y}!3K$8ZwyPJW)wD3=GzsbTKgkkm zVw-W^g!Ek>=S06tibF={I}s}ZM$#+usU60;$ENf}Stf^t-y2p~mOHJxu!QLAGhM21 zXA!lHmGtq^_9+YzS%C+C-2XPX3bx_yv$*>h?i_^sJ_8N^^$B;R#2ux;a_|s(vI6$t zzJBOS6~2$^;I2W~#3}F`dZCDWx`OQJ$8o;iY=6U+Eib-2j+0Lk>r_9BO>@iTiP~H$ zQU2PPcPpi_=n*e;Y?t;)Rgq85O;ULop+FTXWaW1 z_zL_D=85d)=Pi5~!bd7{Ujquk%Ms*X;;>^K=|wiN5EX{;5B#* zKwoa6C#vu{509eghZgoP1(br$TdCSN#t;KMmZt3RxHj?6956d-UUR541 zx?yvT>c_|Cn?GJ?>XHqrPOsJ6r*PaP+*4b*r&RrJBsblM)|rO|_hzsEzV^e$J=&%C z*;P@U{T<(3f3!J&`pjY(fR@}e^Q@y~|iUoV%dzW8u? zGU?5R1zaD7OHH`E2A8+NZjcpjFT$lfI(8WD$l%Thu71LeIJ#yFN6v7>4M+T-7w88b zLl-Z>;VEofA6&Abn@Vtb8-ren27^i9 zgzr9zd6>l&yKc-Q`{=~yr(C1 zr+|EiR^)-?*%roGo&Uo4sPh#_ok*EAC@;twy8Nd^u1z9eLjFW$TtJ&S+=A}%A&alU zM2}-GM{F(8M!S?7QCNz9zDA}hokSrKx<}MYD!I#BCDLVzA>8^cyBKwZIG=@v^fhNe z+JrD}jwn_e`AC6q&&Y)q=_#wL9MOiVmaQ&c!Mw3~XCB4gTZ<%*G$QQ0&k{NFhC%n0 z+QuFVZfimV-oXF;QC)#lr6=TxwDhqJrQieP<{LN#w&QJdM4q03UEnful!Q&-K#t%@3oSg&1khjms+bHOX+)aY!$X_P77ddQ04lR&Fa^y`Fv`6k5kh^=x-8oe10S&M*Vc-Gek_+Sp4Fv8Ts3AEQ|4Vb3er9G#`k7kiXu$V>w?bCbWd4Imr&W&p-mbD%a z?rM)w@W>}o){SYAeh|*h@Myl-lX%R|Ga*ZZlB2`(vTZcKl}39$m1xXMS*e9Ze~lv- zO{SYj4emT8ly8fi5a)^dPW3=cm6i6GDwAPV^HC=a{iA#X-_9hq@P_q{jxo59I-F-) zZ55{~YGG1{5tkLa7Jk5OMDrMxM@OLcSQ>IBjNJH&?0&v?Aff2)&u5XNbmSr*xp)CS zMlQIJhjiqC1v!vJ4tU}H2B;4Ix!`w@1$od1FCZ6_|MmzuP=V)Aumhe|;57|wgWn+d z%>vEfxfSGuZ)5Nb=m>UTrw;4x-o+HO1l^F6Rpg-|;`SkrThc~7N&ZHO&u$-leVdau z;m@MiV`Fds*X_57Km6XdH7IW)>iP2dz}VXywVCymgIn}V2jXwJ^ThxDa610Cq{d9U z|9#;VU$w-l4bquz=@ZFS4c|Mjg__c&Y|0H7KRZy-^W^MC?R)>yXPZU~@BP)vUYZ~1 zdLwgs{+-Gmk7zo&>06lrjUR6E|43D2YfM|@6TG@fmjLhIu_rZxyPu~SRKvdbfW62E zBk~{&O5>fn2TJ|>E`mLwM?U<)VC3Q`a`6!~Kt2v)Cj`M7uoSsaLmsYy+{nXg@GY2+ zJiG!wA{V!j16BCG4jzNoHh46Kzvp0CE{mso)kS~u$02vGXI_+!&9sv(-SUwpkFZ*F zvsQX8nq&Af{s~w5kKWUgJ)0M6bawP@C{@gs9)8i2zh0}{F8Gf5s6o=j{d`Z@jAkC& zzOVf}_cgEHrGe(9(|#Rx<9o%A-55$Ym1+%Mtus5Wg?y*k8u%{4dFMM#W{Ap>J2KD7 z29;h${@Z>y+Jc)14yIC=uE!j&D|tf0#> z|GJE>K0-$i!9h73SiwOC*pDu*!$mi`Ru3n6aMA=`4n1Pfs}$(G7UVcHVtvqjhsB6> z=Zw5Sj}(zemqEe#+rF(cUzTSCwv22#M=pO5>1BQ`Xs)b7VY%_}%D~9U*w^0eu35@6 z!gHq_h0Q}wnawJWX@|-mw(ghRE0|^J?RuBXz^u{wd(elY&dv=Zle&G4W7@f9i#mpE z>|ucldqr|&uUZF&QEO$&JMSAl6)5oTIl*~zuJ4K)=jcSTtX);I7$RA%R34i5)fKqD zgtL6OqJ%4P@Fyq(XIIgyI#3<%q~VSN@3kG=JporiEx5c5CSsR!;C28`@4#gz7!9ZU z;qnj252x+_`Ubb6;9>O5>|g)zUY~(`8obZO;3gOk*SX+6IIjRdfj-#NG_V6YhbT&eVVarvGad$Wj*TK@&vC-jBCy~X#ZUXr~^*T5yjR37lS;i}S$ z+=jEx0hc(njlRpyimM+bW0!olHzTz=f^k3HRTW9<&bw;|wHj)qOK&syhd2C8o4&EZ z+-xo@^B|{o|Na%pqyHHVRtr5_TAh*eq}8cjJL2W-RRek^t^}f#a{B7IrfZlz{uAAUQJd3RFTC9Kd0a2pxQn&dq`3=w1Uz zf(!{FLx$Ml3*d2NNDmp>j|?Sf?cQk^Ss~Wj{h0(51*5@nFh%mnw^Z7Va#ORw-*lX& zwKtg=if=Nxe)N$RS67lZvaCM0t$0&Hve=s?XH$_&;KM1&+ls7`)-}eLH`Z28Ee_TM zu@8zjh914i@;TLrs{F%E<(kd+Ms$j)(#Myog9hKHT3ddTVOqK(xy@diVwuX!c}nFH z>#>^8Ol(!=%SxPgO_fsBsY4n4sjZl|pK?7fHe$ZyPtU@@9dIiBOorl_R5s*<15^V) zASXJ=2Q9o0gKqGf08V3bo3XXA*xD8F7;DBb+_ebe13DcAx621=ps_Y-oqa(X7-v{F|%h@ZGuKeMzxlclhf)h{`$Wkt^W^{m;X=m|9<_yKrX1j z-~K;?q<(Sue_G&@Jwo@|*Z<6U=ewtZQOb-NGZ{AC+X@(pIX$`Oofisz&&5zIKH zOW}AljvCl-<|Ye7?MTC~Ujdle(~{m7V|ixfa4@kyLi(1XWllWXot=vh`|U7(=uIq$ z%tU#ZC2Ok3;>4lZP(A3wmR&Qj`Bn-G1L9a^Qx2z?2%d|n!hNeqJU%@IX#)n}Me0H5 zofwZ_idIy*`4UU#hf^LgRBBTS-MQgZTW^m^Gb-T}#3N6OP;s~>}oMestg9n))yF}X1oGi_tIbzlf}X8Gaw{MiUF@TATrdkj5k z%L8v`V~^%S2>$-?d7BRBfjYF$DMsHO32Ymii>dd*snB~pZ0FoSOko^Vo4vW&dNvlG zb%Xz!>DUqwK>c2e5&6uIg(VRj*ENa;U3VgX!Va8V@Ct37Siw7|41OEQ7oW}9%5EX_ zKX-=avAbxi5YL`DLt&)an)wQDyq+jeYt2zd#9|PHv0r+9+i4FI9vnBN~Zkl+oVSh5`ow$QnqpcVbV}^j!-ElqH93y>v zsqog5-^OO)lxj3Q@@HV7_j<%U^kCA&3FyA{G-jy#vF&qX&h3(fiVOabx0!(%9a1pD zC<`m^1aWffJMin8f_~yVHm9Q&Hr0>8fa6K9T9pW2+cJ2*cH;zDPi7&UeLfg)|I{pu zuMXq+_z1>FO~K267|!`wiS?5L`TVE{P7H5B^m|Ke_Q^r1zAE>nnBwl5Bpx+L#4F{V zjCtQ10~We5{b3KB?6nG`{2cgb`M+p58_Y2_+I%{xCs+29@xr)Bx^+|Ld09C=KCDND zES0z&%|V(1$9NopQqN!-diYT-Ih4hFPh#Ahe)u!-Fe=9cFx~SGOk0u=yUdqsmbjq9 zEmMXpS%KN1q|L7+j&A42vWX#Z2+2ik#&8Tb3}o|Bf98CehgOwV+%?pjeunl~rPz&r zV+t^Qs*Hidn$YEXAioKzc$P1t=h?yB-YtZh+6ipuW=rFru?(Lz9wXE|`KV+Fu12na zzqS#bi^gGrQ8=SxKf$t6+=JWn@VTNNtxN29VxkA?>+`~)8c8Z{S}t$;<&yK;H?}%&&!_Jy?G=8 z_WlE#NnxBlej?T?`g6^2ZyK!ep=od^J^Dv*byzQ$j@RV9u@*RP62SGwUU*#{h&P=& z@L-%b2S=%5q;VLtw`@giT1Umg&Enk=s!1u`#T*&<(zb?b~Ax~hX~F&6o&yrEoh>jgIybA@N1kE zH?Ti!iz8U}bSiHAi9zUwdgvc`g_jS!xM=Hp?2Kwhp{Yy4>-2fkYy!2F@4nVL7wpXfx{yadYk45MMr zVHkgTi%k!lnZ7%Oju%0%SsO5QL>Auv4CmXv^UxKxYzzZ#6p6X74v@=ZP;qM{1HoF_# zdk6D=b{eB<!E>Sb(awrn!en&3KN(xc4@Xq3fc-)Q z%!l>hrty9pzIPP9%KI>7LpS7_gSi`wxO+$r)|TXfZMQ)~C72m!0%%m<6$Oel7*^#2 z`!lI*x)_7IMSa$4{=H{mfNbj(&=ae%%(bH(1S2qB!$yWT(idqgOK#=2Ue`o zW5nwy{7{VGza2c8V$=pp#q-9feGpS7Mso1EXw3W-1MOd3*|sqUUB~=FmxdaQX;R|i z*A;jaHv#t}gXx`Y&Rd@YV5hYjGxquMgn>Uwj!(hF%ox7d(G}Zd_6$>qhxIofx<4z& zvwL<(9M~JKbA0I9b1Du_7RTHSWc@1{XFF6N#XSsPJp-A4W&)bOhf!wi$GEZ25j{14 zzxCoV(QOY*Cv@kixV}_<)f&SVIdE`|I~RP|4F5yPe7vd(uT^6?b6G6yl7gVTvLlDB z2*I?MA?&m74xTHSaV{65pLoV4dIxggp#c2rZOC zp03g43v(ylJTeleO(I!$LSW?vQ!L+o9b1}vvt3XWv&%1G$twdEuS(?Gp8jm5QGmd! z0&G;)K=tEN?Dg-$M>`*(@0&oLQ%>aj-vJc#Jn_RpT(i$%Y;r2Znb9AGRcBqf=?1X& z(gN%+T!-hSK*{Ra*tQ~)54Or-&J_!)ZVY7X`@#6EHx!k*`iR#s;+anB9CmL9y1w@0 z2yt)S&kW^1%#OXeXsQO?<=YYOUh$@H4cT?UO62#3qFQMN#3ugL6S=T_` zDu09x>NhZ{CYXILs`76z|49o3WDzkP-0^JGqz3t&Ra4J4iJhnY*;F<0M*mj+cKMph5GR6RBxj^x4@ z{>=RxLEGPn)I9FU15IxrJ8%s4j~cLhv<_OW7VXE!I?$N57w_EjarSO^jF=aQfyW;r zXh3fcI^avEYI6=e`w9OHzlBemO}J|3b5#5`!u%rvoNvAichrfQ&Lzk^62bjWfjG8x zD|VMFak{53+NZ`b;7faYH^xx!qBq~_e8fH9Fpjo(1!avOltf0L_lJ(uRkDQF$Oz8T z`iYv&ZBe%?7^WMHklx0S)(!t+!$VuX9hXjhTU*4hvZY(XNqlLgN9SM{bWZ8W9jCV- zOMM)cX05_zJ2e(|KZ^Ld0>ZW3u=ms?+zhgZSULpfoe5n^7O@_f&5c)eSXbHRSx9^=Wh@)({Q z2ejn7Ao_kS^dHW`(;J)6;h6`$lz}j1dFmN>@w}cf?)-GY>#ED>>a-N+y3fRmcVxz& zK%Usti%TAdu}WDJ(V1Qt;&uQfRpVhfCyM9V#9_8-4%*KPfoiojN@`~y;Bs$j9kb!N z;~kiumW3e`>M$+Bm-rD*UqffOY0kr^Q-L%S{i6M%Phs{pl3!&N_-Zg8rgqjW8IgvH zCw?#s@kL0+ay$}UlT=F^gd_!VMY|~GXofO3I~)=HD$#A3DT~HOaNxT@F8wOnNX5Z) zJ{*YIqOY;gH5%+aA7Q3FXf^9MD)+|IDYrL2s=4v%9A{qG5yev@rsLA35onV)7E3Ho zU|yXKo5$tA_>O?oNL_3n<_`DBC|)WvVc6wrMEQiUrIjCB)h9A9#g`n^7mFWi^UCxB z9K0G$-BY41W^Kj~=3#t$M4m(ZQ#fF*C7)>6vegP-9vG9r;zR_`sv2RVOE`LPK5KL_*Z8Xq|K>dNGUI(+ZbnZpdUS%1wFR@c)Q z_9cde!;fOzfNsn-aL1)77Hm7ti&r!KsQqRP9(|5s;Cf#wdUfT(n?amXyb!T#ZFn=h z3vRf0isz6oBleX;=}#E$hNoiv@E+_E6wk|H_MF^JpJS9du-%2OOvs9X?RaNS(+=SZ zU2)%j^kDj7dpx=8N4xB{9F>`Ypc+MlPaXwz&oX314!}R!wYNZ1p?O~c5mZ)XCdocOG)0yX`oV)eXTM=^#7|fX)6t;pg865U;gi-Td>QmZxbn-1zSXNxaxM-=7a}<*xE<#|&Bn;H zlX2K!ARpcL;^$BGFe~)uk5;0sZKs2{Fi-k9&%mc0Ui3WI6D5iQ>=Qz{xh#mbB}Oc5 zWy)#A;fy)p&jSk*SXymEwZ}fRGg^p-8OM;gsEz2GM)9quAg+~Y<7|p!+iC-Tt?7%B z-6~AmGz_hyj2UYYNc$hxF@B~p`W=-~SM)y*tgAt3`VQcVHLr=bme=Rj7|p$S@@^3< z;<~bIh&P>97^D5b(QtSiPrrX;{9U*h?NesL{Bu8!OG!b`+-ZpH=EL{R*8FfTnaApT zA!)HO{Z!1Lsk97^MrBy~r3CeT^vTgv5pcdWid~%fJS&dNX2;WVk`HAvKg>4`qVm0^ zcze;4XX2w6Fg}$z4=2E@`~dnG0jrI*kaK7aoIF+_TYM)BmpP($sweAunX%963M}vV z4xY9@;WE>NN3|?4$$AL-Oc8CoKW;2r9K^Qm0~x(Hf*!+sxmEO2Hb&QAk#Q)`j1yxM z-`#ktXB|2&Ks5>Owp8wR_S5e=2U(enu-^n z1%6oU&ABg?m_52LZi)Lj&O+E0XTDV5Lz9n#Ez3Oj4h8sY;rosq#nW8P;joAIV0WMaD%+S+#G)_ znbn0FR|Dv=J)U#qr{T`yF>q)z1)Js)M_-idJp64P^KY+pgVyL-u z5@PN|(q>vHl`hsG-8qrx_c+kIM;cEnM{Dl zHT*nROHrl*MK^@|6{H0(szaVBW#G7-y{b>=;rFwEcLi4}(e zs3Q7)O&^2UUnzuHkN3c`sR?ZoQ+>l_AUvlW(Kj=SM(qB{h2rDEAmWjXrnz1+0VaYM-XxD z18# z<8$CTVFlci!&tFEjC&3Wp~9vt7%o;-5Nhzj;{T+|N85e0OsOGn$g=dd>{5@Acz z@N97;J;i6ERkvbXyC%H3x*ck}4RPj-8R~n;@!eDh-1`pHJGk(ek}DOBlW^91A8tKq z%eqJBu~_yE!F#SDsPkO(73~*~MtvUZ&>DB^%P=r05AD-$p?0_y&+A9CIIR>vLr5!c z4bIdG#QO2xsGAYUC&L{Oe@>5Dbyb+JpG2FZ6QKIk5B*+RaG8Duie6S?d3SLiT^NCD zpL?@v$U3N{#B!GyqtI_N6v`Le`R?Q+ILthV0r(Zk^fV z$p}nu&_m0$45(N~FxaLqmfRbU^qq$6Y2?oIXEFp#3T1e?!0UlQ%+5=}u|9gdTT=!T zlTe1ijq%@9X{2}@aYnlMDB6-n1H|~`#0Zq`H)7F^MfmPvf$EIjbj?_aA6oO!XS@fM zOMTd5>t4KC9*V5cP(B&D94Gt+VtDUqh_kIiK(ZY)Tte~HG8UX(g@(wngK~XRz&N&U_bLE~t*+vJ5*Mzw9K&(sem^@I8NfdiO2A&m3mj^pOCM20F&zy{rauzS&o0Y>9M)!Idn}2@`7GxOda2ZyWhc-*UO5f7DOxk1Xf&$VcwHHP?R%f)7a~{ z)NL#dJa3I{l^LvZ>`3*qA*}s&0w0#n#$9zA-pChi`}g6nZi%I>>Tg($4PpLVU)sNO zq(`hPDreb4%_fkJzvCF1tVS!ABjQ9MT6-EYdw&Fd_n5;@yq})dDKq1tm{;f_#-&By zyx)&c(SbWfFQPdGn!fJpE5QvHD+A)YZ&`?wJDEISTBovlrtR6hkK| zl!`jj;BG5p@9EvdXQSb*F&DyW6Mk@6gI_mgXh9a)pVn45)8fPVcINo=%$qYz z)}zj@9ZUOIaj&N?V^5?Y=gJAhE2r`HfsM$RW6MEeKC8>aaKsj5V_W?|+))i+zri1{ zY$f^nNH8l_$8n;?RP4XE3wN$XBQe#Es`~<&l^eo=Ps8zNoFm^qOGDPj*Jycl2X!5F zSy|nk7v4O;#y|c{ouEOhP6sh9-GT3;lW{;PAFbs@AFZQ|)9pMF{-qR+lcMN4Jdo~6 z)3JXM*ll?fFN7S!w5TX-%JJd>b9dlCETdgFqNmzYWLjE4q0J|(UfCI`A5@ueFO=IW zqG;D<6rRP2KKhF8Xq)Q8Z%oGpJrC|`+ksPy4KVvg<A6f9^E^JH0uQjnZ6t@ zqocU6a}AWj1vdG4;IX-YWZknUvCqTS10mdI9L+tSefaOyp6tIdlqDs7IPK{Ke97&` zx+mUDv+`twTTlL+63>#$(R|zz%-W}7%(;FJ22O}T&x=tUE9Rz6)eoX~fEsfa8B$Fv z0C!q|jukx_yEdM`#n^gwOc9j-@uI<|Y1rSf5al0YxMHe1T+CNvXr&7UuceqMmyJ0k zA)I$D7X31JLnC_zT>B^TGF-T*oXDr0ep7v8xAX#;8%>I4-xQx9U|y4ta_ZFJ%0YNi5S0 z=8P-7IHk^;4cdV;wu?p3(IB>03uB#Z7SgrCkP#cm!jA%5W;B+eIQ2IPi zWMcCuI+$4zV+XJzdH~za87M|*{HfR9g{|e%m}J_I@;_qOWra6GR%OxRLKYQFMzVOV z5|1a0qQU7j{!?4XcjqkW;9N|%i84NGQ%LXUdTe8#!w>I5IXb?O&NUslVM;MGogGDs ze+7n`wc&zigCW%P<+PTEcr~^&+awRd?Yy3R@NyE;jazY1l_R#@iRLcHhj?72#6e4y z;Hmfy*ZV|c&#N8q9G-){KjqO`7-FJdp)Rl^5OVfXpUB;AMR$j!1<{dx#N@21I2r>qvPninx>M;&AI^+=YFBS1z?NdD2UPwLh#x;(Zi}k%t zSpD4%>PH9DdjDZ`yXeNw*=9H!>cOU}QVf2q#me56aQKtKPhA?(TU(7aR>uUN#O?Up z+6Vzz^U&d85?)P}7nX?;@22uj2p*7%g69tryrM=JHtH$e~jb0#7XFRqZf-*W8nR~kVDpNgHP|#jQ^v9kOogqJ<=NuBaAuZ zkG5!qW^#V*dUzZR<=4fP!sJ`qWOJXNLadnKSo>!Kf}XS!eEg~arLltb^WAtldAl%W zS3Gw1EW&ApGI(fp5|TU%kaFyS5Nq)eIJpV~1R+fF8O?|T+PslrM3;T-dBnt?->$XdkF)ALJXVL>)&vm03^*oAi?;`L<7V9j z7_7$3+#Uzwd^8Pa_Ja7h}e-woEv84lBriasWM^Q1i{Cx1ccr!K-Mop%^DBT0BqRd!o_PDs7dnS&Y!V}ybV z`yH*9rO=!2y0pW>rRr2|lgm!+AEUDSbz$MJA?%k`#Nk?h@Z<9Wq5H5TF0nW*YYOd8 z)V1K>EB@R(H=kyXhP1jV&;HSUxbDDZp~FHi-WwSOm2O_#T+tw`SBVs(5ti`D2&I#p zGOmA3W`)&k+}R^$XU;g`T3rU)Hc!Q&S4r$(62Z*cb$ELFE&QHuK+f9~T8^wnZs0vQ zi&2E6btYVEQw447w)A|v0G+4Bah2y`ED!pDyc;i|shbJSgkxgW)HFOCb{V=6+l3AK zx6r-V9G#M{pm==)zMrqdi&1+Jl=%R|g;p@t5hI5+iP)U?3e83VjJt6gax>+)W|Rtd z4I99cQ9sc1L5{19d-7tMD-A5(;BMd_42v)nLs-siJpN4MA?Gcex|ma&;vaHJX1KaC_`A zOn70+;`CBD*I01-l~DA)pv#@_Msi#2QuOj3$ne&m;Ib-*Lrzb`rm+P))T0R%wK6WW z=tWuI1TGD-;>2tpF$!TSMnB^C=&L6;x&-js${TnuR-Ek>ZGsT?#l}+i-QQzK|4(^Asd%ZR7F8qdSx(EGTvsn0kpWt<4H1*28 zdGdBTyBFpQ=MEIG@_v8TCVBDuj~ptz61}){DJ;F1$_+P1(5XC%KFve8C2a%`A63U0 zk0Kt*trcp6a=7<^yKr+v2|p-&m32)Ovv2`D*ec4L9-^0G*`!LZuh!(O?rb?Mdb-}{ zg}!PT3@t8X>81is*wInwdp4c}{sakcPR*3f{qPVI=jHKys6N}>&ZotTtFV1k%qTSv zuJ+VhLWo;6A(k=wv&Pecu@IT2(R62UVckiQ#0i2B*82vsuH2wb>4= z3wEKCe@6}paO0xVE5>(3TPyysJcB+C z0aBr*6`4*KjI%&N|&SeiJ1Dq6Q>9gg{O z=ABbeaSo^4Ax-{n?@3L?br{t~tTqXL106lKjW)a*^yxc%Hqv*PQ9*4JLQ_?! zA6br$U0-3G-z4liDbHv9E@1J_)@=RpDZU6FaBS8(=*#}0a>rdV|88`dgM;V%GR5qs1=Re0YmX?P!Nu19m5UV zxp=%W9*WJ!p5?1Qjgh0xU}t`*zY62j za8@bEal`fQj6c}`^&)U%zY}H0)78<*(t)sum-0J6!9bJfV1-O=Iv z1^o7kL(Gs*cs%eORt;9=;#zq=C~HDl{1&{M_z=BwE}_*SYgBhO!j4|{!u+FiaOy}L zl-8)A;j}6+#RYmM30PZPhM|F~I9E6iyWU#CpubqPw7)^{pPGY56P^fH=RU)}pq0X% z@blPq-2)XSULX>OhiAx0Sa`oOvKY=kC3p|954JHpjl%m&nd3O zT<3h=Gx`C$cM0sF8;%hj3t6-588n84FsfRMgI@P%vZ*I0dM9%F2tA%&o58yckyQPU zFOsqYDHp{kdx!fd?G?m2uR*ZZ?#DchvuJtJg`T_Ha>;f_=AAL(ukm^e&1l7ipFNm! zxgB3WI4=9*kqq}O+JZ{ZG{N2asqnp|NeCR?EE~Q>8D^8(@R!AC#<}W=c3C)wwBIOP ze%}lGyNB}Mr-jULJt?$bBgc&@)iTF+@+@+_COb3w0i2(|lMULt7fLpJ5#Ol8oe!SC zZ+8!Vyg30rSG76b#0eYE{(_OgI*b#eke>{apY{Va^#+>CBJc44>Lbd)`kr)-cdd*4y!i7&S?e6uR2ymjR` z3r)KDRigNm5^rl6ajlb{xcA?}c|;f9>d>9nn|kr%^ncO3MS(|8$W!&DA-i24foEpc zG^7`qXE18?n+fJ+u)qaSM zF*3Yunt_#*-0A1F2H9@j_#WPXX*;_T3QtjNx)D3Vo5gC#uG|-P3S+nJ!IDjTFugpQ ze=d)w&$=y&gk0dE;tQ zE8YzY;F)Mgo=={Ff1b2w|7Q_Q9_>%d@6Kprs>#!$EN->NJSS!!LO)rv%@|iseIu~? z?q@71{e}5w;^=$DoOL;7n66>SeEEU2&FM+OZ?&rc951iJfU!pqHcFe%|9OhDGtWUo zrwVgZH5gXA1jXA|BkN`vG)DF$4CRS-vLk2FYgn|8V~8{Y@xyRtFM_a;!uJen8VWgs=t zPOR`y<&r2z_GmADQQ#fPpc8u3Zw_RqV`uTwW;x!A)l%mAZCHQdo^Ue19+5|rxqRPu zbbhx?nEL%ZPW5r->mCZcoxdBqwm-wNE!JEU@(~p~W}@o(GT1EW!>ehAj5^*R+}Ko# zT;&309&X31ab?1Zwa2l&(T~G=X;JNF0+!9b4uxTnH2vL9tVA(D>dt4dKAXW)#i5M5 z_ep5gpuzZENtCxr=g2-uP|7pnpm-;)eB?xnK3B1(%A5nlD*km{gBcvzif8!~4;Bw+ z?H3mo-ffHXxmx^aF_30`+^BkRpP+ONyyvP*N3Q@5@LvMCp8^N}bY`clSf22!fn!`J z>@m?}=LRbb)Na71p&bO*{70Cc&?rnjeGKb{)Cs4~D>DCr_(hB6Rz%2N36Fcfz~t%% zp}GHjWOl9=rU!~q%V*>8sIwo5WA%khv<*IDT@N2@J+0ksC=){(J zeORvj0Y^AUj2H*9ZgDPK-f6PAS0X!KEaHf>JsG^}qRh-DlS#8ivu05NUpC$qCLT%W z9S4DV3zK>B_%&RcR>Wl+y_ng(fKKo9xH)_XKF$i~?}*8Wt#~S=J$)cd5i?U~!!`;@ z-~JW8&Ire@YtB?&lmz9lGW;nyAQ-+d;)h;pf?|^`)K5~(R`g@zo`2!teLzNow?ak6 z0N(R2gMFQWaA1!M8WiH#taTZO9xW4IFB&LwD-q9!jghd9KOp>w(`B>jFpjVr$(?tS zWY$Nm>9jMOA4&^&Zt`e4n)TwS4pD4_-u$zm73X$~;Xtusao6Bjte$!b!o%w_?_KVK<&1dlx$KSn0v(~pFkj)6raRkB-GEa{y12RX zo$SYFL*BR6#H>~ig@FZ!F$I~lN*l$Pb=jD{zJ%ijCGygP0#>aTV|sl=8@t7fp5fUv zY4r*bo_QSj$c1Bj6!E&IB5O6OasS~cMx0IIl_3fkn?91=d;W)n{u0F%Z}Wa z-M1M7WhT+DVK>6Y91&t0bc7#s`!Z60uCU2vwD8U*2-~7XdtK3(oda778aeH-YEnLb z*{npTe(i+f7pn#J&%@b1Mvdxbhh&{P-<7RfnZvAMAA}C)6@=!>2l$aUnw1lWurXq_ z(B8y^S6>uxck9ty^Jl2wAXeZFY4qitPC2}kd=Wo7_2yJEM}0}8GL!v zo|l7<$>#q%nokcsgpr~cGnnWG-QEfOr)o8-`nRQB${|5@dS8xd^#;D*joG1W6*BkA zn0ELYvb(kjBWkjEWa~UwcP?Sh9BsT0O`wbXF8Ke-XhrNe(v>O46$HD4Aq)<*$L@1CQSxPt@WCXJkI)gm z;@zogD8}g({OK-M8~B>vklBduZB%?HRhAU-eT%-JTkOUaa-(=VW{b@2#&)6fd21TF zid7a31>Af#6Q^dYvekkX1nn2~(6a%%N>9rol1GcxSc@=YlPLopwZY^A(adryh3xJ( z*jjf)y66MmjlKa@;~q?koq%>-ow!Kx1ftsRky(F8rd-#j!s^^Y8oAa9ZHfZ8DzOTe z)rWJKPZDnL_oRA(0&gDe&xdI*kTmf*&d=25qUW91K6)+G7H9~+_a$-5>iNQvncvWU z@NVIleG0cZi9U_)PE0M@AUtgHV(o^f!o3O=c8Iit$8Q(9n&)EdxLZQ+$0=x=UBEx@ zi)g6YQ7Dkfk+%xyl~XJ1$(V%Zvs^0*1wr7l=>+M zd1j;8HrftFH*Dw|(b*0mf$^_4)xUy)}dl-+g=93-WXsRfFjWPH$>elJ-``s=q zJ1ABe+PoKz-k2&xtjXrArc^3FIfw|yP%L>nnBzw2&`+%|l;?MbpgDkQ$33~U;s-kA z)nHPb2S*QA<507EvVBjwBFH9!KgBcgQ&edgAB1PUx69m~=kx6uJ3g0badt^9w92A5#OE_U2`}MX)__9M z4@_R#mCxp?^Ul0Gcz>!VU)@qU+UjWjXH1!ED$F}9`W5q&MEkaYqbow;{b)Nz z$HdZCyes^UnB(lRY6Lg<@Pk1*Z!S5HG}}kG-)KquuHCsxEbTeice?P;?mX^39n6j; z>mjc!<~xqWu;a@P)J^&YkM=(>_IwCuG=XQ`G}v+O4_Ib);mav{{9YRhmF{9JETtVQ z!o>4lz6`0Rrc|i-i77jR*>C@T{Bd&RhePVLADuwMV+Y}8Va#8m-M68gz_uG!3Rmy# z6qfrGakoWZejMhE9*KpBJ2;BQsm5$u+7+X}2f+Ag9A&!#dA9#q%u6|rS>o3W_mn#@ z`kAWWjjedQUtrdhksSNvxiEX_NAwc&WfNwk@w5?qNqZXtd?8{ehhFCR_Ys=q+9}cIKG1 z5&R_P1Pn8ExaOof=ark%XzfMe`P>c|w{{e7t{2Z(pJH6vJqtHQdpPA`YtEY~eo

G`9usC<#GAlWI`8Vw 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%0D_2I(HU^@K_JSaG^8Lr9&T$(l5OZ7UXvit&AeSew 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata new file mode 100644 index 0000000000000000000000000000000000000000..58dba597b5f35b4a918ec7eaf79c3ea877e03ddb GIT binary patch literal 360000 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%0AdvjP^tQv=h==h1hxs{SIYi9fBAa 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

dI>*xmh6a61GH&Wa8 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 AkpKVy literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 new file mode 100644 index 0000000000000000000000000000000000000000..164d1c0e02643840d748fe3bc6646843dbe475f6 GIT binary patch literal 137771 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 Qa-1BTj~j45Hm0rn|C|PA7XSbN literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 new file mode 100644 index 0000000000000000000000000000000000000000..5c161e7e4f51131e1aa2b339bf4d45af0cec1bf5 GIT binary patch literal 137771 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 Q4o~>=;rIpKVue5de;0j13;+NC literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 new file mode 100644 index 0000000000000000000000000000000000000000..1846b543b1a42b7b8f8dbe640bc48b9143f0311f GIT binary patch literal 137771 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_iterate_input.py b/demos/offline_ivf/tests/test_iterate_input.py new file mode 100644 index 0000000000..3f59071102 --- /dev/null +++ b/demos/offline_ivf/tests/test_iterate_input.py @@ -0,0 +1,132 @@ +# 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 numpy as np +import unittest +from typing import List +from utils import load_config +from tests.testing_utils import TestDataCreator +import tempfile +from dataset import create_dataset_from_oivf_config + +DIMENSION: int = 768 +SMALL_FILE_SIZES: List[int] = [100, 210, 450] +LARGE_FILE_SIZES: List[int] = [1253, 3459, 890] +TEST_BATCH_SIZE: int = 500 +SMALL_SAMPLE_SIZE: int = 1000 +NUM_FILES: int = 3 + + +class TestUtilsMethods(unittest.TestCase): + """ + Unit tests for iterate and decreasing_matrix methods. + """ + + def test_iterate_input_file_smaller_than_batch(self): + """ + Tests when batch size is larger than the file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_sizes=SMALL_FILE_SIZES, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + db_iterator = create_dataset_from_oivf_config( + cfg, args.xb + ).iterate(0, TEST_BATCH_SIZE, np.float32) + + for i in range(len(SMALL_FILE_SIZES) - 1): + vecs = next(db_iterator) + if i != 1: + self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) + else: + self.assertEqual( + vecs.shape[0], sum(SMALL_FILE_SIZES) - TEST_BATCH_SIZE + ) + + def test_iterate_input_file_larger_than_batch(self): + """ + Tests when batch size is smaller than the file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_sizes=LARGE_FILE_SIZES, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + db_iterator = create_dataset_from_oivf_config( + cfg, args.xb + ).iterate(0, TEST_BATCH_SIZE, np.float32) + + for i in range(len(LARGE_FILE_SIZES) - 1): + vecs = next(db_iterator) + if i != 9: + self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) + else: + self.assertEqual( + vecs.shape[0], + sum(LARGE_FILE_SIZES) - TEST_BATCH_SIZE * 9, + ) + + def test_get_vs_iterate(self) -> None: + """ + Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_size=SMALL_SAMPLE_SIZE, + num_files=NUM_FILES, + normalise=True, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + ds = create_dataset_from_oivf_config(cfg, args.xb) + vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) + self.assertEqual( + vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES + ) + vecs_by_get = ds.get(list(range(vecs_by_iterator.shape[0]))) + self.assertTrue(np.all(vecs_by_iterator == vecs_by_get)) + + def test_iterate_back(self) -> None: + """ + Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_size=SMALL_SAMPLE_SIZE, + num_files=NUM_FILES, + normalise=True, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + ds = create_dataset_from_oivf_config(cfg, args.xb) + vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) + self.assertEqual( + vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES + ) + vecs_chunk = np.vstack( + [ + next(ds.iterate(i, 543, np.float32)) + for i in range(0, SMALL_SAMPLE_SIZE * NUM_FILES, 543) + ] + ) + self.assertTrue(np.all(vecs_by_iterator == vecs_chunk)) diff --git a/demos/offline_ivf/tests/test_offline_ivf.py b/demos/offline_ivf/tests/test_offline_ivf.py new file mode 100644 index 0000000000..b3501122ca --- /dev/null +++ b/demos/offline_ivf/tests/test_offline_ivf.py @@ -0,0 +1,545 @@ +# 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 numpy as np +import unittest +from utils import load_config +from offline_ivf import OfflineIVF +import pathlib as pl +import tempfile +import shutil +import os +from typing import List +from tests.testing_utils import TestDataCreator +from run import process_options_and_run_jobs + +INDEX_TEMPLATE_FILE: str = "/tests/test_data/IVF256_PQ4.empty.faissindex" +OPQ_INDEX_TEMPLATE_FILE: str = ( + "/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex" +) +KNN_RESULTS_FILE: str = ( + "/my_test_data_in_my_test_data/knn/I0000000000_IVF256_PQ4_np2.npy" +) +TEST_INDEX_A: str = "/tests/test_data/goku_lang/IVF256_PQ4.faissindex" +TEST_INDEX_DATA_A: str = ( + "/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata" +) +TEST_INDEX_B: str = "/tests/test_data/coco_lang/IVF256_PQ4.faissindex" +TEST_INDEX_DATA_B: str = ( + "/tests/test_data/coco_lang/IVF256_PQ4.faissindex.ivfdata" +) +TEST_INDEX_OPQ: str = "/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex" +TEST_INDEX_DATA_OPQ: str = ( + "/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata" +) +A_INDEX_FILES: List[str] = [ + "I_a_gt.npy", + "D_a_gt.npy", + "vecs_a.npy", + "D_a_ann_IVF256_PQ4_np2.npy", + "I_a_ann_IVF256_PQ4_np2.npy", + "D_a_ann_refined_IVF256_PQ4_np2.npy", +] + +A_INDEX_OPQ_FILES: List[str] = [ + "I_a_gt.npy", + "D_a_gt.npy", + "vecs_a.npy", + "D_a_ann_OPQ4_IVF256_PQ4_np200.npy", + "I_a_ann_OPQ4_IVF256_PQ4_np200.npy", + "D_a_ann_refined_OPQ4_IVF256_PQ4_np200.npy", +] + +B_INDEX_FILES: List[str] = [ + "I_b_gt.npy", + "vecs_b_gt.npy", + "vecs_b_ann_IVF256_PQ4_np2.npy", + "D_b_ann_gt_IVF256_PQ4_np2.npy", + "I_b_ann_gt_IVF256_PQ4_np2.npy", + "margin_refined_IVF256_PQ4_np2.npy", + "idx_b_ann_IVF256_PQ4_np2.npy", +] + + +class TestOIVF(unittest.TestCase): + """ + Unit tests for OIVF. Some of these unit tests first copy the required test data objects and puts them in the tempdir created by the context manager. + """ + + def assert_file_exists(self, filepath: str) -> None: + path = pl.Path(filepath) + self.assertEqual((str(path), path.is_file()), (str(path), True)) + + def test_consistency_check(self) -> None: + """ + Test the OIVF consistency check step, that it throws if no other steps have been ran. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("consistency_check") + self.assertRaises( + AssertionError, process_options_and_run_jobs, test_args + ) + + def test_train_index(self) -> None: + """ + Test the OIVF train index step, that it correctly produces the empty.faissindex template file. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + empty_index = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + ".empty.faissindex" + ) + self.assert_file_exists(empty_index) + + def test_index_shard_equal_file_sizes(self) -> None: + """ + Test the case where the shard size is a divisor of the database size and it is equal to the first file size. + """ + + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + index_shard_size = 10000 + num_files = 3 + file_size = 10000 + xb_ds_size = num_files * file_size + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=num_files, + file_size=file_size, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=index_shard_size, + query_batch_size=1000, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("index_shard") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + num_shards = xb_ds_size // index_shard_size + if xb_ds_size % index_shard_size != 0: + num_shards += 1 + print(f"number of shards:{num_shards}") + for i in range(num_shards): + index_shard_file = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + f".shard_{i}" + ) + self.assert_file_exists(index_shard_file) + + def test_index_shard_unequal_file_sizes(self) -> None: + """ + Test the case where the shard size is not a divisor of the database size and is greater than the first file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + file_sizes = [20000, 15001, 13990] + xb_ds_size = sum(file_sizes) + index_shard_size = 30000 + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["IVF256,PQ4"], + training_sample=9984, + file_sizes=file_sizes, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=index_shard_size, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("index_shard") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + num_shards = xb_ds_size // index_shard_size + if xb_ds_size % index_shard_size != 0: + num_shards += 1 + print(f"number of shards:{num_shards}") + for i in range(num_shards): + index_shard_file = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + f".shard_{i}" + ) + self.assert_file_exists(index_shard_file) + + def test_search(self) -> None: + """ + Test search step using test data objects to bypass dependencies on previous steps. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + os.makedirs(tmpdirname + "/my_test_data/", exist_ok=True) + num_files = 3 + for i in range(num_files): + test_index_shard = ( + os.getcwd() + + f"/tests/test_data/goku_lang/IVF256_PQ4.shard_{i}" + ) + shutil.copy(test_index_shard, tmpdirname + "/my_test_data/") + file_size = 10000 + query_batch_size = 10000 + total_batches = num_files * file_size // query_batch_size + if num_files * file_size % query_batch_size != 0: + total_batches += 1 + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=query_batch_size, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("search") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + # TODO: add check that there are number of batches total of files + knn_file = cfg["output"] + KNN_RESULTS_FILE + self.assert_file_exists(knn_file) + + def test_evaluate_without_margin(self) -> None: + """ + Test evaluate step using test data objects, no margin evaluation, single index. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + goku_index_file = os.getcwd() + TEST_INDEX_A + goku_index_data = os.getcwd() + TEST_INDEX_DATA_A + shutil.copy(goku_index_file, new_path) + shutil.copy(goku_index_data, new_path) + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=10000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("evaluate") + process_options_and_run_jobs(test_args) + common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" + for filename in A_INDEX_FILES: + file_to_check = common_path + filename + self.assert_file_exists(file_to_check) + + def test_evaluate_without_margin_OPQ(self) -> None: + """ + Test evaluate step using test data objects, no margin evaluation, single index. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + OPQ_INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + goku_index_file = os.getcwd() + TEST_INDEX_OPQ + goku_index_data = os.getcwd() + TEST_INDEX_DATA_OPQ + shutil.copy(goku_index_file, new_path) + shutil.copy(goku_index_data, new_path) + + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=200, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=10000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("evaluate") + process_options_and_run_jobs(test_args) + common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" + for filename in A_INDEX_OPQ_FILES: + file_to_check = common_path + filename + self.assert_file_exists(file_to_check) + + def test_evaluate_with_margin(self) -> None: + """ + Test evaluate step using test data objects with margin evaluation, pair of indexes A and B case. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE + new_path = f"{tmpdirname}/my_test_data/" + os.makedirs(new_path, exist_ok=True) + shutil.copy(test_index_path, new_path) + goku_index_file = os.getcwd() + TEST_INDEX_A + goku_index_data = os.getcwd() + TEST_INDEX_DATA_A + shutil.copy(goku_index_file, new_path) + shutil.copy(goku_index_data, new_path) + coco_index_file = os.getcwd() + TEST_INDEX_B + coco_index_data = os.getcwd() + TEST_INDEX_DATA_B + queries_path = f"{tmpdirname}/my_queries_data/" + os.makedirs(queries_path, exist_ok=True) + shutil.copy(coco_index_file, queries_path) + shutil.copy(coco_index_data, queries_path) + + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=10000, + evaluation_sample=100, + with_queries_ds=True, + evaluate_by_margin=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("evaluate") + process_options_and_run_jobs(test_args) + common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" + + for filename in A_INDEX_FILES + B_INDEX_FILES: + file_to_check = common_path + filename + self.assert_file_exists(file_to_check) + + def test_split_batch_size_bigger_than_file_sizes(self) -> None: + """ + Test split_files step, batch size bigger than file sizes. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + test_file_sizes = [19999, 20001, 30000, 10000] + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + file_sizes=test_file_sizes, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=40000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("search") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("split_files") + process_options_and_run_jobs(test_args) + + common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" + I_groundtruth_files = [ + "I0000000000_IVF256_PQ4_np2.npy", + "I0000040000_IVF256_PQ4_np2.npy", + ] + first_file_gt = I_groundtruth_files.pop(0) + I_groundtruth = np.load(common_path + first_file_gt) + for batched_file in I_groundtruth_files: + I_groundtruth = np.vstack( + [I_groundtruth, np.load(common_path + batched_file)] + ) + split_files = sorted( + [ + "mm5_p5.x2y.002.idx.npy", + "mm5_p5.x2y.003.idx.npy", + "mm5_p5.x2y.000.idx.npy", + "mm5_p5.x2y.001.idx.npy", + ] + ) + first_file = split_files.pop(0) + output_path = ( + common_path + + "dists5_p5.my_test_data-my_queries_data.IVF256_PQ4.k2.np2.fp32-shard/" + ) + + I_all_splits = np.load(output_path + first_file) + for filename in split_files: + self.assert_file_exists(output_path + filename) + I = np.load(output_path + filename) + I_all_splits = np.vstack([I_all_splits, I]) + + self.assertTrue((I_all_splits == I_groundtruth).all()) + + def test_split_batch_size_smaller_than_file_sizes(self) -> None: + """ + Test split_files step, the batch size less than file sizes + """ + test_file_sizes = [14995, 5005] + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + file_sizes=test_file_sizes, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=5000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("search") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("split_files") + process_options_and_run_jobs(test_args) + + common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" + I_groundtruth_files = [ + "D_approx0000000000_IVF256_PQ4_np2.npy", + "D_approx0000005000_IVF256_PQ4_np2.npy", + "D_approx0000010000_IVF256_PQ4_np2.npy", + "D_approx0000015000_IVF256_PQ4_np2.npy", + ] + + first_file_gt = I_groundtruth_files.pop(0) + I_groundtruth = np.load(common_path + first_file_gt) + for batched_file in I_groundtruth_files: + I_groundtruth = np.vstack( + [I_groundtruth, np.load(common_path + batched_file)] + ) + split_files = sorted( + ["mm5_p5.x2y.000.dist.npy", "mm5_p5.x2y.001.dist.npy"] + ) + output_path = ( + common_path + + "dists5_p5.my_test_data-my_queries_data.IVF256_PQ4.k2.np2.fp32-shard/" + ) + first_file = split_files.pop(0) + I_all_splits = np.load(output_path + first_file) + for filename in split_files: + self.assert_file_exists(output_path + filename) + I = np.load(output_path + filename) + I_all_splits = np.vstack([I_all_splits, I]) + + self.assertTrue((I_all_splits == I_groundtruth).all()) + + def test_split_files_with_corrupted_input_file(self) -> None: + """ + Test split_files step, the batch size less than file sizes + """ + test_file_sizes = [14995, 5005] + with tempfile.TemporaryDirectory() as tmpdirname: + k = 2 + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + file_sizes=test_file_sizes, + nprobe=2, + k=k, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=5000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("search") + process_options_and_run_jobs(test_args) + # Corrupts the last file + common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" + D_corrupt_file = np.empty((0, k), dtype=np.float32) + np.save( + common_path + "D_approx0000015000_IVF256_PQ4_np2.npy", + D_corrupt_file, + ) + test_args = data_creator.setup_cli("split_files") + + self.assertRaises( + AssertionError, process_options_and_run_jobs, test_args + ) diff --git a/demos/offline_ivf/tests/testing_utils.py b/demos/offline_ivf/tests/testing_utils.py new file mode 100644 index 0000000000..34751f278a --- /dev/null +++ b/demos/offline_ivf/tests/testing_utils.py @@ -0,0 +1,180 @@ +# 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 yaml +import numpy as np +from typing import Dict, List, Optional + +OIVF_TEST_ARGS: List[str] = [ + "--config", + "--xb", + "--xq", + "--command", + "--cluster_run", + "--no_residuals", +] + + +def get_test_parser(args) -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + for arg in args: + parser.add_argument(arg) + return parser + + +class TestDataCreator: + def __init__( + self, + tempdir: str, + dimension: int, + data_type: np.dtype, + index_factory: Optional[List] = ["OPQ4,IVF256,PQ4"], + training_sample: Optional[int] = 9984, + index_shard_size: Optional[int] = 1000, + query_batch_size: Optional[int] = 1000, + evaluation_sample: Optional[int] = 100, + num_files: Optional[int] = None, + file_size: Optional[int] = None, + file_sizes: Optional[List] = None, + nprobe: Optional[int] = 64, + k: Optional[int] = 10, + metric: Optional[str] = "METRIC_L2", + normalise: Optional[bool] = False, + with_queries_ds: Optional[bool] = False, + evaluate_by_margin: Optional[bool] = False, + ) -> None: + self.tempdir = tempdir + self.dimension = dimension + self.data_type = np.dtype(data_type).name + self.index_factory = {"prod": index_factory} + if file_size and num_files: + self.file_sizes = [file_size for _ in range(num_files)] + elif file_sizes: + self.file_sizes = file_sizes + else: + raise ValueError("no file sizes provided") + self.num_files = len(self.file_sizes) + self.training_sample = training_sample + self.index_shard_size = index_shard_size + self.query_batch_size = query_batch_size + self.evaluation_sample = evaluation_sample + self.nprobe = {"prod": [nprobe]} + self.k = k + self.metric = metric + self.normalise = normalise + self.config_file = self.tempdir + "/config_test.yaml" + self.ds_name = "my_test_data" + self.qs_name = "my_queries_data" + self.evaluate_by_margin = evaluate_by_margin + self.with_queries_ds = with_queries_ds + + def create_test_data(self) -> None: + datafiles = self._create_data_files() + files_info = [] + + for i, file in enumerate(datafiles): + files_info.append( + { + "dtype": self.data_type, + "format": "npy", + "name": file, + "size": self.file_sizes[i], + } + ) + + config_for_yaml = { + "d": self.dimension, + "output": self.tempdir, + "index": self.index_factory, + "nprobe": self.nprobe, + "k": self.k, + "normalise": self.normalise, + "metric": self.metric, + "training_sample": self.training_sample, + "evaluation_sample": self.evaluation_sample, + "index_shard_size": self.index_shard_size, + "query_batch_size": self.query_batch_size, + "datasets": { + self.ds_name: { + "root": self.tempdir, + "size": sum(self.file_sizes), + "files": files_info, + } + }, + } + if self.evaluate_by_margin: + config_for_yaml["evaluate_by_margin"] = self.evaluate_by_margin + q_datafiles = self._create_data_files("my_q_data") + q_files_info = [] + + for i, file in enumerate(q_datafiles): + q_files_info.append( + { + "dtype": self.data_type, + "format": "npy", + "name": file, + "size": self.file_sizes[i], + } + ) + if self.with_queries_ds: + config_for_yaml["datasets"][self.qs_name] = { + "root": self.tempdir, + "size": sum(self.file_sizes), + "files": q_files_info, + } + + self._create_config_yaml(config_for_yaml) + + def setup_cli(self, command="consistency_check") -> argparse.Namespace: + parser = get_test_parser(OIVF_TEST_ARGS) + + if self.with_queries_ds: + return parser.parse_args( + [ + "--xb", + self.ds_name, + "--config", + self.config_file, + "--command", + command, + "--xq", + self.qs_name, + ] + ) + return parser.parse_args( + [ + "--xb", + self.ds_name, + "--config", + self.config_file, + "--command", + command, + ] + ) + + def _create_data_files(self, name_of_file="my_data") -> List[str]: + """ + Creates a dataset "my_test_data" with number of files (num_files), using padding in the files + name. If self.with_queries is True, it adds an extra dataset "my_queries_data" with the same number of files + as the "my_test_data". The default name for embeddings files is "my_data" + .npy. + """ + filenames = [] + for i, file_size in enumerate(self.file_sizes): + # np.random.seed(i) + db_vectors = np.random.random((file_size, self.dimension)).astype( + self.data_type + ) + filename = name_of_file + f"{i:02}" + ".npy" + filenames.append(filename) + np.save(self.tempdir + "/" + filename, db_vectors) + return filenames + + def _create_config_yaml(self, dict_file: Dict[str, str]) -> None: + """ + Creates a yaml file in dir (can be a temporary dir for tests). + """ + filename = self.tempdir + "/config_test.yaml" + with open(filename, "w") as file: + yaml.dump(dict_file, file, default_flow_style=False) diff --git a/demos/offline_ivf/utils.py b/demos/offline_ivf/utils.py new file mode 100644 index 0000000000..378af00c30 --- /dev/null +++ b/demos/offline_ivf/utils.py @@ -0,0 +1,94 @@ +# 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 numpy as np +import os +from typing import Dict +import yaml +import faiss +from faiss.contrib.datasets import SyntheticDataset + + +def load_config(config): + assert os.path.exists(config) + with open(config, "r") as f: + return yaml.safe_load(f) + + +def faiss_sanity_check(): + ds = SyntheticDataset(256, 0, 100, 100) + xq = ds.get_queries() + xb = ds.get_database() + index_cpu = faiss.IndexFlat(ds.d) + index_gpu = faiss.index_cpu_to_all_gpus(index_cpu) + index_cpu.add(xb) + index_gpu.add(xb) + D_cpu, I_cpu = index_cpu.search(xq, 10) + D_gpu, I_gpu = index_gpu.search(xq, 10) + assert np.all(I_cpu == I_gpu), "faiss sanity check failed" + assert np.all(np.isclose(D_cpu, D_gpu)), "faiss sanity check failed" + + +def margin(sample, idx_a, idx_b, D_a_b, D_a, D_b, k, k_extract, threshold): + """ + two datasets: xa, xb; n = number of pairs + idx_a - (np,) - query vector ids in xa + idx_b - (np,) - query vector ids in xb + D_a_b - (np,) - pairwise distances between xa[idx_a] and xb[idx_b] + D_a - (np, k) - distances between vectors xa[idx_a] and corresponding nearest neighbours in xb + D_b - (np, k) - distances between vectors xb[idx_b] and corresponding nearest neighbours in xa + k - k nearest neighbours used for margin + k_extract - number of nearest neighbours of each query in xb we consider for margin calculation and filtering + threshold - margin threshold + """ + + n = sample + nk = n * k_extract + assert idx_a.shape == (n,) + idx_a_k = idx_a.repeat(k_extract) + assert idx_a_k.shape == (nk,) + assert idx_b.shape == (nk,) + assert D_a_b.shape == (nk,) + assert D_a.shape == (n, k) + assert D_b.shape == (nk, k) + mean_a = np.mean(D_a, axis=1) + assert mean_a.shape == (n,) + mean_a_k = mean_a.repeat(k_extract) + assert mean_a_k.shape == (nk,) + mean_b = np.mean(D_b, axis=1) + assert mean_b.shape == (nk,) + margin = 2 * D_a_b / (mean_a_k + mean_b) + above_threshold = margin > threshold + print(np.count_nonzero(above_threshold)) + print(idx_a_k[above_threshold]) + print(idx_b[above_threshold]) + print(margin[above_threshold]) + return margin + + +def add_group_args(group, *args, **kwargs): + return group.add_argument(*args, **kwargs) + + +def get_intersection_cardinality_frequencies( + I: np.ndarray, I_gt: np.ndarray +) -> Dict[int, int]: + """ + Computes the frequencies for the cardinalities of the intersection of neighbour indices. + """ + nq = I.shape[0] + res = [] + for ell in range(nq): + res.append(len(np.intersect1d(I[ell, :], I_gt[ell, :]))) + values, counts = np.unique(res, return_counts=True) + return dict(zip(values, counts)) + + +def is_pretransform_index(index): + if index.__class__ == faiss.IndexPreTransform: + assert hasattr(index, "chain") + return True + else: + assert not hasattr(index, "chain") + return False From 562148786e18f0a2952531058cb1943bb2107599 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 21 Dec 2023 15:18:16 -0800 Subject: [PATCH 003/206] Remove unused function from faiss/impl/ProductQuantizer.cpp Summary: `-Wunused-function` has identified an unused function. This diff removes it. In many cases these functions have existed for years in an unused state. Reviewed By: bunnypak Differential Revision: D52355753 fbshipit-source-id: 54c8b47224c1dafc4e2464fe4e528c78ecabf0b8 --- faiss/impl/ProductQuantizer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/faiss/impl/ProductQuantizer.cpp b/faiss/impl/ProductQuantizer.cpp index 8ae033ca8f..afcb7cbb9d 100644 --- a/faiss/impl/ProductQuantizer.cpp +++ b/faiss/impl/ProductQuantizer.cpp @@ -780,10 +780,6 @@ void ProductQuantizer::search_ip( init_finalize_heap); } -static float sqr(float x) { - return x * x; -} - void ProductQuantizer::compute_sdc_table() { sdc_table.resize(M * ksub * ksub); From 65b08ef2b728697810adfe691ac8986246924f97 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 21 Dec 2023 15:31:48 -0800 Subject: [PATCH 004/206] Remove unused function from faiss/utils/quantize_lut.cpp Summary: `-Wunused-function` has identified an unused function. This diff removes it. In many cases these functions have existed for years in an unused state. Reviewed By: bunnypak Differential Revision: D52355736 fbshipit-source-id: e315cf420053472218bbf2fdd647ab073c6f6cd6 --- faiss/utils/quantize_lut.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/faiss/utils/quantize_lut.cpp b/faiss/utils/quantize_lut.cpp index 642f601d79..ca917e582c 100644 --- a/faiss/utils/quantize_lut.cpp +++ b/faiss/utils/quantize_lut.cpp @@ -24,20 +24,6 @@ namespace quantize_lut { namespace { -float round_uint8_and_mul(float* tab, size_t n) { - float max = 0; - for (int i = 0; i < n; i++) { - if (fabs(tab[i]) > max) { - max = fabs(tab[i]); - } - } - float multiplier = 127 / max; - for (int i = 0; i < n; i++) { - tab[i] = floorf(tab[i] * multiplier + 128); - } - return multiplier; -} - // there can be NaNs in tables, they should be ignored float tab_min(const float* tab, size_t n) { float min = HUGE_VAL; From 77c28f8ba4e4c6695abfa1678b3c2e76ab67c817 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 22 Dec 2023 03:43:05 -0800 Subject: [PATCH 005/206] Back out "Offline IVF powered by faiss big batch search" Summary: Revert so that the test data can be replaced with synthetic Reviewed By: mdouze Differential Revision: D52388604 fbshipit-source-id: c0037635a4e66c54d42400294d13d9a80610b845 --- demos/offline_ivf/README.md | 52 - demos/offline_ivf/__init__.py | 0 demos/offline_ivf/config_ssnpp.yaml | 109 -- .../offline_ivf/create_sharded_ssnpp_files.py | 63 - demos/offline_ivf/dataset.py | 173 --- demos/offline_ivf/generate_config.py | 45 - demos/offline_ivf/offline_ivf.py | 1036 ----------------- demos/offline_ivf/run.py | 218 ---- .../test_data/IVF256_PQ4.empty.faissindex | Bin 16564 -> 0 bytes .../OPQ4_IVF256_PQ4.empty.faissindex | Bin 16891 -> 0 bytes .../test_data/coco_lang/IVF256_PQ4.faissindex | Bin 22856 -> 0 bytes .../coco_lang/IVF256_PQ4.faissindex.ivfdata | Bin 360000 -> 0 bytes .../test_data/coco_lang/IVF256_PQ4.shard_0 | Bin 138612 -> 0 bytes .../test_data/coco_lang/IVF256_PQ4.shard_1 | Bin 138612 -> 0 bytes .../test_data/coco_lang/IVF256_PQ4.shard_2 | Bin 138612 -> 0 bytes .../coco_lang/OPQ4_IVF256_PQ4.faissindex | Bin 23188 -> 0 bytes .../OPQ4_IVF256_PQ4.faissindex.ivfdata | Bin 360000 -> 0 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_0 | Bin 137755 -> 0 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_1 | Bin 137787 -> 0 bytes .../coco_lang/OPQ4_IVF256_PQ4.shard_2 | Bin 137771 -> 0 bytes .../test_data/goku_lang/IVF256_PQ4.faissindex | Bin 22856 -> 0 bytes .../goku_lang/IVF256_PQ4.faissindex.ivfdata | Bin 360000 -> 0 bytes .../test_data/goku_lang/IVF256_PQ4.shard_0 | Bin 138612 -> 0 bytes .../test_data/goku_lang/IVF256_PQ4.shard_1 | Bin 138612 -> 0 bytes .../test_data/goku_lang/IVF256_PQ4.shard_2 | Bin 138612 -> 0 bytes .../goku_lang/OPQ4_IVF256_PQ4.faissindex | Bin 23188 -> 0 bytes .../OPQ4_IVF256_PQ4.faissindex.ivfdata | Bin 360000 -> 0 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_0 | Bin 137771 -> 0 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_1 | Bin 137771 -> 0 bytes .../goku_lang/OPQ4_IVF256_PQ4.shard_2 | Bin 137771 -> 0 bytes demos/offline_ivf/tests/test_iterate_input.py | 132 --- demos/offline_ivf/tests/test_offline_ivf.py | 545 --------- demos/offline_ivf/tests/testing_utils.py | 180 --- demos/offline_ivf/utils.py | 94 -- 34 files changed, 2647 deletions(-) delete mode 100644 demos/offline_ivf/README.md delete mode 100644 demos/offline_ivf/__init__.py delete mode 100644 demos/offline_ivf/config_ssnpp.yaml delete mode 100644 demos/offline_ivf/create_sharded_ssnpp_files.py delete mode 100644 demos/offline_ivf/dataset.py delete mode 100644 demos/offline_ivf/generate_config.py delete mode 100644 demos/offline_ivf/offline_ivf.py delete mode 100644 demos/offline_ivf/run.py delete mode 100644 demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.faissindex.ivfdata delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_0 delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_1 delete mode 100644 demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.shard_2 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_2 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 delete mode 100644 demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 delete mode 100644 demos/offline_ivf/tests/test_iterate_input.py delete mode 100644 demos/offline_ivf/tests/test_offline_ivf.py delete mode 100644 demos/offline_ivf/tests/testing_utils.py delete mode 100644 demos/offline_ivf/utils.py diff --git a/demos/offline_ivf/README.md b/demos/offline_ivf/README.md deleted file mode 100644 index df848ba0ab..0000000000 --- a/demos/offline_ivf/README.md +++ /dev/null @@ -1,52 +0,0 @@ - -# Offline IVF - -This folder contains the code for the offline ivf algorithm powered by faiss big batch search. - -Create a conda env: - -`conda create --name oivf python=3.10` - -`conda activate oivf` - -`conda install -c pytorch/label/nightly -c nvidia faiss-gpu=1.7.4` - -`conda install tqdm` - -`conda install pyyaml` - -`conda install -c conda-forge submitit` - - -## Run book - -1. Optionally shard your dataset (see create_sharded_dataset.py) and create the corresponding yaml file `config_ssnpp.yaml`. You can use `generate_config.py` by specifying the root directory of your dataset and the files with the data shards - -`python generate_config` - -2. Run the train index command - -`python run.py --command train_index --config config_ssnpp.yaml --xb ssnpp_1B` - - -3. Run the index-shard command so it produces sharded indexes, required for the search step - -`python run.py --command index_shard --config config_ssnpp.yaml --xb ssnpp_1B` - - -6. Send jobs to the cluster to run search - -`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --cluster_run --partition ` - - -Remarks about the `search` command: it is assumed that the database vectors are the query vectors when performing the search step. -a. If the query vectors are different than the database vectors, it should be passed in the xq argument -b. A new dataset needs to be prepared (step 1) before passing it to the query vectors argument `–xq` - -`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --xq ` - - -6. We can always run the consistency-check for sanity checks! - -`python run.py --command consistency_check--config config_ssnpp.yaml --xb ssnpp_1B` - diff --git a/demos/offline_ivf/__init__.py b/demos/offline_ivf/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/demos/offline_ivf/config_ssnpp.yaml b/demos/offline_ivf/config_ssnpp.yaml deleted file mode 100644 index 690f0de156..0000000000 --- a/demos/offline_ivf/config_ssnpp.yaml +++ /dev/null @@ -1,109 +0,0 @@ -d: 256 -output: /checkpoint/marialomeli/offline_faiss/ssnpp -index: - prod: - - 'IVF8192,PQ128' - non-prod: - - 'IVF16384,PQ128' - - 'IVF32768,PQ128' -nprobe: - prod: - - 512 - non-prod: - - 256 - - 128 - - 1024 - - 2048 - - 4096 - - 8192 - -k: 50 -index_shard_size: 50000000 -query_batch_size: 50000000 -evaluation_sample: 10000 -training_sample: 1572864 -datasets: - ssnpp_1B: - root: /checkpoint/marialomeli/ssnpp_data - size: 1000000000 - files: - - dtype: uint8 - format: npy - name: ssnpp_0000000000.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000001.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000002.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000003.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000004.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000005.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000006.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000007.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000008.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000009.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000010.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000011.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000012.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000013.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000014.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000015.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000016.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000017.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000018.npy - size: 50000000 - - dtype: uint8 - format: npy - name: ssnpp_0000000019.npy - size: 50000000 diff --git a/demos/offline_ivf/create_sharded_ssnpp_files.py b/demos/offline_ivf/create_sharded_ssnpp_files.py deleted file mode 100644 index 7967fbbbac..0000000000 --- a/demos/offline_ivf/create_sharded_ssnpp_files.py +++ /dev/null @@ -1,63 +0,0 @@ -# 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 numpy as np -import argparse -import os - - -def xbin_mmap(fname, dtype, maxn=-1): - """ - Code from - https://github.com/harsha-simhadri/big-ann-benchmarks/blob/main/benchmark/dataset_io.py#L94 - mmap the competition file format for a given type of items - """ - n, d = map(int, np.fromfile(fname, dtype="uint32", count=2)) - assert os.stat(fname).st_size == 8 + n * d * np.dtype(dtype).itemsize - if maxn > 0: - n = min(n, maxn) - return np.memmap(fname, dtype=dtype, mode="r", offset=8, shape=(n, d)) - - -def main(args: argparse.Namespace): - ssnpp_data = xbin_mmap(fname=args.filepath, dtype="uint8") - num_batches = ssnpp_data.shape[0] // args.data_batch - assert ( - ssnpp_data.shape[0] % args.data_batch == 0 - ), "num of embeddings per file should divide total num of embeddings" - for i in range(num_batches): - xb_batch = ssnpp_data[ - i * args.data_batch : (i + 1) * args.data_batch, : - ] - filename = args.output_dir + f"/ssnpp_{(i):010}.npy" - np.save(filename, xb_batch) - print(f"File {filename} is saved!") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "--data_batch", - dest="data_batch", - type=int, - default=50000000, - help="Number of embeddings per file, should be a divisor of 1B", - ) - parser.add_argument( - "--filepath", - dest="filepath", - type=str, - default="/datasets01/big-ann-challenge-data/FB_ssnpp/FB_ssnpp_database.u8bin", - help="path of 1B ssnpp database vectors' original file", - ) - parser.add_argument( - "--filepath", - dest="output_dir", - type=str, - default="/checkpoint/marialomeli/ssnpp_data", - help="path to put sharded files", - ) - - args = parser.parse_args() - main(args) diff --git a/demos/offline_ivf/dataset.py b/demos/offline_ivf/dataset.py deleted file mode 100644 index bdd96a463c..0000000000 --- a/demos/offline_ivf/dataset.py +++ /dev/null @@ -1,173 +0,0 @@ -# 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 os -import numpy as np -import faiss -from typing import List -import random -import logging -from functools import lru_cache - - -def create_dataset_from_oivf_config(cfg, ds_name): - normalise = cfg["normalise"] if "normalise" in cfg else False - return MultiFileVectorDataset( - cfg["datasets"][ds_name]["root"], - [ - FileDescriptor( - f["name"], f["format"], np.dtype(f["dtype"]), f["size"] - ) - for f in cfg["datasets"][ds_name]["files"] - ], - cfg["d"], - normalise, - cfg["datasets"][ds_name]["size"], - ) - - -@lru_cache(maxsize=100) -def _memmap_vecs( - file_name: str, format: str, dtype: np.dtype, size: int, d: int -) -> np.array: - """ - If the file is in raw format, the file size will - be divisible by the dimensionality and by the size - of the data type. - Otherwise,the file contains a header and we assume - it is of .npy type. It the returns the memmapped file. - """ - - assert os.path.exists(file_name), f"file does not exist {file_name}" - if format == "raw": - fl = os.path.getsize(file_name) - nb = fl // d // dtype.itemsize - assert nb == size, f"{nb} is different than config's {size}" - assert fl == d * dtype.itemsize * nb # no header - return np.memmap(file_name, shape=(nb, d), dtype=dtype, mode="r") - elif format == "npy": - vecs = np.load(file_name, mmap_mode="r") - assert vecs.shape[0] == size, f"size:{size},shape {vecs.shape[0]}" - assert vecs.shape[1] == d - assert vecs.dtype == dtype - return vecs - else: - ValueError("The file cannot be loaded in the current format.") - - -class FileDescriptor: - def __init__(self, name: str, format: str, dtype: np.dtype, size: int): - self.name = name - self.format = format - self.dtype = dtype - self.size = size - - -class MultiFileVectorDataset: - def __init__( - self, - root: str, - file_descriptors: List[FileDescriptor], - d: int, - normalize: bool, - size: int, - ): - assert os.path.exists(root) - self.root = root - self.file_descriptors = file_descriptors - self.d = d - self.normalize = normalize - self.size = size - self.file_offsets = [0] - t = 0 - for f in self.file_descriptors: - xb = _memmap_vecs( - f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d - ) - t += xb.shape[0] - self.file_offsets.append(t) - assert ( - t == self.size - ), "the sum of num of embeddings per file!=total num of embeddings" - - def iterate(self, start: int, batch_size: int, dt: np.dtype): - buffer = np.empty(shape=(batch_size, self.d), dtype=dt) - rem = 0 - for f in self.file_descriptors: - if start >= f.size: - start -= f.size - continue - logging.info(f"processing: {f.name}...") - xb = _memmap_vecs( - f"{self.root}/{f.name}", - f.format, - f.dtype, - f.size, - self.d, - ) - if start > 0: - xb = xb[start:] - start = 0 - req = min(batch_size - rem, xb.shape[0]) - buffer[rem : rem + req] = xb[:req] - rem += req - if rem == batch_size: - if self.normalize: - faiss.normalize_L2(buffer) - yield buffer.copy() - rem = 0 - for i in range(req, xb.shape[0], batch_size): - j = i + batch_size - if j <= xb.shape[0]: - tmp = xb[i:j].astype(dt) - if self.normalize: - faiss.normalize_L2(tmp) - yield tmp - else: - rem = xb.shape[0] - i - buffer[:rem] = xb[i:j] - if rem > 0: - tmp = buffer[:rem] - if self.normalize: - faiss.normalize_L2(tmp) - yield tmp - - def get(self, idx: List[int]): - n = len(idx) - fidx = np.searchsorted(self.file_offsets, idx, "right") - res = np.empty(shape=(len(idx), self.d), dtype=np.float32) - for r, id, fid in zip(range(n), idx, fidx): - assert fid > 0 and fid <= len(self.file_descriptors), f"{fid}" - f = self.file_descriptors[fid - 1] - # deferring normalization until after reading the vec - vecs = _memmap_vecs( - f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d - ) - i = id - self.file_offsets[fid - 1] - assert i >= 0 and i < vecs.shape[0] - res[r, :] = vecs[i] # TODO: find a faster way - if self.normalize: - faiss.normalize_L2(res) - return res - - def sample(self, n, idx_fn, vecs_fn): - if vecs_fn and os.path.exists(vecs_fn): - vecs = np.load(vecs_fn) - assert vecs.shape == (n, self.d) - return vecs - if idx_fn and os.path.exists(idx_fn): - idx = np.load(idx_fn) - assert idx.size == n - else: - idx = np.array(sorted(random.sample(range(self.size), n))) - if idx_fn: - np.save(idx_fn, idx) - vecs = self.get(idx) - if vecs_fn: - np.save(vecs_fn, vecs) - return vecs - - def get_first_n(self, n, dt): - assert n <= self.size - return next(self.iterate(0, n, dt)) diff --git a/demos/offline_ivf/generate_config.py b/demos/offline_ivf/generate_config.py deleted file mode 100644 index b5a12645ab..0000000000 --- a/demos/offline_ivf/generate_config.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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 numpy as np -import os -import yaml - -# with ssnpp sharded data -root = "/checkpoint/marialomeli/ssnpp_data" -file_names = [f"ssnpp_{i:010}.npy" for i in range(20)] -d = 256 -dt = np.dtype(np.uint8) - - -def read_embeddings(fp): - fl = os.path.getsize(fp) - nb = fl // d // dt.itemsize - print(nb) - if fl == d * dt.itemsize * nb: # no header - return ("raw", np.memmap(fp, shape=(nb, d), dtype=dt, mode="r")) - else: # assume npy - vecs = np.load(fp, mmap_mode="r") - assert vecs.shape[1] == d - assert vecs.dtype == dt - return ("npy", vecs) - - -cfg = {} -files = [] -size = 0 -for fn in file_names: - fp = f"{root}/{fn}" - assert os.path.exists(fp), f"{fp} is missing" - ft, xb = read_embeddings(fp) - files.append( - {"name": fn, "size": xb.shape[0], "dtype": dt.name, "format": ft} - ) - size += xb.shape[0] - -cfg["size"] = size -cfg["root"] = root -cfg["d"] = d -cfg["files"] = files -print(yaml.dump(cfg)) diff --git a/demos/offline_ivf/offline_ivf.py b/demos/offline_ivf/offline_ivf.py deleted file mode 100644 index a2babd762e..0000000000 --- a/demos/offline_ivf/offline_ivf.py +++ /dev/null @@ -1,1036 +0,0 @@ -# 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 faiss -import numpy as np -import os -from tqdm import tqdm, trange -import sys -import logging -from faiss.contrib.ondisk import merge_ondisk -from faiss.contrib.big_batch_search import big_batch_search -from faiss.contrib.exhaustive_search import knn_ground_truth -from faiss.contrib.evaluation import knn_intersection_measure -from utils import ( - get_intersection_cardinality_frequencies, - margin, - is_pretransform_index, -) -from dataset import create_dataset_from_oivf_config - -logging.basicConfig( - format=( - "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)-12s %(message)s" - ), - level=logging.INFO, - datefmt="%Y-%m-%d %H:%M:%S", - force=True, -) - -EMBEDDINGS_BATCH_SIZE: int = 100_000 -NUM_SUBSAMPLES: int = 100 -SMALL_DATA_SAMPLE: int = 10000 - - -class OfflineIVF: - def __init__(self, cfg, args, nprobe, index_factory_str): - self.input_d = cfg["d"] - self.dt = cfg["datasets"][args.xb]["files"][0]["dtype"] - assert self.input_d > 0 - output_dir = cfg["output"] - assert os.path.exists(output_dir) - self.index_factory = index_factory_str - assert self.index_factory is not None - self.index_factory_fn = self.index_factory.replace(",", "_") - self.index_template_file = ( - f"{output_dir}/{args.xb}/{self.index_factory_fn}.empty.faissindex" - ) - logging.info(f"index template: {self.index_template_file}") - - if not args.xq: - args.xq = args.xb - - self.by_residual = True - if args.no_residuals: - self.by_residual = False - - xb_output_dir = f"{output_dir}/{args.xb}" - if not os.path.exists(xb_output_dir): - os.makedirs(xb_output_dir) - xq_output_dir = f"{output_dir}/{args.xq}" - if not os.path.exists(xq_output_dir): - os.makedirs(xq_output_dir) - search_output_dir = f"{output_dir}/{args.xq}_in_{args.xb}" - if not os.path.exists(search_output_dir): - os.makedirs(search_output_dir) - self.knn_dir = f"{search_output_dir}/knn" - if not os.path.exists(self.knn_dir): - os.makedirs(self.knn_dir) - self.eval_dir = f"{search_output_dir}/eval" - if not os.path.exists(self.eval_dir): - os.makedirs(self.eval_dir) - self.index = {} # to keep a reference to opened indices, - self.ivls = {} # hstack inverted lists, - self.index_shards = {} # and index shards - self.index_shard_prefix = ( - f"{xb_output_dir}/{self.index_factory_fn}.shard_" - ) - self.xq_index_shard_prefix = ( - f"{xq_output_dir}/{self.index_factory_fn}.shard_" - ) - self.index_file = ( # TODO: added back temporarily for evaluate, handle name of non-sharded index file and remove. - f"{xb_output_dir}/{self.index_factory_fn}.faissindex" - ) - self.xq_index_file = ( - f"{xq_output_dir}/{self.index_factory_fn}.faissindex" - ) - self.training_sample = cfg["training_sample"] - self.evaluation_sample = cfg["evaluation_sample"] - self.xq_ds = create_dataset_from_oivf_config(cfg, args.xq) - self.xb_ds = create_dataset_from_oivf_config(cfg, args.xb) - file_descriptors = self.xq_ds.file_descriptors - self.file_sizes = [fd.size for fd in file_descriptors] - self.shard_size = cfg["index_shard_size"] # ~100GB - self.nshards = self.xb_ds.size // self.shard_size - if self.xb_ds.size % self.shard_size != 0: - self.nshards += 1 - self.xq_nshards = self.xq_ds.size // self.shard_size - if self.xq_ds.size % self.shard_size != 0: - self.xq_nshards += 1 - self.nprobe = nprobe - assert self.nprobe > 0, "Invalid nprobe parameter." - if "deduper" in cfg: - self.deduper = cfg["deduper"] - self.deduper_codec_fn = [ - f"{xb_output_dir}/deduper_codec_{codec.replace(',', '_')}" - for codec in self.deduper - ] - self.deduper_idx_fn = [ - f"{xb_output_dir}/deduper_idx_{codec.replace(',', '_')}" - for codec in self.deduper - ] - else: - self.deduper = None - self.k = cfg["k"] - assert self.k > 0, "Invalid number of neighbours parameter." - self.knn_output_file_suffix = ( - f"{self.index_factory_fn}_np{self.nprobe}.npy" - ) - - fp = 32 - if self.dt == "float16": - fp = 16 - self.postprocess_output_dir = ( - self.knn_dir - + f"/dists5_p5.{args.xb}-{args.xq}.{self.index_factory_fn}.k{self.k}.np{self.nprobe}.fp{fp}-shard" - ) - - self.xq_bs = cfg["query_batch_size"] - if "metric" in cfg: - self.metric = eval(f'faiss.{cfg["metric"]}') - else: - self.metric = faiss.METRIC_L2 - - if "evaluate_by_margin" in cfg: - self.evaluate_by_margin = cfg["evaluate_by_margin"] - else: - self.evaluate_by_margin = False - - os.system("grep -m1 'model name' < /proc/cpuinfo") - os.system("grep -E 'MemTotal|MemFree' /proc/meminfo") - os.system("nvidia-smi") - os.system("nvcc --version") - - self.knn_queries_memory_limit = 4 * 1024 * 1024 * 1024 # 4 GB - self.knn_vectors_memory_limit = 8 * 1024 * 1024 * 1024 # 8 GB - - def input_stats(self): - """ - Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). - """ - xb_sample = self.xb_ds.get_first_n(self.training_sample, np.float32) - logging.info(f"input shape: {xb_sample.shape}") - logging.info("running MatrixStats on training sample...") - logging.info(faiss.MatrixStats(xb_sample).comments) - logging.info("done") - - def dedupe(self): - logging.info(self.deduper) - if self.deduper is None: - logging.info("No deduper configured") - return - codecs = [] - codesets = [] - idxs = [] - for factory, filename in zip(self.deduper, self.deduper_codec_fn): - if os.path.exists(filename): - logging.info(f"loading trained dedupe codec: {filename}") - codec = faiss.read_index(filename) - else: - logging.info(f"training dedupe codec: {factory}") - codec = faiss.index_factory(self.input_d, factory) - xb_sample = np.unique( - self.xb_ds.get_first_n(100_000, np.float32), axis=0 - ) - faiss.ParameterSpace().set_index_parameter(codec, "verbose", 1) - codec.train(xb_sample) - logging.info(f"writing trained dedupe codec: {filename}") - faiss.write_index(codec, filename) - codecs.append(codec) - codesets.append(faiss.CodeSet(codec.sa_code_size())) - idxs.append(np.empty((0,), dtype=np.uint32)) - bs = 1_000_000 - i = 0 - for buffer in tqdm(self.xb_ds.iterate(0, bs, np.float32)): - for j in range(len(codecs)): - codec, codeset, idx = codecs[j], codesets[j], idxs[j] - uniq = codeset.insert(codec.sa_encode(buffer)) - idxs[j] = np.append( - idx, - np.arange(i, i + buffer.shape[0], dtype=np.uint32)[uniq], - ) - i += buffer.shape[0] - for idx, filename in zip(idxs, self.deduper_idx_fn): - logging.info(f"writing {filename}, shape: {idx.shape}") - np.save(filename, idx) - logging.info("done") - - def train_index(self): - """ - Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). - """ - assert not os.path.exists(self.index_template_file), ( - "The train command has been ran, the index template file already" - " exists." - ) - xb_sample = np.unique( - self.xb_ds.get_first_n(self.training_sample, np.float32), axis=0 - ) - logging.info(f"input shape: {xb_sample.shape}") - index = faiss.index_factory( - self.input_d, self.index_factory, self.metric - ) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - index_ivf.by_residual = True - faiss.ParameterSpace().set_index_parameter(index, "verbose", 1) - logging.info("running training...") - index.train(xb_sample) - logging.info(f"writing trained index {self.index_template_file}...") - faiss.write_index(index, self.index_template_file) - logging.info("done") - - def _iterate_transformed(self, ds, start, batch_size, dt): - assert os.path.exists(self.index_template_file) - index = faiss.read_index(self.index_template_file) - if is_pretransform_index(index): - vt = index.chain.at(0) # fetch pretransform - for buffer in ds.iterate(start, batch_size, dt): - yield vt.apply(buffer) - else: - for buffer in ds.iterate(start, batch_size, dt): - yield buffer - - def index_shard_and_quantize(self): - assert os.path.exists(self.index_template_file) - index = faiss.read_index(self.index_template_file) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - assert self.nprobe <= index_ivf.quantizer.ntotal, ( - f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" - f" to retrieve {self.nprobe} neighbours, check." - ) - - if is_pretransform_index(index): - d = index.chain.at(0).d_out - else: - d = self.input_d - for i in range(0, self.nshards): - sfn = f"{self.index_shard_prefix}{i}" - cqfn = f"{self.coarse_quantization_prefix}{i}" # fixme - if os.path.exists(sfn) or os.path.exists(cqfn): - logging.info(f"skipping shard: {i}") - continue - try: - with open(cqfn, "xb") as cqf: - index.reset() - start = i * self.shard_size - j = 0 - quantizer = faiss.index_cpu_to_all_gpus( - index_ivf.quantizer - ) - for xb_j in tqdm( - self._iterate_transformed( - self.xb_ds, - start, - EMBEDDINGS_BATCH_SIZE, - np.float32, - ), - file=sys.stdout, - ): - assert xb_j.shape[1] == d - _, I = quantizer.search(xb_j, self.nprobe) - assert np.amin(I) >= 0, f"{I}" - assert np.amax(I) < index_ivf.nlist - cqf.write(I) - self._index_add_core_wrapper( # fixme - index_ivf, - xb_j, - np.arange(start + j, start + j + xb_j.shape[0]), - I[:, 0], - ) - j += xb_j.shape[0] - assert j <= self.shard_size - if j == self.shard_size: - break - logging.info(f"writing {sfn}...") - faiss.write_index(index, sfn) - except FileExistsError: - logging.info(f"skipping shard: {i}") - continue - logging.info("done") - - def index_shard(self): - assert os.path.exists(self.index_template_file) - index = faiss.read_index(self.index_template_file) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - assert self.nprobe <= index_ivf.quantizer.ntotal, ( - f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" - f" to retrieve {self.nprobe} neighbours, check." - ) - cpu_quantizer = index_ivf.quantizer - gpu_quantizer = faiss.index_cpu_to_all_gpus(cpu_quantizer) - - for i in range(0, self.nshards): - sfn = f"{self.index_shard_prefix}{i}" - try: - index.reset() - index_ivf.quantizer = gpu_quantizer - with open(sfn, "xb"): - start = i * self.shard_size - jj = 0 - embeddings_batch_size = min( - EMBEDDINGS_BATCH_SIZE, self.shard_size - ) - assert ( - self.shard_size % embeddings_batch_size == 0 - or EMBEDDINGS_BATCH_SIZE % embeddings_batch_size == 0 - ), ( - f"the shard size {self.shard_size} and embeddings" - f" shard size {EMBEDDINGS_BATCH_SIZE} are not" - " divisible" - ) - - for xb_j in tqdm( - self._iterate_transformed( - self.xb_ds, - start, - embeddings_batch_size, - np.float32, - ), - file=sys.stdout, - ): - assert xb_j.shape[1] == index.d - index.add_with_ids( - xb_j, - np.arange(start + jj, start + jj + xb_j.shape[0]), - ) - jj += xb_j.shape[0] - logging.info(jj) - assert ( - jj <= self.shard_size - ), f"jj {jj} and shard_zide {self.shard_size}" - if jj == self.shard_size: - break - logging.info(f"writing {sfn}...") - index_ivf.quantizer = cpu_quantizer - faiss.write_index(index, sfn) - except FileExistsError: - logging.info(f"skipping shard: {i}") - continue - logging.info("done") - - def merge_index(self): - ivf_file = f"{self.index_file}.ivfdata" - - assert os.path.exists(self.index_template_file) - assert not os.path.exists( - ivf_file - ), f"file with embeddings data {ivf_file} not found, check." - assert not os.path.exists(self.index_file) - index = faiss.read_index(self.index_template_file) - block_fnames = [ - f"{self.index_shard_prefix}{i}" for i in range(self.nshards) - ] - for fn in block_fnames: - assert os.path.exists(fn) - logging.info(block_fnames) - logging.info("merging...") - merge_ondisk(index, block_fnames, ivf_file) - logging.info("writing index...") - faiss.write_index(index, self.index_file) - logging.info("done") - - def _cached_search( - self, - sample, - xq_ds, - xb_ds, - idx_file, - vecs_file, - I_file, - D_file, - index_file=None, - nprobe=None, - ): - if not os.path.exists(I_file): - assert not os.path.exists(I_file), f"file {I_file} does not exist " - assert not os.path.exists(D_file), f"file {D_file} does not exist " - xq = xq_ds.sample(sample, idx_file, vecs_file) - - if index_file: - D, I = self._index_nonsharded_search(index_file, xq, nprobe) - else: - logging.info("ground truth computations") - db_iterator = xb_ds.iterate(0, 100_000, np.float32) - D, I = knn_ground_truth( - xq, db_iterator, self.k, metric_type=self.metric - ) - assert np.amin(I) >= 0 - - np.save(I_file, I) - np.save(D_file, D) - else: - assert os.path.exists(idx_file), f"file {idx_file} does not exist " - assert os.path.exists( - vecs_file - ), f"file {vecs_file} does not exist " - assert os.path.exists(I_file), f"file {I_file} does not exist " - assert os.path.exists(D_file), f"file {D_file} does not exist " - I = np.load(I_file) - D = np.load(D_file) - assert I.shape == (sample, self.k), f"{I_file} shape mismatch" - assert D.shape == (sample, self.k), f"{D_file} shape mismatch" - return (D, I) - - def _index_search(self, index_shard_prefix, xq, nprobe): - assert nprobe is not None - logging.info(f"open sharded index: {index_shard_prefix}, {self.nshards}") - index = self._open_sharded_index(index_shard_prefix) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - logging.info(f"setting nprobe to {nprobe}") - index_ivf.nprobe = nprobe - return index.search(xq, self.k) - - def _index_nonsharded_search(self, index_file, xq, nprobe): - assert nprobe is not None - logging.info(f"index {index_file}") - assert os.path.exists(index_file), f"file {index_file} does not exist " - index = faiss.read_index(index_file, faiss.IO_FLAG_ONDISK_SAME_DIR) - logging.info(f"index size {index.ntotal} ") - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - logging.info(f"setting nprobe to {nprobe}") - index_ivf.nprobe = nprobe - return index.search(xq, self.k) - - def _refine_distances(self, xq_ds, idx, xb_ds, I): - xq = xq_ds.get(idx).repeat(self.k, axis=0) - xb = xb_ds.get(I.reshape(-1)) - if self.metric == faiss.METRIC_INNER_PRODUCT: - return (xq * xb).sum(axis=1).reshape(I.shape) - elif self.metric == faiss.METRIC_L2: - return ((xq - xb) ** 2).sum(axis=1).reshape(I.shape) - else: - raise ValueError(f"metric not supported {self.metric}") - - def evaluate(self): - self._evaluate( - self.index_factory_fn, - self.index_file, - self.xq_index_file, - self.nprobe, - ) - - def _evaluate(self, index_factory_fn, index_file, xq_index_file, nprobe): - idx_a_file = f"{self.eval_dir}/idx_a.npy" - idx_b_gt_file = f"{self.eval_dir}/idx_b_gt.npy" - idx_b_ann_file = ( - f"{self.eval_dir}/idx_b_ann_{index_factory_fn}_np{nprobe}.npy" - ) - vecs_a_file = f"{self.eval_dir}/vecs_a.npy" - vecs_b_gt_file = f"{self.eval_dir}/vecs_b_gt.npy" - vecs_b_ann_file = ( - f"{self.eval_dir}/vecs_b_ann_{index_factory_fn}_np{nprobe}.npy" - ) - D_a_gt_file = f"{self.eval_dir}/D_a_gt.npy" - D_a_ann_file = ( - f"{self.eval_dir}/D_a_ann_{index_factory_fn}_np{nprobe}.npy" - ) - D_a_ann_refined_file = f"{self.eval_dir}/D_a_ann_refined_{index_factory_fn}_np{nprobe}.npy" - D_b_gt_file = f"{self.eval_dir}/D_b_gt.npy" - D_b_ann_file = ( - f"{self.eval_dir}/D_b_ann_{index_factory_fn}_np{nprobe}.npy" - ) - D_b_ann_gt_file = ( - f"{self.eval_dir}/D_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" - ) - I_a_gt_file = f"{self.eval_dir}/I_a_gt.npy" - I_a_ann_file = ( - f"{self.eval_dir}/I_a_ann_{index_factory_fn}_np{nprobe}.npy" - ) - I_b_gt_file = f"{self.eval_dir}/I_b_gt.npy" - I_b_ann_file = ( - f"{self.eval_dir}/I_b_ann_{index_factory_fn}_np{nprobe}.npy" - ) - I_b_ann_gt_file = ( - f"{self.eval_dir}/I_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" - ) - margin_gt_file = f"{self.eval_dir}/margin_gt.npy" - margin_refined_file = ( - f"{self.eval_dir}/margin_refined_{index_factory_fn}_np{nprobe}.npy" - ) - margin_ann_file = ( - f"{self.eval_dir}/margin_ann_{index_factory_fn}_np{nprobe}.npy" - ) - - logging.info("exact search forward") - # xq -> xb AKA a -> b - D_a_gt, I_a_gt = self._cached_search( - self.evaluation_sample, - self.xq_ds, - self.xb_ds, - idx_a_file, - vecs_a_file, - I_a_gt_file, - D_a_gt_file, - ) - idx_a = np.load(idx_a_file) - - logging.info("approximate search forward") - D_a_ann, I_a_ann = self._cached_search( - self.evaluation_sample, - self.xq_ds, - self.xb_ds, - idx_a_file, - vecs_a_file, - I_a_ann_file, - D_a_ann_file, - index_file, - nprobe, - ) - - logging.info( - "calculate refined distances on approximate search forward" - ) - if os.path.exists(D_a_ann_refined_file): - D_a_ann_refined = np.load(D_a_ann_refined_file) - assert D_a_ann.shape == D_a_ann_refined.shape - else: - D_a_ann_refined = self._refine_distances( - self.xq_ds, idx_a, self.xb_ds, I_a_ann - ) - np.save(D_a_ann_refined_file, D_a_ann_refined) - - if self.evaluate_by_margin: - k_extract = self.k - margin_threshold = 1.05 - logging.info( - "exact search backward from the k_extract NN results of" - " forward search" - ) - # xb -> xq AKA b -> a - D_a_b_gt = D_a_gt[:, :k_extract].ravel() - idx_b_gt = I_a_gt[:, :k_extract].ravel() - assert len(idx_b_gt) == self.evaluation_sample * k_extract - np.save(idx_b_gt_file, idx_b_gt) - # exact search - D_b_gt, _ = self._cached_search( - len(idx_b_gt), - self.xb_ds, - self.xq_ds, - idx_b_gt_file, - vecs_b_gt_file, - I_b_gt_file, - D_b_gt_file, - ) # xb and xq ^^^ are inverted - - logging.info("margin on exact search") - margin_gt = margin( - self.evaluation_sample, - idx_a, - idx_b_gt, - D_a_b_gt, - D_a_gt, - D_b_gt, - self.k, - k_extract, - margin_threshold, - ) - np.save(margin_gt_file, margin_gt) - - logging.info( - "exact search backward from the k_extract NN results of" - " approximate forward search" - ) - D_a_b_refined = D_a_ann_refined[:, :k_extract].ravel() - idx_b_ann = I_a_ann[:, :k_extract].ravel() - assert len(idx_b_ann) == self.evaluation_sample * k_extract - np.save(idx_b_ann_file, idx_b_ann) - # exact search - D_b_ann_gt, _ = self._cached_search( - len(idx_b_ann), - self.xb_ds, - self.xq_ds, - idx_b_ann_file, - vecs_b_ann_file, - I_b_ann_gt_file, - D_b_ann_gt_file, - ) # xb and xq ^^^ are inverted - - logging.info("refined margin on approximate search") - margin_refined = margin( - self.evaluation_sample, - idx_a, - idx_b_ann, - D_a_b_refined, - D_a_gt, # not D_a_ann_refined(!) - D_b_ann_gt, - self.k, - k_extract, - margin_threshold, - ) - np.save(margin_refined_file, margin_refined) - - D_b_ann, I_b_ann = self._cached_search( - len(idx_b_ann), - self.xb_ds, - self.xq_ds, - idx_b_ann_file, - vecs_b_ann_file, - I_b_ann_file, - D_b_ann_file, - xq_index_file, - nprobe, - ) - - D_a_b_ann = D_a_ann[:, :k_extract].ravel() - - logging.info("approximate search margin") - - margin_ann = margin( - self.evaluation_sample, - idx_a, - idx_b_ann, - D_a_b_ann, - D_a_ann, - D_b_ann, - self.k, - k_extract, - margin_threshold, - ) - np.save(margin_ann_file, margin_ann) - - logging.info("intersection") - logging.info(I_a_gt) - logging.info(I_a_ann) - - for i in range(1, self.k + 1): - logging.info( - f"{i}: {knn_intersection_measure(I_a_gt[:,:i], I_a_ann[:,:i])}" - ) - - logging.info(f"mean of gt distances: {D_a_gt.mean()}") - logging.info(f"mean of approx distances: {D_a_ann.mean()}") - logging.info(f"mean of refined distances: {D_a_ann_refined.mean()}") - - logging.info("intersection cardinality frequencies") - logging.info(get_intersection_cardinality_frequencies(I_a_ann, I_a_gt)) - - logging.info("done") - pass - - def _knn_function(self, xq, xb, k, metric, thread_id=None): - try: - return faiss.knn_gpu( - self.all_gpu_resources[thread_id], - xq, - xb, - k, - metric=metric, - device=thread_id, - vectorsMemoryLimit=self.knn_vectors_memory_limit, - queriesMemoryLimit=self.knn_queries_memory_limit, - ) - except Exception: - logging.info(f"knn_function failed: {xq.shape}, {xb.shape}") - raise - - def _coarse_quantize(self, index_ivf, xq, nprobe): - assert nprobe <= index_ivf.quantizer.ntotal - quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) - bs = 100_000 - nq = len(xq) - q_assign = np.empty((nq, nprobe), dtype="int32") - for i0 in trange(0, nq, bs): - i1 = min(nq, i0 + bs) - _, q_assign_i = quantizer.search(xq[i0:i1], nprobe) - q_assign[i0:i1] = q_assign_i - return q_assign - - def search(self): - logging.info(f"search: {self.knn_dir}") - slurm_job_id = os.environ.get("SLURM_JOB_ID") - - ngpu = faiss.get_num_gpus() - logging.info(f"number of gpus: {ngpu}") - self.all_gpu_resources = [ - faiss.StandardGpuResources() for _ in range(ngpu) - ] - self._knn_function( - np.zeros((10, 10), dtype=np.float16), - np.zeros((10, 10), dtype=np.float16), - self.k, - metric=self.metric, - thread_id=0, - ) - - index = self._open_sharded_index() - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - logging.info(f"setting nprobe to {self.nprobe}") - index_ivf.nprobe = self.nprobe - # quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) - for i in range(0, self.xq_ds.size, self.xq_bs): - Ifn = f"{self.knn_dir}/I{(i):010}_{self.knn_output_file_suffix}" - Dfn = f"{self.knn_dir}/D_approx{(i):010}_{self.knn_output_file_suffix}" - CPfn = f"{self.knn_dir}/CP{(i):010}_{self.knn_output_file_suffix}" - - if slurm_job_id: - worker_record = ( - self.knn_dir - + f"/record_{(i):010}_{self.knn_output_file_suffix}.txt" - ) - if not os.path.exists(worker_record): - logging.info( - f"creating record file {worker_record} and saving job" - f" id: {slurm_job_id}" - ) - with open(worker_record, "w") as h: - h.write(slurm_job_id) - else: - old_slurm_id = open(worker_record, "r").read() - logging.info( - f"old job slurm id {old_slurm_id} and current job id:" - f" {slurm_job_id}" - ) - if old_slurm_id == slurm_job_id: - if os.path.getsize(Ifn) == 0: - logging.info( - f"cleaning up zero length files {Ifn} and" - f" {Dfn}" - ) - os.remove(Ifn) - os.remove(Dfn) - - try: # TODO: modify shape for pretransform case - with open(Ifn, "xb") as f, open(Dfn, "xb") as g: - xq_i = np.empty( - shape=(self.xq_bs, self.input_d), dtype=np.float16 - ) - q_assign = np.empty( - (self.xq_bs, self.nprobe), dtype=np.int32 - ) - j = 0 - quantizer = faiss.index_cpu_to_all_gpus( - index_ivf.quantizer - ) - for xq_i_j in tqdm( - self._iterate_transformed( - self.xq_ds, i, min(100_000, self.xq_bs), np.float16 - ), - file=sys.stdout, - ): - xq_i[j:j + xq_i_j.shape[0]] = xq_i_j - ( - _, - q_assign[j:j + xq_i_j.shape[0]], - ) = quantizer.search(xq_i_j, self.nprobe) - j += xq_i_j.shape[0] - assert j <= xq_i.shape[0] - if j == xq_i.shape[0]: - break - xq_i = xq_i[:j] - q_assign = q_assign[:j] - - assert q_assign.shape == (xq_i.shape[0], index_ivf.nprobe) - del quantizer - logging.info(f"computing: {Ifn}") - logging.info(f"computing: {Dfn}") - prefetch_threads = faiss.get_num_gpus() - D_ann, I = big_batch_search( - index_ivf, - xq_i, - self.k, - verbose=10, - method="knn_function", - knn=self._knn_function, - threaded=faiss.get_num_gpus() * 8, - use_float16=True, - prefetch_threads=prefetch_threads, - computation_threads=faiss.get_num_gpus(), - q_assign=q_assign, - checkpoint=CPfn, - checkpoint_freq=7200, # in seconds - ) - assert ( - np.amin(I) >= 0 - ), f"{I}, there exists negative indices, check" - logging.info(f"saving: {Ifn}") - np.save(f, I) - logging.info(f"saving: {Dfn}") - np.save(g, D_ann) - - if os.path.exists(CPfn): - logging.info(f"removing: {CPfn}") - os.remove(CPfn) - - except FileExistsError: - logging.info(f"skipping {Ifn}, already exists") - logging.info(f"skipping {Dfn}, already exists") - continue - - def _open_index_shard(self, fn): - if fn in self.index_shards: - index_shard = self.index_shards[fn] - else: - logging.info(f"open index shard: {fn}") - index_shard = faiss.read_index( - fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY - ) - self.index_shards[fn] = index_shard - return index_shard - - def _open_sharded_index(self, index_shard_prefix=None): - if index_shard_prefix is None: - index_shard_prefix = self.index_shard_prefix - if index_shard_prefix in self.index: - return self.index[index_shard_prefix] - assert os.path.exists( - self.index_template_file - ), f"file {self.index_template_file} does not exist " - logging.info(f"open index template: {self.index_template_file}") - index = faiss.read_index(self.index_template_file) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - ilv = faiss.InvertedListsPtrVector() - for i in range(self.nshards): - fn = f"{index_shard_prefix}{i}" - assert os.path.exists(fn), f"file {fn} does not exist " - logging.info(fn) - index_shard = self._open_index_shard(fn) - il = faiss.downcast_index( - faiss.extract_index_ivf(index_shard) - ).invlists - ilv.push_back(il) - hsil = faiss.HStackInvertedLists(ilv.size(), ilv.data()) - index_ivf.replace_invlists(hsil, False) - self.ivls[index_shard_prefix] = hsil - self.index[index_shard_prefix] = index - return index - - def index_shard_stats(self): - for i in range(self.nshards): - fn = f"{self.index_shard_prefix}{i}" - assert os.path.exists(fn) - index = faiss.read_index( - fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY - ) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - il = index_ivf.invlists - il.print_stats() - - def index_stats(self): - index = self._open_sharded_index() - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - il = index_ivf.invlists - list_sizes = [il.list_size(i) for i in range(il.nlist)] - logging.info(np.max(list_sizes)) - logging.info(np.mean(list_sizes)) - logging.info(np.argmax(list_sizes)) - logging.info("index_stats:") - il.print_stats() - - def consistency_check(self): - logging.info("consistency-check") - - logging.info("index template...") - - assert os.path.exists(self.index_template_file) - index = faiss.read_index(self.index_template_file) - - offset = 0 # 2**24 - assert self.shard_size > offset + SMALL_DATA_SAMPLE - - logging.info("index shards...") - for i in range(self.nshards): - r = i * self.shard_size + offset - xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) - fn = f"{self.index_shard_prefix}{i}" - assert os.path.exists(fn), f"There is no index shard file {fn}" - index = self._open_index_shard(fn) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - index_ivf.nprobe = 1 - _, I = index.search(xb, 100) - for j in range(SMALL_DATA_SAMPLE): - assert np.where(I[j] == j + r)[0].size > 0, ( - f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" - f" {self.shard_size}" - ) - - logging.info("merged index...") - index = self._open_sharded_index() - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - index_ivf.nprobe = 1 - for i in range(self.nshards): - r = i * self.shard_size + offset - xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) - _, I = index.search(xb, 100) - for j in range(SMALL_DATA_SAMPLE): - assert np.where(I[j] == j + r)[0].size > 0, ( - f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" - f" {self.shard_size}" - ) - - logging.info("search results...") - index_ivf.nprobe = self.nprobe - for i in range(0, self.xq_ds.size, self.xq_bs): - Ifn = f"{self.knn_dir}/I{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" - assert os.path.exists(Ifn) - assert os.path.getsize(Ifn) > 0, f"The file {Ifn} is empty." - logging.info(Ifn) - I = np.load(Ifn, mmap_mode="r") - - assert I.shape[1] == self.k - assert I.shape[0] == min(self.xq_bs, self.xq_ds.size - i) - assert np.all(I[:, 1] >= 0) - - Dfn = f"{self.knn_dir}/D_approx{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" - assert os.path.exists(Dfn) - assert os.path.getsize(Dfn) > 0, f"The file {Dfn} is empty." - logging.info(Dfn) - D = np.load(Dfn, mmap_mode="r") - assert D.shape == I.shape - - xq = next(self.xq_ds.iterate(i, SMALL_DATA_SAMPLE, np.float32)) - D_online, I_online = index.search(xq, self.k) - assert ( - np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size - / (self.k * SMALL_DATA_SAMPLE) - > 0.95 - ), ( - "the ratio is" - f" {np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size / (self.k * SMALL_DATA_SAMPLE)}" - ) - assert np.allclose( - D[:SMALL_DATA_SAMPLE].sum(axis=1), - D_online.sum(axis=1), - rtol=0.01, - ), ( - "the difference is" - f" {D[:SMALL_DATA_SAMPLE].sum(axis=1), D_online.sum(axis=1)}" - ) - - logging.info("done") - - def split_files(self): - self._split_files(file_type="I", save_output_id="idx") - self._split_files(file_type="D_approx", save_output_id="dist") - - def _split_files(self, file_type: str, save_output_id: str): - """ - #Output in directory dists5_p5.eng0-hin.OPQ64,IVFauto,PQ64.k16.np128.fp16-shard - This method handles the post-processing of npy files to have the same number and size - as the number of files in a given dataset. - The assumption about the input files are all of size xq_bs except possible for the last one, that can be shorter. - """ - - logging.info( - f"split_npy_files, output dir in {self.postprocess_output_dir}" - ) - if not os.path.exists(self.postprocess_output_dir): - os.makedirs(self.postprocess_output_dir) - - I_files = sorted(self._get_output_files(file_type)) - - num_input_files = len(I_files) - total_output_size = sum(self.file_sizes) - last_input_file = np.load(I_files[-1], mmap_mode="r") - I_dtype = last_input_file.dtype - remainder = total_output_size - (num_input_files - 1) * self.xq_bs - assert ( - last_input_file.shape[0] == remainder - and last_input_file.shape[1] == self.k - ), f"wrong size for input data file, check file: {I_files[-1]}" - for i in range( - num_input_files - 1 - ): # check all files except the last one, which is checked above - I_matrix = np.load(I_files[i], mmap_mode="r") - assert ( - I_matrix.shape[0] == self.xq_bs and I_matrix.shape[1] == self.k - ), f"wrong size for input data file , check file: {I_files[i]} " - - output_files = [] - - current_input_file_index = 0 - current_input_file_offset = 0 - for jj, current_output_file_size in enumerate(self.file_sizes): - output_file = np.empty((0, self.k), dtype=I_dtype) - while output_file.shape[0] < current_output_file_size: - still_need = current_output_file_size - output_file.shape[0] - I_current_file = np.load( - I_files[current_input_file_index], mmap_mode="r" - ) - max_we_can_read_from_current_input = min( - I_current_file.shape[0], - current_input_file_offset + still_need, - ) - input_chunk = I_current_file[ - current_input_file_offset:max_we_can_read_from_current_input, - ] - output_file = np.vstack([output_file, input_chunk]) - current_input_file_offset = max_we_can_read_from_current_input - if current_input_file_offset == I_current_file.shape[0]: - current_input_file_index += 1 - current_input_file_offset = 0 - output_files.append(output_file) - logging.info( - f"saving files: mm5_p5.x2y.{(jj):03}.{save_output_id}" - ) - np.save( - f"{self.postprocess_output_dir}" - + f"/mm5_p5.x2y.{(jj):03}.{save_output_id}", - output_file, - ) - - def cast_to_uint32(self): - self._cast_to_unint32(file_type="I") - - def _cast_to_unint32(self, file_type: str): - logging.info("casting to uint32:") - I_files = self._get_output_files(file_type) - for I_file in I_files: - I_matrix = np.load(I_file, mmap_mode="r") - assert ( - np.all(I_matrix) >= 0 - and np.all(I_matrix) < np.iinfo(np.uint32).max - ), ( - "Some indices are less than zero or exceed" - f" {np.iinfo(np.uint32).max}, canno cast to uint32" - ) - - filename = I_file.rsplit(".", 1)[0] - np.save(filename + "_uint32.npy", I_matrix.astype(np.uint32)) - logging.info("done! casting to uint32") - - def _get_output_files(self, file_type): - return [ - f"{self.knn_dir}/{file_type}{(i):010}_{self.knn_output_file_suffix}" - for i in range(0, self.xq_ds.size, self.xq_bs) - ] diff --git a/demos/offline_ivf/run.py b/demos/offline_ivf/run.py deleted file mode 100644 index dfa831d6f0..0000000000 --- a/demos/offline_ivf/run.py +++ /dev/null @@ -1,218 +0,0 @@ -# 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 -from utils import ( - load_config, - add_group_args, -) -from offline_ivf import OfflineIVF -import faiss -from typing import List, Callable, Dict -import submitit - - -def join_lists_in_dict(poss: List[str]) -> List[str]: - """ - Joins two lists of prod and non-prod values, checking if the prod value is already included. - If there is no non-prod list, it returns the prod list. - """ - if "non-prod" in poss.keys(): - all_poss = poss["non-prod"] - if poss["prod"][-1] not in poss["non-prod"]: - all_poss += poss["prod"] - return all_poss - else: - return poss["prod"] - - -def main( - args: argparse.Namespace, - cfg: Dict[str, str], - nprobe: int, - index_factory_str: str, -) -> None: - oivf = OfflineIVF(cfg, args, nprobe, index_factory_str) - eval(f"oivf.{args.command}()") - - -def process_options_and_run_jobs(args: argparse.Namespace) -> None: - """ - If "--cluster_run", it launches an array of jobs to the cluster using the submitit library for all the index strings. In - the case of evaluate, it launches a job for each index string and nprobe pair. Otherwise, it launches a single job - that is ran locally with the prod values for index string and nprobe. - """ - - cfg = load_config(args.config) - index_strings = cfg["index"] - nprobes = cfg["nprobe"] - if args.command == "evaluate": - if args.cluster_run: - all_nprobes = join_lists_in_dict(nprobes) - all_index_strings = join_lists_in_dict(index_strings) - for index_factory_str in all_index_strings: - for nprobe in all_nprobes: - launch_job(main, args, cfg, nprobe, index_factory_str) - else: - launch_job( - main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] - ) - else: - if args.cluster_run: - all_index_strings = join_lists_in_dict(index_strings) - for index_factory_str in all_index_strings: - launch_job( - main, args, cfg, nprobes["prod"][-1], index_factory_str - ) - else: - launch_job( - main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] - ) - - -def launch_job( - func: Callable, - args: argparse.Namespace, - cfg: Dict[str, str], - n_probe: int, - index_str: str, -) -> None: - """ - Launches an array of slurm jobs to the cluster using the submitit library. - """ - - if args.cluster_run: - assert args.num_nodes >= 1 - executor = submitit.AutoExecutor(folder=args.logs_dir) - - executor.update_parameters( - nodes=args.num_nodes, - gpus_per_node=args.gpus_per_node, - cpus_per_task=args.cpus_per_task, - tasks_per_node=args.tasks_per_node, - name=args.job_name, - slurm_partition=args.partition, - slurm_time=70 * 60, - ) - if args.slurm_constraint: - executor.update_parameters(slurm_constraint=args.slurm_constrain) - - job = executor.submit(func, args, cfg, n_probe, index_str) - print(f"Job id: {job.job_id}") - else: - func(args, cfg, n_probe, index_str) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - group = parser.add_argument_group("general") - - add_group_args(group, "--command", required=True, help="command to run") - add_group_args( - group, - "--config", - required=True, - help="config yaml with the dataset specs", - ) - add_group_args( - group, "--nt", type=int, default=96, help="nb search threads" - ) - add_group_args( - group, - "--no_residuals", - action="store_false", - help="set index.by_residual to False during train index.", - ) - - group = parser.add_argument_group("slurm_job") - - add_group_args( - group, - "--cluster_run", - action="store_true", - help=" if True, runs in cluster", - ) - add_group_args( - group, - "--job_name", - type=str, - default="oivf", - help="cluster job name", - ) - add_group_args( - group, - "--num_nodes", - type=str, - default=1, - help="num of nodes per job", - ) - add_group_args( - group, - "--tasks_per_node", - type=int, - default=1, - help="tasks per job", - ) - - add_group_args( - group, - "--gpus_per_node", - type=int, - default=8, - help="cluster job name", - ) - add_group_args( - group, - "--cpus_per_task", - type=int, - default=80, - help="cluster job name", - ) - - add_group_args( - group, - "--logs_dir", - type=str, - default="/checkpoint/marialomeli/offline_faiss/logs", - help="cluster job name", - ) - - add_group_args( - group, - "--slurm_constraint", - type=str, - default=None, - help="can be volta32gb for the fair cluster", - ) - - add_group_args( - group, - "--partition", - type=str, - default="learnlab", - help="specify which partition to use if ran on cluster with job arrays", - choices=[ - "learnfair", - "devlab", - "scavenge", - "learnlab", - "nllb", - "seamless", - "seamless_medium", - "learnaccel", - "onellm_low", - "learn", - "scavenge", - ], - ) - - group = parser.add_argument_group("dataset") - - add_group_args(group, "--xb", required=True, help="database vectors") - add_group_args(group, "--xq", help="query vectors") - - args = parser.parse_args() - print("args:", args) - faiss.omp_set_num_threads(args.nt) - process_options_and_run_jobs(args=args) diff --git a/demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex b/demos/offline_ivf/tests/test_data/IVF256_PQ4.empty.faissindex deleted file mode 100644 index 9cd6a19c26bff31a24ce9430e5492069cc961eba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16564 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%0AF73lUzgB0$dPaR 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 U^FRM`;D0g#x!F0n|C1#6UvuR9-~a#s diff --git a/demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex b/demos/offline_ivf/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex deleted file mode 100644 index 56b70276f838658f80268eb758ea74abc4d0fef0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16891 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 UG_1|xq{1^qmtyd(N>l%Zb9ab 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

6ZG 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 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_0 deleted file mode 100644 index 5f2f4ba5a3a60b404c37001cbd8e21fa9e8fe719..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138612 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

M$6=T^F!78pyQ`?iY-^jf1ktH3#mP1Ga-#ao2QE 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 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 deleted file mode 100644 index f229716ab9d41f2f67fc5bc95d2f0ea1f8b45253..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138612 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 A`(e5eujTw%~pVWkYJFa2F@DK0} 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 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 deleted file mode 100644 index 28aabd44c7fc0cb2a1a506305acde7a19b257b48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138612 zcmZU*bzE0X^9BqkC?O%CA|;^$N;ltgU37O!3bulPfl?}pVt0ay-F@34wxAebcZ)6R zjh*j#evjwC#Ts>{Pll7n*SdvFaMw7|NZ)Z ziCl0&fWv<}N%dm)|CGd^|I+_<`o9)(a&`)2yyZaH>I5=$n=$VHR%B2>4=S%t=gVj{ zYJK--!>$nK-f-mi+-w-DZGqxvFB*Czvy<^kTrr4b_F^mU$@FGpvoXfLEkoB|jtJT7 z!tJlYYv(+eIz5i-QeUg)6q4>=(j}HpeioF@ck> zMl$n^E`^gZIBsCeS(_~py)zxZeg$Gy4=egyievq%;b2lfg!U;#%iIKNotuXb2kkL_ z=q)Ua8iGmTR@_}R7N?HPf%0Krw(OaSEw@uy7#Pn=+evVajpX^*N<6TR!jrR8k>0;Q zUZfp{-l_5U)ykTRw_ak|f(XhZmWnE+(47}S)eR1qJhKAM(SFd_o`(59OR=fOnRAL{ z*ep-p`WnXNt≫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 z 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 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex b/demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex deleted file mode 100644 index 582159767d472205c57fbb311e0c176816dcb1c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23188 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%0DOio^_klJw}YY;T! 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 hOZ>yMg6^ar(+oW1ww^VtjIJ-mf^czC3AxNraS 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ɒ)BSDltUTyg$I@z8tk)Q_~ruj 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 cb(n+oW1ww^VtjIJ-mf^czC3AxNraS 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 YUY~cTyS_L_I2H(|>(~Cy`Z!+yKdP(-Qvd(} diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata deleted file mode 100644 index 4726d998866def3afe805d17fa3bec4252c8e68c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360000 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 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_1 deleted file mode 100644 index 73ddb25147a9759a5405221e0d09d097db6b3eb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138612 zcmZU*Wmp#97d8qgC?O%GNC}7nN;l8kH{G3*f~_cEpp=TD*qxwacXwh7iUD@F*o~cM z{_o42>pH)~2NrwJj#abwsv%@#bWCeGIXTVF;;;Ynqxt`V^78*{{-0m}FOUl<2z314 zB&lDV{=b&^^MB$0o%DZ3$jR9&kO@}(V5bwruq`II|5uU0fnBM*GJ`K;)Ts3{fb}~< znR~;DKXV7cL~Rokzk1WiGllIB}}ROR;v(VO+Rk$BF)-%xrZGV;T}U@oE&a&gfD& z8H?kFcAT-%3NhO=@aInuW^}ct@1=Owtr!X>_eNOHQZ&s@q}I7P_;|npV+Y^D{OEz0 z5Mj+-Rikn0$Sf!y_G8oT>DY8TjfFu8thAc|m$)dNkE_H3n`k^aI~f^$`rt+SVd$M2 zi$5)FsCeromduN!JmRRRQVQKUkyKshh>6oH;1c5xjjidJ`@0kys$Dp%NQRB_tTPQf=8KwH%`aJC;>WhTGj>JnhvI{f$&PuFj7t|7Ii9L6O@%HThsv zJOm!`SME1Aau!gyQb;_|)E+DXDE(xIc_tlUVbqx!fWPx*A;{31IvX7^__RF_ zzMX}=8Veu<2Ey-cCS3dK&@rbNJ-Z~aO?)n<+>fL}_jRzJeG_qo2~>XP%T2bku;82r z0#{GN=Aa-NbX$bzX8|lMiQ|Y41fDFc)#}GI9XR_Ba%Hn8uGxDY>cgn z;Dy8}CdN$0%b+;U{#}7}6NCBuxED?hZ9?n^Yi#n%L8*Z<_otcR-s%({H%!JWrLK(o z&>ejicrf!(7o6_45+eef_;}eT)Se6FC_8O7PVCARy=1&NCYm0WO1vPOfX|O=P%cX+ z?!>a6hQLu?$Dr6Xltx|wR80+M@xId-GrJf5jX#QtQ9;b~z6-Oa6vQv}=jz37(7$cQ zu*J(UE1b0Zlfsc&0W2FI2B)xG#Agk~P@`bJJ08fKFLTkd!iKvC`!c}D5i46*GGJ5z zhE9<&ct`^}-U#LoAsx^1W%NGRpW7_MsG*%iEf0H|{Elbj%&{1z>dnU`18^;RIRdqf z=~^@f^Nk}J8~+8?6`~Gq)x+2FUbHQ7;HmLmoShxU(5U{fwpfUgVNRG{pMh~6Ip|&J zLZ5~htc_H|sP~cVy!#+4Cgr1kM+nzeccQat7x=D;W2lb-vI66< zE4CO1|3y$u@eceoT9#si+CP(3w~w%Xrey*7dCdH}vkQS`pzjXj%&BWT}F z*iDS!tg+*qJk{1=Dt^))a!_zEu{`f%Zv57-f-MM0}8d_%1<;BO2K8iQz~*ax>RW@5?| zKU(fMg3e8jJmMY4=xb3_+2@7G;t-y>R0I=cAKb1|V_|(P8x~H(ZY@Jvxj5s*HeV*6 zcc$8oMR4*Ti@NhZG|`-ckg#BW-W5ngIq?0OAm$Gy%~gGI;Z%Fd<|a|TYXpsQj>6>I zTWoyj%FI1sbiM@o%v_Ht!?N+=cO>8ToQqDdXMJQi-&=(6dulXSx~F2_wP@aar^(w( z<#@?8g09L*oZdf%PMf_L|InM+dsFyQeIss^PQ=bSN2<95)4?d2M}LOl`YcO$b`Rx) zK^ctMCC@qgLs)rj6bg^r$Jh36(5;g@51$XmFD)Bxj*!v$!6a-MI}|a81RM~eU@@c% zH;xV9(0wEDUEYsr>n)LM0p_kZ=AHpLSW}V*w%H2xR-w$Q3!-sNCls{Ug&~!GaI8yb z!=*UfJ01Kk0ij%~%CX#Pi0uZ3xrGN3;L=Sj_kn2kk$d*rq-QoksmZ$J$*O)u6~lugmc` zVH_SrhtfCIg15g0!9jBsrtc5nDZ@aNoScmD1LOE&dnas_IWj^a5w<`4==p2{p51pq za^LQ7pY2EYu2XP$k~rs9Fl%1PILoOVX`T`I?j6khx^Z~-GlDXc049unj@T(d{HvFU z@g93&Hm);AB=n^6tJWB@(24zbd2;^8O$a=a$|ox;@me{aGnU5FAteM#E820$@-R$& z8O9#_@8Y?lIp=T@dWmOTvTrc^9tpxHUq`0crs3$68Cawf#%0Sh8MJFJ_LxO+@X&S0 z2uNi~k`DuxC1JguC)Y+s@_7AL+#PPtiA&uXPYJA8Z-!-iZea7f?$ip2;h+hZvG|oCi&rM|ZP!4yR4+jAH34?5 zRzvyo66_1?$j3V#qvxAoo>xldhrdA-^t|!QNtD^w2sXGBqHg48VdXh@ZoCPsxjY{S z3fJO!DNwR%7Pc;r=EE&=n0?iX${T_i|Div=>J3Ikt^pF&jak=TjYIBlN2k}`946}4 zgMs1PIU#~$D?x<=197%TGAcjX&^4$hlVT>o^rso`4hZ2UotH4^kPUMKqO4OeZ%=rP z^=daUaaSmx6!pQzqk&BF7wsz>`Dn}E( zLt|ZMo{j0sZ9l%l`*|uS$ptZ~=_XRn_QH%MTFf=@cgdG;bw1<1e*{Nby@HZ@2uh-((EVdO>MB~pXLuB6YW~Kq zO>I!UI}~Q?jghHhMBCa=SpUeLZ^vZPz}_B-EA8o#bQ<4U>d`gS4IR?jar@cL$W|MJ zCD|*n$w8HcosT1Nj(|vQ59~WL5w}7dVV*My3S$y+$KQkXA(OCGe;_g+`Qo?9RHSzC z;GLuym{BnVzQa8^aOf7OcJ9f=?%^D_-xzVP&3K_}Bz)el!}-tvZj19~#)LSY9|JVy zyCL?$As9TGiN>27q5sT_K1x7@l05YceRx671b2VC;dSK|baGjO^POkl#d|XAUocN? z?8e1UB3P-Uf!KjQ7~pXbC6!}gJv)ZyRT3~uIR|a$hC#VX8zqOPBj`$ZYM!v;`IGw0 z%*e)oan+a_29TbVEUKOxhYR00mQSAFZm`lEkHd1jYU5^H1 zmgs9NaE}GM&qIV+7uwAHi;8`Tbjj_`&#E50HrtgKx5x0zuxYq_c^FjkMq{z{Da@_5 z%bv~+N`Qn1tCnjab!G5eOr)r0Bxvr?U zpS_rQ)Dchb1<+wo8;%&5g^*n>5IJcC)V#}(9o+{zwaGK5dcf}`(KJHFu11k;*s%sj zFBf3o-EiJqXwMaQMj>f$7&i_fuf3fCjBw$zvU2R|Jq4>ycSY_X3uvlZam`%u-u4gX zmDN77+NT_e7fwO3tebe(Xd^ztpK9X_Ir{5x zEI#)G{iA-vT9}4fB{$4FcLHBDH{x5rU&7TtF7&TjiIVdPFuoYgexX{N*Ek5n&rQNn z!@hj{z=vPI)WEzjkiS}rwzh)~5+b}A;5r>&w)@cgd{>mT5a5^;&P`<@v@bDcX-hLs zEskW|!9X6IpTyECJE}hMql57R)J{KvOFN9b>|Ht6)0*x`DAXl+f$AjJl%#d2sD6lxA)RuG;dtXlwa=ZH$rw51D092$yC;cQ%nCErR=)5CxqIR!x%TBF#_mCv&ixO7$`tta|XCJVqkvk)rXUxK%n zyjhnR!=SP0%y~2pJ`)b2hcU3qL=!njR>Q?>IR=UEgwaxGbWitYbvJYNSXGW??cT%N z{x{ranDV%$6(-saK#$3yjrY%kWs5@Crfo1|_eIfbh(EW8e#(Z}U07%m&bl#TY~rT} zZ+A`L>DVq@JD~!1(lh8=mWpd?WU09`>SmK~H~Dk^y(IcaoQKu36&SWI7&~8!@9V_^ zM7K)Aw@H!w_bQBMqua96QZ1gM1ueS<^W#UtJJyaT`rLt4>m;u4lg>Axh% zMEl1R(LDqBVc$&T&$7jW;rZyQ=*N-mBf0d66FaP5jEELyJhD;`TQ{Zi+u(G(_$u(@ zB45sVsmMVid*ZgJ&taD*!1%VnWsXjqJ|Tf+(OqcW+Y711K?rtSiUTzfyubG}me%^R zi)}1yyL#ium3&l-HpaATp46 zT%L?aXWR1E+U_*ck7U2r9!OsyV@+TZZ~b0|&tK=@&~UKjk3jaU4d$wgb})W29)9~0 z;S&MJrMM;yHTUQ$TgnK7@Wh1gqz{2sQ{}Xshp@L|7_*=3g>^#%@)pMO$m?WQylcs^-^Ss%T0V50#n_309W{={Q)x;!+OC|B zko;gM^wh$OE-O$oQ5QKIzM<@W3Rcbt;URy~e=rDSUcc|iGqaN@+&^W8ISv8L`mh6oFDlXehym}kjpDo8QN)c3{Q2xp!(rXI_nrq|T_9^CJ&`vy z2kzsR!!tF4<@3e3XTLBiY|MsXr+oC9Q;6H2-KjG#4$m!tyd$Mh{^G}zO%CvT{R8)% z=OE7QEoQ66bM)P1$h+^z3oT?^cDN(|cW;f}r2>t688ohpr@H(vxclfc(L59Bt=w5Q zW(dBu^}z)#75e6e^W)}D9O=~-y%u=$*kxlXILdLM7LX$n=uw@CHuuhBUqmz_mSo`B zqG)=H&qgY5!5FOuyt%dws(Xx3S7(lzE^>T7#R>O+0yR!!OP65{B_!fcdvvpV2ya5-%?^!tA(iF zXMxg~_H3}#g*GnZ;GJmXF7A)p_twMYiypsiS7W!K0o=u`U?Qt_NAQnLC)VeM@xDg~c6mAs z(`xn5bUh2LY@--z*At8Hk45GVBX%|RWacv&f+mJDa)Q7c!66)!mxdEP^muPq8B9&X z837L_{!pfIi<3w&*2QPhmNf1o#wW)|q4a<;i*7E&PcJJ}Wp$@})(ZU6oQob~y{J^` z$1Yp;;nlKmWQT|I>ELBJ70?$$yH7=eeIlp8_uq@SKI}3K@%ExIp9F5(q~3(OwPc`P2h@ zel5rEU57EI)`wLO=iwI)V#>G(&PzCnTT7D}t~d_sb$4R_vvIh*r8A$LUxc)k&(Z5f z9CL3gQT?kN|5@tsUD0#sn)T&Hy$+Z%wgLBkf@!ap!C;goo2p{b*>e^0K1Ad2@m9Pu zRJ6@a!6mP4&~LReiVIY@ww-{qgd}d7_Zh#Zg>%Bweb{xx0N1}ep>x0eC@*cx^-(VP zs2T#(%tpAhQs>>PAF;zV3tOJGU{+5>S{TT9VvvaYniM=c+L>>aM`Ob!F`l7og-Mqt zihkEljBFjliX3Y$y_bSz39s?=dl)Z#o`+V~roe7ZH>Q-Vh3}$Mc)QaFj>AP7cctM% zKVM!y+@0%2Y)1=gA4V>m4(&Bdp|%oya}8vnhj6H%8z!}Ke;b*VZegf<3AEWaAZyr+B7Le7K@qi^7{ zGryI?y1O<;JcDs4CcQKt&g+S`bO4n)y^uLT^$`>C;7iCK@tyh0Z-E-m`z zy?#wV$8-Ueek-xLdMs8{q@a6>FCY0QGVrVmt3H{bde>a&))m0PSzrg9eHc5x7&-P#=JYyV|h6hm3*h`(UyIJ3v)Wc+P445vzcxO|}pC;Sla`7B`5a9cVVJ8-m^1Gwd4 zNB8!zTq*PB6ETlitmV%K6K106ksqCRII`y-wpxClE9mXz0hVEjZQH-ORh;hp3 zb67Rj37x_{VCNr1Khf`fJl2WHeY9~>rz0bu{YC2~Z8_J$m}gUlqj0DZ-Ui*m(6jGw ztty`0Eu)YzCx+v~v!S%(Byv1&;7oV%&MA0_FMaG${lF1BTic+n$&d3KEb#A{FQ=QX zL$!kzOMBRGpSLdKPo*K}>M0~DW$@0y4ak~p&wgS)tK*|c#1{<0)|$S!s~p5${Xb&q z3i9=_P?oPs;CQPkIBr}@t(}b19J~?vtrYbWW9U9Kn4XH$ za9|;5xh#ek!%kpoObj;W`0${GCvY&HvF;ntRdoplT3bOuS3R1;t2#4FO(wVj&<^_Z&(b^RVS$7`K|la_?6^e!A9`y*Grjq@)L@Hjcx$TuW9z z^<{>QH={hd^7rIKmRyPDlcrD}Y7}G6HM7xoTok%qis5K6H*KbN7~O+ZnX}M{s+vK# z+XS>L@5=Z!iTo?Z)(6EEL20KC4L453fp&$M@G*|dr+C86Vig8gxKZ#~g7I>LFuNp- zbFasv*T6kcA2c2Ay_0zbZd}^i10Qeh$2#92KD++|M-@x(C(eow#k-|NeGhz2zK3*! zNqAe_33b1H*>E?2nsu%myf^^1N6TOl?A91dkd-NGL? zRt7Ns_GsL^?ZFmT3-L-2?XvJFT>9)y?OQ4w|8W?cm)X)+`5K}JG-B8b8Gj8VmTH7@ z`qgfnTWX#3ST*2-~Vguv#_~nVJ#EiVtStXMs(#oG{Kklx;6|KjX5vp$sX6w#@+fFnX~t59C*G)Xo}Pjyk{&H zZ1?J5Q0tSz^~_d0vuu&9uuC<93SEVafdwot9LAeZTyXZUy5LjNk1lmxnNSl>zvszJ zem8J6~`QYd>_t{iG_6CrO)+~i#gEMS+w|< zW3agj=RfNYVOLL1ZF+=PqdQO~wIA-}b>+jC6On1sk_#)HvGr~&cRN4AlS)PQTcQZ> z7VmMRM=bWf+79obIoS7G9!(Q0uyl-=8FY<6TTKD&H%Gh}zzcT%SaHmi$B&N_ravFSF7Jz=(bSW#1GfqnwR=;|v^|ts zS@US$8N#cOLjD~Zf-zPpoa^#j*57D@tYugM4c2~!OTR!N=Ru{ce7YiP-c<^w4IhQI zFyig%H?s9951=u8lWb+LE<(ursWP+4tAuM7MGVY^~?QoSIx7{#GR3=3Zj8 zK|HTc96&YQYzB`Ls{)RgFsZI5)!jz$Qg^Y6q0ExDS95sHd8Ac0ygc{ zz|ASc**$188b%IgUS$prxsT+T5m%x1elSZ196|o&BA!3gh^N~MsVCmJCQ);+uDdC# zetJOdcz@a+I10;49_%p49OuHl*ic!D{!cVn(cKzO|FZa{V?DZSt8$mk3BfOU8@{$S zMo{)#=s!xqt10rrQZeG)Frhs{`=q1b`6Glb-z5wgaSrCS@|fm-UGURZ5sDq7F+52V zr;8Igr|uX0?{;BR%>(Sa-k&9p+H!46b8<=uNA)Ksm8rA!y7t^IM&0GM2QX=xXi0vx zqw=O_2!gg-BCNtgaiI* zi&p4B&O5XYUWdc^eNlxl>GoFHoabi{FJ?H_{9BKZr&@wvKqa6!TCjb-2aS`q36pmx zVn^2^oK+};mu7n*#k&A$Cmsrs7E|E8I+w@Fl-Rk^fg!E*si`@DhhCX5zqLqPZV=_` zQ#g3MczcRO#%(udSXUT8=hF7E(G0jVe6CT zcsAOTC1cXi%08MG4y=a8kvL{L^~2C5=`566gKE`Gh97n2p_#{ES@;ujh2;o3AHZD8 zgK(%;(7d-kCHE*br1H(=a(eXeZ%5GjKf!`@*&{`l_3aGNT0 zd;DAI;kpX3mrJolbrqIByM_xxM`7>pIv7n_jO-TPcqmN7CVTf zbzhM5?=ZYBwPNN6OXPbSQ#iW_(}%QS()sgPalw!om0Pg+q9F&wKSiCXC6`aUjz4{! zh{?TqW@$MFuZ-c6X)W=$xQH`eR3NV*pSgJrf@XapP2P%n9AnE4>)s1rJLj@{`gBZq zGMp2hs|ij&9?HslnDWijwwRRq4dGup3L|vhW5o0n;RBUvx$3--ezgPp)%V9Rg;wl! zyhfHrU%v0Cg#}C0sH~F9_HCb_qVo-5!Jh%_m0iT4n*Z?Y>wKZ}kQ6SqIxA}k?@d%U z;nUSXZkm%%b7v#k+>&SS*dAPa@QR?nz=!vT$Doy^4>y(93hP=$i_r*c_+^FDMNSDf zzNfO>W)|-56|*ySF1TKu#WwGz;K-{K>YGM!;Gwl>yz>?T&(|a8Z5pkIS0Oj}K3v5p zLdsfGuCc3xwrv}FznzZ`Qxmw-`zV%${6gN%7tqih2#ur@V%5}CJQ{KZx>4JN^#-@m zx!3~jQ?H_UT`hiIsK$#Cdl545A%+SqVWuNS4tFJEQ{F4QGY(?H%{!2rA;;AtT5g4C?he1<;vD$%(y^BnR`M#7`UPcMlJ>{_E>}t z?Yc2&^drH}-IjN+k3;qKE)00r8ykN*vBqgPviFIVUaux0$Oychu@MEYNsk+;q6ymq zr3J${$fgIJZ3C%0?6Is-Gm%HvX$VcO-Yk;)i0NrT+_Ki4$&PN+p4dw0X4ivv3VQOF znHUZ9>x?_c6IdHO3#wkhyjdaPm+5`=!G$TQwf3XwSPB{-MPpWp-)O zWM+#t91xwu`);nXlk4q-0JHv-6>Ue;+&i-MAs(o4yDQs#Z3VoK^=0pI&rsyooBPA( zV5Lzi(Q+RmpAF%w<#MPf=*TNuP7BJ`PRtv=N$9dnn}Jutgxjf|Ii*__-u*V@w)hhm z_ri?DnWb>uWyNh*!_obsE_b{i&aH=*pqp=BMz;O}x0N{@aCSU4jxOMlE)6I@B;x|B zZj|**;*t;>jvwSFMj_0^=tlw{fA{7Fw;=vlaT6cJinD#9jnHvn7Qf{dqs#h1e82uO zw&)wM-wQpqyxNIHVuobVdRty9Qst6V8@@Ic-(R~iNS!#6>juw9U`Re!ock(-TpYm- z7CJ&sk3z=(FUo9}%80mDoERFz)qf^4_!X9%VLnMJLdU#vY=NX`Xq*Ne}fge zw2I-qu7?HA4W)eG4J@DN&W6nAsA=m@C(onUv(A(UpZ8GC3bB2>+fQMEGo zY_R0j+4G<^2Hd)%gkFM}S$#K{%L47itXL6Cvz_5Lrhr!eI#PF>J0rivGUQ$`hna;@ zU)z<1LwfPPW*oC*DKv^I;C_b#Xm8(_J>MAfdSx*$gp|Yb)KIcmozvVb_)gu9hXy&Z zI@FCWf$caT$b(-dxYKMy0MBG?g?Dx_dx?>c-}{T%x{DVgE*EfEPcgnD+FFT6@wp2E;SIq0#YKPx+!VM%fyw$i*U(?8+Q z8F$a1m1`vBj%e_2TW@N#Sc?%VVzo)=D|lay<1sZ;{yd|H9WO1|KRpfe{dCx~eYJ4S zT!DE_4#Lex`gBS-40RiO7CjN8uoho2*f>h8_PUM2H`?&2HK6~{S;*XOP6gGC2v2WC zgXjrp*Xb3;1Wd&K)AD@Q>mnBIXwBB28}Uu}h!Zo{LT9@QjqA3-u){%==BmTD$5OP- zcp%)UJ&rTuD}`gRhA_98eJ-AG5J^VyZZL`}?xLo$&+EH?}>+i~MHP>L0 z9?41tIj+CanTe-sp;iQL=yeLOle^LI&UDb0Bw;-*9Sb6d36($6kvtI2xj){@6 z_2%{1JGdhi?H*vx!uvRv_CuyL?}L!2X(}Xzhd7cMit*qhry+X(uc?wfRd*tU>RTy7r!yfOa;c%}SEDzL1Qj!=|mT$zk zKCSpP`Wg;h)!~<_<#?d4M(dc5wX%f~HmtkEgh&80;lBQ@wlhLwK>nQKV*e) zH}V3u-ta>ClnvNhRx1Xdw?Hm&Hdf602UF1xaDoC|tdr5W^f8jwSl~s#L%dTT%=0bQ zV2*1(?;HPu!}}z5(T&8gc7@!v^cmELgfXT{ll@-zW~!Mt$NMI8+AuwyU6aLowb4}m zpD&WO9ch=uD7*dxly(bYwNF3TYWHHE`Z+W`?MUxEZMb-wGxO?<`Dd&i!?Rj)!B;Ql zT+!m|hbLv3v8?dSxgtOW3F-06LtSBT!(e!ZT-%?(a?>br+vb^%?dnzN}kFujc9pe7@nEi z(!45z)jO@3wQwkwwbkI;=_>4}rcM0=dy#Zqtn{n2X6t#@^wB+ps{=QpyMtI6s{IJ< z;$(Q+FdZuR=(VF8R@0_81C&a*fKV6|>ropo!EgpwVcwWptgnzN6$|!eEc_Xmu z-d8Lx{eyXR3G}~e!Rj1yOj9>vzIv*c+p+W0i8BWtR~ilvJlygnwB z-|m4H)%)=9?plm|VaM-p_dw&oDwO{TL71HdJBb-8=PN7GXY?^djL_!uosBp*<2=-L zDlsQroe_r?qj=jYWZx=-`tYuVksNd7gR$Mw1qI6f9CZ9VGDmB`zfU82<$b|~dL_2m zUjUU$k8u5ks;r z?J(vrn+A0Da_03$3(A{E&@$&G9M3jl@VWq|Om}7dhfw@fGU0@MNmR6m74 zgqF4HOx&G9d7DfQ?~wwhQL%!hyv3xh)g-vsN zaDw(n9AiH*VjRrsMY(KxufccSlG))>5r>`Y%FvaUWaf4QnKE-EcP%X7%ldo5_+y#8 z>m)F5K`Kw5ypHQri@0=y4+nNGpv!wbZi*a$&od+WH);~%%NvD^#)raWF*9{8VuO(K z0?KH(~MK9Lx{RA)HgEAVv70R>v z@P1$!9IFk5gL~ajtB}BVnpbe-@lxUS!oD((67hW45DnYJgTk)_UA|Ku!eI`>x#Mn% z%=Wk~U3LuO$I=3xpEQ!r=G{0#KZYvk&VTb;a*kyj`-&BdyZdL-S^P@JC0Lag78J1a z34ui?7RbUkh0vr`J}Yj=ig&HHaC1`_JqvqKQ@0NXI#vUFv-n|cviJp4wpamaMvb}O zg!E7D3`h#b$=2O)wxUWF|Ie1jQEy~}w-v&pp)E?c*swy)1Y5LL!+OO(S=WDUxOP&6 zu<82>BreVnt{eHr0d&KyolzrMU~n@zo0rdaqhi)mt2 zrS`L7v|70nhn^JB@0K-l7Z&n*tH%hxP=X^v22v|aL#Q8KMAvij(7ck!jk)h+OOHK} zJ+K=EC8jW-b`K&(9TVbfb%bAYdNSHzjs%AL;T7c$%^p(|N*(ryg9|sfY$1J=l<=A=GRZSgqHKe=qcB-?;hk4$q^VTq6J6DrSgk9lkwo z%PXNLWb;0aWaE)XFm55n490svw|f$IR<1&2?>2NuJ0d7g>&a0q-@yN;3H8fXV&Fa* zGmc)zpiWJ~uwB_awq-7CJCrbIwl+S5C(%uQHv<0*A-%;)$_-fR z*p-uiyu}o_6SJb>ZmKC1_Q>Ig*cRA+tP|5tDhLiq0~i|Yh&|_Tq2$|Y;iG9XAEO=o z#k*74NQ~1f1kzKiHt@H&DYFyb+nB^~wpv`o4^0MwZm|cK%Z=cjxXm(;o7;ra=dEev zE>>C87I4$KfjBcunJwoxA>@F_hpx5QU3yj)l{!+a##)H!8_gK>SOt>~#xmQZ6ta6i zU~k(FnW7JPFZL#sO}a28ejKzqxo}~NQ;2D^S7!S$m2#aLg;lwQGR{Th7z7>l*QlS}Mi?rdw|776hu_UM49Q!7J7%GD)ZT;l z-Uo$^@6zdbb`boJ=5s=Z4&45F)9T(r^gWl!iR~uf(YF=mSbobS_{ zUpISU(|1QEzr2N~`ooEti*d=m9X(cEMK520yE|mTD{q%joSeZ9TkB=z?@l2!Q3*Rr zqd8FZzR-Ao1Cqzcz#+3W^DL_nT}$0*flejrM08y@%w0~cVO0TT^dYS zgQmyPtc?)ASX~##?MJR+TXc@taeGsMUiwvmu>IPY)x?IUI}M_UD)pIt)Pc@dDgTA` zdAl$%!HXk@s&cUTecAq}oe*Ld#oywY_$9_2vXt*wELJuzY~@cmr&4UcSqH08R*Zh1 zNP}0`@cMu6M+ZaJ*?Y5t!AId)_iZwd=lOhF=fLMOP0lJg1kJJ-4)FVmFTzW>merzA z^aE3ubmFr)YP>u5E;zIYwW)E^76JRli=g0fkU zKbWI46EovXuudb37V9i%@%{k@j#!8UvD)f*{#Q(%VY;inzzBCqEByMVI74Bpe<=lXMfdDeZ)jKZ9V>m_XU?V4mxJ4s+8^Vy5^t!+j-v z#y(RPe6a;@4+zYjJe;GSJ{M*!`HXI2zHHp|be_sNEEu=g1YbLIF5BCeC;M08aE1bd z^EIi^--+@XcIf?~Lg*}>mysFdW!>Y*bQzDWf0Mc4f-;xN{}M znkaq|a{@*Kb-4Pp8s|F(6_dt$H%8Qyz7B5+)b=-eKe3=t`4L2Ku3(5ehF`a)9Jdq zHwTW^!GzX_;3?+0rgiN_jlm1iF7hcNCMfWv7!MdQC~K(nuLY!P%FX18K=hFOKqSvgsEzu{t_m}u0LHp)@NiLGSrSTHI(l}`!XHU!ANq9@+B)ygRBk@JjBS{Y>I;C;azLNYUx}OU<4zb~TCU=}A@kU`rk$nnS00^cxYAk9WumE) z%ecp9)tg!!TX3bu+`Z9sX4;;e#~pV)9@qAUcX`2;@bN9@dv9EQGf%Y3gHdNwoH&F%j(FX;cF>Ab_a(EBiK?-VjKlUYWD>`ivE8?r}M zWv0j;DH+*CNF*UDGKwU7k1~>MNePumz2|y8`RBgsI@f#hxu56x{(8^CG2B2Wxt*V1 z1@-YEflp!Q=TCtP$~!-1Q`sS*>JC4v@9>bu4ofw6SPm9z?fiH_XNSbPJJi(Mp$|9? zZW`?Td}`hyTPCUmawbY*Qso#eRc7Hsc?`J=W~r}=EcQ{Hv*6nAVlF3CYRr-@%y@)K zgHb9>n3S#UZazH`g}lV;1{t|B4b@bNDdHdT6k*A2YEp8-#r%6-Z8VwN9kHbqES5^V z=SRpG+bi?7h+v;FrHchKp(Tk@BgHgFc{}rPL8m>#r$dfMbS)j_u8}iHaIeZR#j}t< zx!z!#)Og*PgDTHN@{K7WJwYCCa+!WUW0+-_+`=aw-ziZ6a|%0AWfW-zB!ojMP#qiw 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

G`9usC<#GAlWI`8Vw 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%0D_2I(HU^@K_JSaG^8Lr9&T$(l5OZ7UXvit&AeSew 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 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata deleted file mode 100644 index 58dba597b5f35b4a918ec7eaf79c3ea877e03ddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360000 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%0AdvjP^tQv=h==h1hxs{SIYi9fBAa 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

dI>*xmh6a61GH&Wa8 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 AkpKVy diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_0 deleted file mode 100644 index 164d1c0e02643840d748fe3bc6646843dbe475f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137771 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 Qa-1BTj~j45Hm0rn|C|PA7XSbN diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_1 deleted file mode 100644 index 5c161e7e4f51131e1aa2b339bf4d45af0cec1bf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137771 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 Q4o~>=;rIpKVue5de;0j13;+NC diff --git a/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 b/demos/offline_ivf/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.shard_2 deleted file mode 100644 index 1846b543b1a42b7b8f8dbe640bc48b9143f0311f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137771 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 diff --git a/demos/offline_ivf/tests/test_iterate_input.py b/demos/offline_ivf/tests/test_iterate_input.py deleted file mode 100644 index 3f59071102..0000000000 --- a/demos/offline_ivf/tests/test_iterate_input.py +++ /dev/null @@ -1,132 +0,0 @@ -# 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 numpy as np -import unittest -from typing import List -from utils import load_config -from tests.testing_utils import TestDataCreator -import tempfile -from dataset import create_dataset_from_oivf_config - -DIMENSION: int = 768 -SMALL_FILE_SIZES: List[int] = [100, 210, 450] -LARGE_FILE_SIZES: List[int] = [1253, 3459, 890] -TEST_BATCH_SIZE: int = 500 -SMALL_SAMPLE_SIZE: int = 1000 -NUM_FILES: int = 3 - - -class TestUtilsMethods(unittest.TestCase): - """ - Unit tests for iterate and decreasing_matrix methods. - """ - - def test_iterate_input_file_smaller_than_batch(self): - """ - Tests when batch size is larger than the file size. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=DIMENSION, - data_type=np.float16, - file_sizes=SMALL_FILE_SIZES, - ) - data_creator.create_test_data() - args = data_creator.setup_cli() - cfg = load_config(args.config) - db_iterator = create_dataset_from_oivf_config( - cfg, args.xb - ).iterate(0, TEST_BATCH_SIZE, np.float32) - - for i in range(len(SMALL_FILE_SIZES) - 1): - vecs = next(db_iterator) - if i != 1: - self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) - else: - self.assertEqual( - vecs.shape[0], sum(SMALL_FILE_SIZES) - TEST_BATCH_SIZE - ) - - def test_iterate_input_file_larger_than_batch(self): - """ - Tests when batch size is smaller than the file size. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=DIMENSION, - data_type=np.float16, - file_sizes=LARGE_FILE_SIZES, - ) - data_creator.create_test_data() - args = data_creator.setup_cli() - cfg = load_config(args.config) - db_iterator = create_dataset_from_oivf_config( - cfg, args.xb - ).iterate(0, TEST_BATCH_SIZE, np.float32) - - for i in range(len(LARGE_FILE_SIZES) - 1): - vecs = next(db_iterator) - if i != 9: - self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) - else: - self.assertEqual( - vecs.shape[0], - sum(LARGE_FILE_SIZES) - TEST_BATCH_SIZE * 9, - ) - - def test_get_vs_iterate(self) -> None: - """ - Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=DIMENSION, - data_type=np.float16, - file_size=SMALL_SAMPLE_SIZE, - num_files=NUM_FILES, - normalise=True, - ) - data_creator.create_test_data() - args = data_creator.setup_cli() - cfg = load_config(args.config) - ds = create_dataset_from_oivf_config(cfg, args.xb) - vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) - self.assertEqual( - vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES - ) - vecs_by_get = ds.get(list(range(vecs_by_iterator.shape[0]))) - self.assertTrue(np.all(vecs_by_iterator == vecs_by_get)) - - def test_iterate_back(self) -> None: - """ - Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=DIMENSION, - data_type=np.float16, - file_size=SMALL_SAMPLE_SIZE, - num_files=NUM_FILES, - normalise=True, - ) - data_creator.create_test_data() - args = data_creator.setup_cli() - cfg = load_config(args.config) - ds = create_dataset_from_oivf_config(cfg, args.xb) - vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) - self.assertEqual( - vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES - ) - vecs_chunk = np.vstack( - [ - next(ds.iterate(i, 543, np.float32)) - for i in range(0, SMALL_SAMPLE_SIZE * NUM_FILES, 543) - ] - ) - self.assertTrue(np.all(vecs_by_iterator == vecs_chunk)) diff --git a/demos/offline_ivf/tests/test_offline_ivf.py b/demos/offline_ivf/tests/test_offline_ivf.py deleted file mode 100644 index b3501122ca..0000000000 --- a/demos/offline_ivf/tests/test_offline_ivf.py +++ /dev/null @@ -1,545 +0,0 @@ -# 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 numpy as np -import unittest -from utils import load_config -from offline_ivf import OfflineIVF -import pathlib as pl -import tempfile -import shutil -import os -from typing import List -from tests.testing_utils import TestDataCreator -from run import process_options_and_run_jobs - -INDEX_TEMPLATE_FILE: str = "/tests/test_data/IVF256_PQ4.empty.faissindex" -OPQ_INDEX_TEMPLATE_FILE: str = ( - "/tests/test_data/OPQ4_IVF256_PQ4.empty.faissindex" -) -KNN_RESULTS_FILE: str = ( - "/my_test_data_in_my_test_data/knn/I0000000000_IVF256_PQ4_np2.npy" -) -TEST_INDEX_A: str = "/tests/test_data/goku_lang/IVF256_PQ4.faissindex" -TEST_INDEX_DATA_A: str = ( - "/tests/test_data/goku_lang/IVF256_PQ4.faissindex.ivfdata" -) -TEST_INDEX_B: str = "/tests/test_data/coco_lang/IVF256_PQ4.faissindex" -TEST_INDEX_DATA_B: str = ( - "/tests/test_data/coco_lang/IVF256_PQ4.faissindex.ivfdata" -) -TEST_INDEX_OPQ: str = "/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex" -TEST_INDEX_DATA_OPQ: str = ( - "/tests/test_data/goku_lang/OPQ4_IVF256_PQ4.faissindex.ivfdata" -) -A_INDEX_FILES: List[str] = [ - "I_a_gt.npy", - "D_a_gt.npy", - "vecs_a.npy", - "D_a_ann_IVF256_PQ4_np2.npy", - "I_a_ann_IVF256_PQ4_np2.npy", - "D_a_ann_refined_IVF256_PQ4_np2.npy", -] - -A_INDEX_OPQ_FILES: List[str] = [ - "I_a_gt.npy", - "D_a_gt.npy", - "vecs_a.npy", - "D_a_ann_OPQ4_IVF256_PQ4_np200.npy", - "I_a_ann_OPQ4_IVF256_PQ4_np200.npy", - "D_a_ann_refined_OPQ4_IVF256_PQ4_np200.npy", -] - -B_INDEX_FILES: List[str] = [ - "I_b_gt.npy", - "vecs_b_gt.npy", - "vecs_b_ann_IVF256_PQ4_np2.npy", - "D_b_ann_gt_IVF256_PQ4_np2.npy", - "I_b_ann_gt_IVF256_PQ4_np2.npy", - "margin_refined_IVF256_PQ4_np2.npy", - "idx_b_ann_IVF256_PQ4_np2.npy", -] - - -class TestOIVF(unittest.TestCase): - """ - Unit tests for OIVF. Some of these unit tests first copy the required test data objects and puts them in the tempdir created by the context manager. - """ - - def assert_file_exists(self, filepath: str) -> None: - path = pl.Path(filepath) - self.assertEqual((str(path), path.is_file()), (str(path), True)) - - def test_consistency_check(self) -> None: - """ - Test the OIVF consistency check step, that it throws if no other steps have been ran. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float16, - index_factory=["OPQ4,IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=2, - k=2, - metric="METRIC_L2", - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("consistency_check") - self.assertRaises( - AssertionError, process_options_and_run_jobs, test_args - ) - - def test_train_index(self) -> None: - """ - Test the OIVF train index step, that it correctly produces the empty.faissindex template file. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float16, - index_factory=["OPQ4,IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=2, - k=2, - metric="METRIC_L2", - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("train_index") - cfg = load_config(test_args.config) - process_options_and_run_jobs(test_args) - empty_index = ( - cfg["output"] - + "/my_test_data/" - + cfg["index"]["prod"][-1].replace(",", "_") - + ".empty.faissindex" - ) - self.assert_file_exists(empty_index) - - def test_index_shard_equal_file_sizes(self) -> None: - """ - Test the case where the shard size is a divisor of the database size and it is equal to the first file size. - """ - - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - index_shard_size = 10000 - num_files = 3 - file_size = 10000 - xb_ds_size = num_files * file_size - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float16, - index_factory=["IVF256,PQ4"], - training_sample=9984, - num_files=num_files, - file_size=file_size, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=index_shard_size, - query_batch_size=1000, - evaluation_sample=100, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("index_shard") - cfg = load_config(test_args.config) - process_options_and_run_jobs(test_args) - num_shards = xb_ds_size // index_shard_size - if xb_ds_size % index_shard_size != 0: - num_shards += 1 - print(f"number of shards:{num_shards}") - for i in range(num_shards): - index_shard_file = ( - cfg["output"] - + "/my_test_data/" - + cfg["index"]["prod"][-1].replace(",", "_") - + f".shard_{i}" - ) - self.assert_file_exists(index_shard_file) - - def test_index_shard_unequal_file_sizes(self) -> None: - """ - Test the case where the shard size is not a divisor of the database size and is greater than the first file size. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - file_sizes = [20000, 15001, 13990] - xb_ds_size = sum(file_sizes) - index_shard_size = 30000 - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float16, - index_factory=["IVF256,PQ4"], - training_sample=9984, - file_sizes=file_sizes, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=index_shard_size, - evaluation_sample=100, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("index_shard") - cfg = load_config(test_args.config) - process_options_and_run_jobs(test_args) - num_shards = xb_ds_size // index_shard_size - if xb_ds_size % index_shard_size != 0: - num_shards += 1 - print(f"number of shards:{num_shards}") - for i in range(num_shards): - index_shard_file = ( - cfg["output"] - + "/my_test_data/" - + cfg["index"]["prod"][-1].replace(",", "_") - + f".shard_{i}" - ) - self.assert_file_exists(index_shard_file) - - def test_search(self) -> None: - """ - Test search step using test data objects to bypass dependencies on previous steps. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - os.makedirs(tmpdirname + "/my_test_data/", exist_ok=True) - num_files = 3 - for i in range(num_files): - test_index_shard = ( - os.getcwd() - + f"/tests/test_data/goku_lang/IVF256_PQ4.shard_{i}" - ) - shutil.copy(test_index_shard, tmpdirname + "/my_test_data/") - file_size = 10000 - query_batch_size = 10000 - total_batches = num_files * file_size // query_batch_size - if num_files * file_size % query_batch_size != 0: - total_batches += 1 - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=query_batch_size, - evaluation_sample=100, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("search") - cfg = load_config(test_args.config) - process_options_and_run_jobs(test_args) - # TODO: add check that there are number of batches total of files - knn_file = cfg["output"] + KNN_RESULTS_FILE - self.assert_file_exists(knn_file) - - def test_evaluate_without_margin(self) -> None: - """ - Test evaluate step using test data objects, no margin evaluation, single index. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - goku_index_file = os.getcwd() + TEST_INDEX_A - goku_index_data = os.getcwd() + TEST_INDEX_DATA_A - shutil.copy(goku_index_file, new_path) - shutil.copy(goku_index_data, new_path) - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=10000, - evaluation_sample=100, - with_queries_ds=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("evaluate") - process_options_and_run_jobs(test_args) - common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" - for filename in A_INDEX_FILES: - file_to_check = common_path + filename - self.assert_file_exists(file_to_check) - - def test_evaluate_without_margin_OPQ(self) -> None: - """ - Test evaluate step using test data objects, no margin evaluation, single index. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + OPQ_INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - goku_index_file = os.getcwd() + TEST_INDEX_OPQ - goku_index_data = os.getcwd() + TEST_INDEX_DATA_OPQ - shutil.copy(goku_index_file, new_path) - shutil.copy(goku_index_data, new_path) - - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["OPQ4,IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=200, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=10000, - evaluation_sample=100, - with_queries_ds=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("evaluate") - process_options_and_run_jobs(test_args) - common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" - for filename in A_INDEX_OPQ_FILES: - file_to_check = common_path + filename - self.assert_file_exists(file_to_check) - - def test_evaluate_with_margin(self) -> None: - """ - Test evaluate step using test data objects with margin evaluation, pair of indexes A and B case. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_index_path = os.getcwd() + INDEX_TEMPLATE_FILE - new_path = f"{tmpdirname}/my_test_data/" - os.makedirs(new_path, exist_ok=True) - shutil.copy(test_index_path, new_path) - goku_index_file = os.getcwd() + TEST_INDEX_A - goku_index_data = os.getcwd() + TEST_INDEX_DATA_A - shutil.copy(goku_index_file, new_path) - shutil.copy(goku_index_data, new_path) - coco_index_file = os.getcwd() + TEST_INDEX_B - coco_index_data = os.getcwd() + TEST_INDEX_DATA_B - queries_path = f"{tmpdirname}/my_queries_data/" - os.makedirs(queries_path, exist_ok=True) - shutil.copy(coco_index_file, queries_path) - shutil.copy(coco_index_data, queries_path) - - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - num_files=3, - file_size=10000, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=10000, - evaluation_sample=100, - with_queries_ds=True, - evaluate_by_margin=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("evaluate") - process_options_and_run_jobs(test_args) - common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" - - for filename in A_INDEX_FILES + B_INDEX_FILES: - file_to_check = common_path + filename - self.assert_file_exists(file_to_check) - - def test_split_batch_size_bigger_than_file_sizes(self) -> None: - """ - Test split_files step, batch size bigger than file sizes. - """ - with tempfile.TemporaryDirectory() as tmpdirname: - test_file_sizes = [19999, 20001, 30000, 10000] - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - file_sizes=test_file_sizes, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=40000, - evaluation_sample=100, - with_queries_ds=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("train_index") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("index_shard") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("search") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("split_files") - process_options_and_run_jobs(test_args) - - common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" - I_groundtruth_files = [ - "I0000000000_IVF256_PQ4_np2.npy", - "I0000040000_IVF256_PQ4_np2.npy", - ] - first_file_gt = I_groundtruth_files.pop(0) - I_groundtruth = np.load(common_path + first_file_gt) - for batched_file in I_groundtruth_files: - I_groundtruth = np.vstack( - [I_groundtruth, np.load(common_path + batched_file)] - ) - split_files = sorted( - [ - "mm5_p5.x2y.002.idx.npy", - "mm5_p5.x2y.003.idx.npy", - "mm5_p5.x2y.000.idx.npy", - "mm5_p5.x2y.001.idx.npy", - ] - ) - first_file = split_files.pop(0) - output_path = ( - common_path - + "dists5_p5.my_test_data-my_queries_data.IVF256_PQ4.k2.np2.fp32-shard/" - ) - - I_all_splits = np.load(output_path + first_file) - for filename in split_files: - self.assert_file_exists(output_path + filename) - I = np.load(output_path + filename) - I_all_splits = np.vstack([I_all_splits, I]) - - self.assertTrue((I_all_splits == I_groundtruth).all()) - - def test_split_batch_size_smaller_than_file_sizes(self) -> None: - """ - Test split_files step, the batch size less than file sizes - """ - test_file_sizes = [14995, 5005] - with tempfile.TemporaryDirectory() as tmpdirname: - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - file_sizes=test_file_sizes, - nprobe=2, - k=2, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=5000, - evaluation_sample=100, - with_queries_ds=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("train_index") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("index_shard") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("search") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("split_files") - process_options_and_run_jobs(test_args) - - common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" - I_groundtruth_files = [ - "D_approx0000000000_IVF256_PQ4_np2.npy", - "D_approx0000005000_IVF256_PQ4_np2.npy", - "D_approx0000010000_IVF256_PQ4_np2.npy", - "D_approx0000015000_IVF256_PQ4_np2.npy", - ] - - first_file_gt = I_groundtruth_files.pop(0) - I_groundtruth = np.load(common_path + first_file_gt) - for batched_file in I_groundtruth_files: - I_groundtruth = np.vstack( - [I_groundtruth, np.load(common_path + batched_file)] - ) - split_files = sorted( - ["mm5_p5.x2y.000.dist.npy", "mm5_p5.x2y.001.dist.npy"] - ) - output_path = ( - common_path - + "dists5_p5.my_test_data-my_queries_data.IVF256_PQ4.k2.np2.fp32-shard/" - ) - first_file = split_files.pop(0) - I_all_splits = np.load(output_path + first_file) - for filename in split_files: - self.assert_file_exists(output_path + filename) - I = np.load(output_path + filename) - I_all_splits = np.vstack([I_all_splits, I]) - - self.assertTrue((I_all_splits == I_groundtruth).all()) - - def test_split_files_with_corrupted_input_file(self) -> None: - """ - Test split_files step, the batch size less than file sizes - """ - test_file_sizes = [14995, 5005] - with tempfile.TemporaryDirectory() as tmpdirname: - k = 2 - data_creator = TestDataCreator( - tempdir=tmpdirname, - dimension=8, - data_type=np.float32, - index_factory=["IVF256,PQ4"], - training_sample=9984, - file_sizes=test_file_sizes, - nprobe=2, - k=k, - metric="METRIC_L2", - index_shard_size=10000, - query_batch_size=5000, - evaluation_sample=100, - with_queries_ds=True, - ) - data_creator.create_test_data() - test_args = data_creator.setup_cli("train_index") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("index_shard") - process_options_and_run_jobs(test_args) - test_args = data_creator.setup_cli("search") - process_options_and_run_jobs(test_args) - # Corrupts the last file - common_path = tmpdirname + "/my_queries_data_in_my_test_data/knn/" - D_corrupt_file = np.empty((0, k), dtype=np.float32) - np.save( - common_path + "D_approx0000015000_IVF256_PQ4_np2.npy", - D_corrupt_file, - ) - test_args = data_creator.setup_cli("split_files") - - self.assertRaises( - AssertionError, process_options_and_run_jobs, test_args - ) diff --git a/demos/offline_ivf/tests/testing_utils.py b/demos/offline_ivf/tests/testing_utils.py deleted file mode 100644 index 34751f278a..0000000000 --- a/demos/offline_ivf/tests/testing_utils.py +++ /dev/null @@ -1,180 +0,0 @@ -# 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 yaml -import numpy as np -from typing import Dict, List, Optional - -OIVF_TEST_ARGS: List[str] = [ - "--config", - "--xb", - "--xq", - "--command", - "--cluster_run", - "--no_residuals", -] - - -def get_test_parser(args) -> argparse.ArgumentParser: - parser = argparse.ArgumentParser() - for arg in args: - parser.add_argument(arg) - return parser - - -class TestDataCreator: - def __init__( - self, - tempdir: str, - dimension: int, - data_type: np.dtype, - index_factory: Optional[List] = ["OPQ4,IVF256,PQ4"], - training_sample: Optional[int] = 9984, - index_shard_size: Optional[int] = 1000, - query_batch_size: Optional[int] = 1000, - evaluation_sample: Optional[int] = 100, - num_files: Optional[int] = None, - file_size: Optional[int] = None, - file_sizes: Optional[List] = None, - nprobe: Optional[int] = 64, - k: Optional[int] = 10, - metric: Optional[str] = "METRIC_L2", - normalise: Optional[bool] = False, - with_queries_ds: Optional[bool] = False, - evaluate_by_margin: Optional[bool] = False, - ) -> None: - self.tempdir = tempdir - self.dimension = dimension - self.data_type = np.dtype(data_type).name - self.index_factory = {"prod": index_factory} - if file_size and num_files: - self.file_sizes = [file_size for _ in range(num_files)] - elif file_sizes: - self.file_sizes = file_sizes - else: - raise ValueError("no file sizes provided") - self.num_files = len(self.file_sizes) - self.training_sample = training_sample - self.index_shard_size = index_shard_size - self.query_batch_size = query_batch_size - self.evaluation_sample = evaluation_sample - self.nprobe = {"prod": [nprobe]} - self.k = k - self.metric = metric - self.normalise = normalise - self.config_file = self.tempdir + "/config_test.yaml" - self.ds_name = "my_test_data" - self.qs_name = "my_queries_data" - self.evaluate_by_margin = evaluate_by_margin - self.with_queries_ds = with_queries_ds - - def create_test_data(self) -> None: - datafiles = self._create_data_files() - files_info = [] - - for i, file in enumerate(datafiles): - files_info.append( - { - "dtype": self.data_type, - "format": "npy", - "name": file, - "size": self.file_sizes[i], - } - ) - - config_for_yaml = { - "d": self.dimension, - "output": self.tempdir, - "index": self.index_factory, - "nprobe": self.nprobe, - "k": self.k, - "normalise": self.normalise, - "metric": self.metric, - "training_sample": self.training_sample, - "evaluation_sample": self.evaluation_sample, - "index_shard_size": self.index_shard_size, - "query_batch_size": self.query_batch_size, - "datasets": { - self.ds_name: { - "root": self.tempdir, - "size": sum(self.file_sizes), - "files": files_info, - } - }, - } - if self.evaluate_by_margin: - config_for_yaml["evaluate_by_margin"] = self.evaluate_by_margin - q_datafiles = self._create_data_files("my_q_data") - q_files_info = [] - - for i, file in enumerate(q_datafiles): - q_files_info.append( - { - "dtype": self.data_type, - "format": "npy", - "name": file, - "size": self.file_sizes[i], - } - ) - if self.with_queries_ds: - config_for_yaml["datasets"][self.qs_name] = { - "root": self.tempdir, - "size": sum(self.file_sizes), - "files": q_files_info, - } - - self._create_config_yaml(config_for_yaml) - - def setup_cli(self, command="consistency_check") -> argparse.Namespace: - parser = get_test_parser(OIVF_TEST_ARGS) - - if self.with_queries_ds: - return parser.parse_args( - [ - "--xb", - self.ds_name, - "--config", - self.config_file, - "--command", - command, - "--xq", - self.qs_name, - ] - ) - return parser.parse_args( - [ - "--xb", - self.ds_name, - "--config", - self.config_file, - "--command", - command, - ] - ) - - def _create_data_files(self, name_of_file="my_data") -> List[str]: - """ - Creates a dataset "my_test_data" with number of files (num_files), using padding in the files - name. If self.with_queries is True, it adds an extra dataset "my_queries_data" with the same number of files - as the "my_test_data". The default name for embeddings files is "my_data" + .npy. - """ - filenames = [] - for i, file_size in enumerate(self.file_sizes): - # np.random.seed(i) - db_vectors = np.random.random((file_size, self.dimension)).astype( - self.data_type - ) - filename = name_of_file + f"{i:02}" + ".npy" - filenames.append(filename) - np.save(self.tempdir + "/" + filename, db_vectors) - return filenames - - def _create_config_yaml(self, dict_file: Dict[str, str]) -> None: - """ - Creates a yaml file in dir (can be a temporary dir for tests). - """ - filename = self.tempdir + "/config_test.yaml" - with open(filename, "w") as file: - yaml.dump(dict_file, file, default_flow_style=False) diff --git a/demos/offline_ivf/utils.py b/demos/offline_ivf/utils.py deleted file mode 100644 index 378af00c30..0000000000 --- a/demos/offline_ivf/utils.py +++ /dev/null @@ -1,94 +0,0 @@ -# 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 numpy as np -import os -from typing import Dict -import yaml -import faiss -from faiss.contrib.datasets import SyntheticDataset - - -def load_config(config): - assert os.path.exists(config) - with open(config, "r") as f: - return yaml.safe_load(f) - - -def faiss_sanity_check(): - ds = SyntheticDataset(256, 0, 100, 100) - xq = ds.get_queries() - xb = ds.get_database() - index_cpu = faiss.IndexFlat(ds.d) - index_gpu = faiss.index_cpu_to_all_gpus(index_cpu) - index_cpu.add(xb) - index_gpu.add(xb) - D_cpu, I_cpu = index_cpu.search(xq, 10) - D_gpu, I_gpu = index_gpu.search(xq, 10) - assert np.all(I_cpu == I_gpu), "faiss sanity check failed" - assert np.all(np.isclose(D_cpu, D_gpu)), "faiss sanity check failed" - - -def margin(sample, idx_a, idx_b, D_a_b, D_a, D_b, k, k_extract, threshold): - """ - two datasets: xa, xb; n = number of pairs - idx_a - (np,) - query vector ids in xa - idx_b - (np,) - query vector ids in xb - D_a_b - (np,) - pairwise distances between xa[idx_a] and xb[idx_b] - D_a - (np, k) - distances between vectors xa[idx_a] and corresponding nearest neighbours in xb - D_b - (np, k) - distances between vectors xb[idx_b] and corresponding nearest neighbours in xa - k - k nearest neighbours used for margin - k_extract - number of nearest neighbours of each query in xb we consider for margin calculation and filtering - threshold - margin threshold - """ - - n = sample - nk = n * k_extract - assert idx_a.shape == (n,) - idx_a_k = idx_a.repeat(k_extract) - assert idx_a_k.shape == (nk,) - assert idx_b.shape == (nk,) - assert D_a_b.shape == (nk,) - assert D_a.shape == (n, k) - assert D_b.shape == (nk, k) - mean_a = np.mean(D_a, axis=1) - assert mean_a.shape == (n,) - mean_a_k = mean_a.repeat(k_extract) - assert mean_a_k.shape == (nk,) - mean_b = np.mean(D_b, axis=1) - assert mean_b.shape == (nk,) - margin = 2 * D_a_b / (mean_a_k + mean_b) - above_threshold = margin > threshold - print(np.count_nonzero(above_threshold)) - print(idx_a_k[above_threshold]) - print(idx_b[above_threshold]) - print(margin[above_threshold]) - return margin - - -def add_group_args(group, *args, **kwargs): - return group.add_argument(*args, **kwargs) - - -def get_intersection_cardinality_frequencies( - I: np.ndarray, I_gt: np.ndarray -) -> Dict[int, int]: - """ - Computes the frequencies for the cardinalities of the intersection of neighbour indices. - """ - nq = I.shape[0] - res = [] - for ell in range(nq): - res.append(len(np.intersect1d(I[ell, :], I_gt[ell, :]))) - values, counts = np.unique(res, return_counts=True) - return dict(zip(values, counts)) - - -def is_pretransform_index(index): - if index.__class__ == faiss.IndexPreTransform: - assert hasattr(index, "chain") - return True - else: - assert not hasattr(index, "chain") - return False From 9d74f0994fea09da405b0755a8990ff36e92600a Mon Sep 17 00:00:00 2001 From: Jason Sylka Date: Sat, 23 Dec 2023 07:39:10 -0800 Subject: [PATCH 006/206] Adding [[fallthrough]] annotation to case statements in faiss/utils/hamming_distance/generic-inl.h Summary: ## Context Due to a recent change (D52393687) to increase compiler warnings arcoss faiss/PACKAGE aggregator [build](https://www.internalfb.com/chronos/job/gp/9007207455707765) is failing. The annotation [[fallthrough]]; needs to be used in every [nested]case statement where fallthrough can occur. ## COMPILER ERROR ``` [2023-12-22T22:06:48.478-08:00] Action failed: fbcode//faiss:faiss (ovr_config//platform/linux:x86_64-fbcode-platform010-clang15-jemalloc-master#a916d57931e3a679) (cxx_compile impl/LocalSearchQuantizer.cpp) [CONTEXT] [2023-12-22T22:06:48.478-08:00] Remote command returned non-zero exit code 1 [CONTEXT] [2023-12-22T22:06:48.478-08:00] Remote action, reproduce with: `frecli cas download-action d02e5a31e82ab2a6a2ce8b84dff4d4bce3997ca49783013f860d16dd566edaaf:145` buck-out/v2/gen/fbcode/a916d57931e3a679/faiss/__faiss__/buck-headers/faiss/utils/hamming_distance/generic-inl.h:278:21: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough] [CONTEXT] case 7: [CONTEXT] ^ buck-out/v2/gen/fbcode/a916d57931e3a679/faiss/__faiss__/buck-headers/faiss/utils/hamming_distance/generic-inl.h:281:21: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough] [CONTEXT] case 6: [CONTEXT] ^ buck-out/v2/gen/fbcode/a916d57931e3a679/faiss/__faiss__/buck-headers/faiss/utils/hamming_distance/generic-inl.h:284:21: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough] [CONTEXT] case 5: ``` ## WHAT I DID +1 annotation **[[fallthrough]];** at every case statement that required it. ## WHAT I DIDNT DO - I did NOT **EXPORTED TO OSS FAISS** - mdouze please do this if it is required. I do not know your policy. Prior to landing i saw the message but was unsure. As well as not having github account. Differential Revision: D52396801 fbshipit-source-id: a563068af00135f7fd24de6633007a1957fc6e31 --- faiss/utils/hamming_distance/generic-inl.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/faiss/utils/hamming_distance/generic-inl.h b/faiss/utils/hamming_distance/generic-inl.h index 1607fb5d05..e0907a1586 100644 --- a/faiss/utils/hamming_distance/generic-inl.h +++ b/faiss/utils/hamming_distance/generic-inl.h @@ -275,24 +275,31 @@ struct HammingComputerDefault { len -= 8; accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 7: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 6: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 5: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 4: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 3: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 2: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 1: accu += popcount64(a64[i] ^ b64[i]); i++; @@ -302,20 +309,28 @@ struct HammingComputerDefault { const uint8_t* a = a8 + 8 * quotient8; const uint8_t* b = b8 + 8 * quotient8; switch (remainder8) { + [[fallthrough]]; case 7: accu += hamdis_tab_ham_bytes[a[6] ^ b[6]]; + [[fallthrough]]; case 6: accu += hamdis_tab_ham_bytes[a[5] ^ b[5]]; + [[fallthrough]]; case 5: accu += hamdis_tab_ham_bytes[a[4] ^ b[4]]; + [[fallthrough]]; case 4: accu += hamdis_tab_ham_bytes[a[3] ^ b[3]]; + [[fallthrough]]; case 3: accu += hamdis_tab_ham_bytes[a[2] ^ b[2]]; + [[fallthrough]]; case 2: accu += hamdis_tab_ham_bytes[a[1] ^ b[1]]; + [[fallthrough]]; case 1: accu += hamdis_tab_ham_bytes[a[0] ^ b[0]]; + [[fallthrough]]; default: break; } From 0727fff94148a440c86ef5dc06edc1db70c2139d Mon Sep 17 00:00:00 2001 From: Eddy Li Date: Tue, 26 Dec 2023 15:14:13 -0800 Subject: [PATCH 007/206] Adding [[fallthrough]] annotation to case statements in faiss/utils/hamming_distance/neon-inl.h Summary: Error: https://www.internalfb.com/sandcastle/workflow/1661828262501424314 Due to a recent change (D52393687) to increase compiler warnings arcoss faiss/PACKAGE aggregator build is failing. The annotation [[fallthrough]]; needs to be used in every [nested]case statement where fallthrough can occur. WHAT I DIDNT DO I did NOT EXPORTED TO OSS FAISS mdouze please do this if it is required. I do not know your policy. Prior to landing i saw the message but was unsure. As well as not having github account. Reviewed By: r-barnes Differential Revision: D52420730 fbshipit-source-id: 92ec8382226ea35bdacb668b3c329bd8b41a67fc --- faiss/utils/hamming_distance/neon-inl.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/faiss/utils/hamming_distance/neon-inl.h b/faiss/utils/hamming_distance/neon-inl.h index d1a0fdee7a..b66c16368c 100644 --- a/faiss/utils/hamming_distance/neon-inl.h +++ b/faiss/utils/hamming_distance/neon-inl.h @@ -341,21 +341,27 @@ struct HammingComputerDefault { case 7: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 6: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 5: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 4: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 3: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 2: accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 1: accu += popcount64(a64[i] ^ b64[i]); i++; @@ -367,18 +373,25 @@ struct HammingComputerDefault { switch (remainder8) { case 7: accu += hamdis_tab_ham_bytes[a[6] ^ b[6]]; + [[fallthrough]]; case 6: accu += hamdis_tab_ham_bytes[a[5] ^ b[5]]; + [[fallthrough]]; case 5: accu += hamdis_tab_ham_bytes[a[4] ^ b[4]]; + [[fallthrough]]; case 4: accu += hamdis_tab_ham_bytes[a[3] ^ b[3]]; + [[fallthrough]]; case 3: accu += hamdis_tab_ham_bytes[a[2] ^ b[2]]; + [[fallthrough]]; case 2: accu += hamdis_tab_ham_bytes[a[1] ^ b[1]]; + [[fallthrough]]; case 1: accu += hamdis_tab_ham_bytes[a[0] ^ b[0]]; + [[fallthrough]]; default: break; } From 449f02c4490cd052295e3e170e7dd772903c1619 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 27 Dec 2023 14:34:55 -0800 Subject: [PATCH 008/206] Add missing fallthrough to fbcode/faiss/utils/hamming_distance/neon-inl.h Differential Revision: D52436745 fbshipit-source-id: 7e4c55a8255b2f25b3394146a24d1af698b3b2e9 --- faiss/utils/hamming_distance/neon-inl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/faiss/utils/hamming_distance/neon-inl.h b/faiss/utils/hamming_distance/neon-inl.h index b66c16368c..adc09651e3 100644 --- a/faiss/utils/hamming_distance/neon-inl.h +++ b/faiss/utils/hamming_distance/neon-inl.h @@ -338,6 +338,7 @@ struct HammingComputerDefault { len -= 8; accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 7: accu += popcount64(a64[i] ^ b64[i]); i++; From b7681bef4018ddd99fa4e4784d3de19320d29943 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 3 Jan 2024 14:53:08 -0800 Subject: [PATCH 009/206] Remove unused exception parameter from files inc facer/engine/utils/StatsD.cpp Summary: `-Wunused-exception-parameter` has identified an unused exception parameter. This diff removes it. This: ``` try { ... } catch (exception& e) { // no use of e } ``` should instead be written as ``` } catch (exception&) { ``` If the code compiles, this is safe to land. Reviewed By: dmm-fb Differential Revision: D51977749 fbshipit-source-id: aab6f8bcb8a0d9273b7894b8e85615d4a31cac86 --- faiss/IndexIDMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/IndexIDMap.cpp b/faiss/IndexIDMap.cpp index 7972bec9a0..02bfbc0553 100644 --- a/faiss/IndexIDMap.cpp +++ b/faiss/IndexIDMap.cpp @@ -266,7 +266,7 @@ void IndexIDMap2Template::reconstruct( typename IndexT::component_t* recons) const { try { this->index->reconstruct(rev_map.at(key), recons); - } catch (const std::out_of_range& e) { + } catch (const std::out_of_range&) { FAISS_THROW_FMT("key %" PRId64 " not found", key); } } From beef6107fc50be5f5c6eea319bd52a5a75ef9890 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 5 Jan 2024 09:27:04 -0800 Subject: [PATCH 010/206] faiss paper benchmarks (#3189) Summary: - IVF benchmarks: `bench_fw_ivf.py bench_fw_ivf.py bigann /checkpoint/gsz/bench_fw/ivf` - Codec benchmarks: `bench_fw_codecs.py contriever /checkpoint/gsz/bench_fw/codecs` and `bench_fw_codecs.py deep1b /checkpoint/gsz/bench_fw/codecs` - A range codec evaluation: `bench_fw_range.py ssnpp /checkpoint/gsz/bench_fw/range` - Visualize with `bench_fw_notebook.ipynb` - Support for running on a cluster Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3189 Reviewed By: mdouze Differential Revision: D52544642 Pulled By: algoriddle fbshipit-source-id: 21dcdfd076aef6d36467c908e6be78ef851b0e98 --- benchs/bench_fw/benchmark.py | 482 +++++++++++++------- benchs/bench_fw/benchmark_io.py | 63 ++- benchs/bench_fw/descriptors.py | 27 ++ benchs/bench_fw/index.py | 759 +++++++++++++++++++++----------- benchs/bench_fw/utils.py | 107 +++++ benchs/bench_fw_codecs.py | 146 ++++++ benchs/bench_fw_ivf.py | 120 +++++ benchs/bench_fw_ivf_flat.py | 37 -- benchs/bench_fw_notebook.ipynb | 376 +++++++++++++++- benchs/bench_fw_range.py | 83 ++++ benchs/bench_fw_test.py | 61 --- contrib/factory_tools.py | 21 +- 12 files changed, 1729 insertions(+), 553 deletions(-) create mode 100644 benchs/bench_fw/utils.py create mode 100644 benchs/bench_fw_codecs.py create mode 100644 benchs/bench_fw_ivf.py delete mode 100644 benchs/bench_fw_ivf_flat.py create mode 100644 benchs/bench_fw_range.py delete mode 100644 benchs/bench_fw_test.py diff --git a/benchs/bench_fw/benchmark.py b/benchs/bench_fw/benchmark.py index 8ee53103e5..ccdbf9c5d6 100644 --- a/benchs/bench_fw/benchmark.py +++ b/benchs/bench_fw/benchmark.py @@ -4,18 +4,17 @@ # LICENSE file in the root directory of this source tree. import logging +from copy import copy from dataclasses import dataclass from operator import itemgetter from statistics import median, mean from typing import Any, Dict, List, Optional +from .utils import dict_merge from .index import Index, IndexFromCodec, IndexFromFactory from .descriptors import DatasetDescriptor, IndexDescriptor import faiss # @manual=//faiss/python:pyfaiss_gpu -from faiss.contrib.evaluation import ( # @manual=//faiss/contrib:faiss_contrib_gpu - knn_intersection_measure, -) import numpy as np @@ -90,26 +89,18 @@ def optimizer(op, search, cost_metric, perf_metric): continue logger.info(f"{cno=:4d} {str(parameters):50}: RUN") - cost, perf = search( + cost, perf, requires = search( parameters, cost_metric, perf_metric, ) + if requires is not None: + return requires logger.info( f"{cno=:4d} {str(parameters):50}: DONE, {cost=:.3f} {perf=:.3f}" ) op.add_operating_point(key, perf, cost) - - -def distance_ratio_measure(I, R, D_GT, metric): - sum_of_R = np.sum(np.where(I >= 0, R, 0)) - sum_of_D_GT = np.sum(np.where(I >= 0, D_GT, 0)) - if metric == faiss.METRIC_INNER_PRODUCT: - return (sum_of_R / sum_of_D_GT).item() - elif metric == faiss.METRIC_L2: - return (sum_of_D_GT / sum_of_R).item() - else: - raise RuntimeError(f"unknown metric {metric}") + return None # range_metric possible values: @@ -194,6 +185,7 @@ def sigmoid(x, a, b, c): @dataclass class Benchmark: + num_threads: int training_vectors: Optional[DatasetDescriptor] = None database_vectors: Optional[DatasetDescriptor] = None query_vectors: Optional[DatasetDescriptor] = None @@ -233,7 +225,8 @@ def range_search_reference(self, index, parameters, range_metric): else: m_radius = range_metric - lims, D, I, R, P = self.range_search( + lims, D, I, R, P, _ = self.range_search( + False, index, parameters, radius=m_radius, @@ -258,7 +251,8 @@ def range_search_reference(self, index, parameters, range_metric): ) def estimate_range(self, index, parameters, range_scoring_radius): - D, I, R, P = index.knn_search( + D, I, R, P, _ = index.knn_search( + False, parameters, self.query_vectors, self.k, @@ -275,10 +269,13 @@ def estimate_range(self, index, parameters, range_scoring_radius): def range_search( self, + dry_run, index: Index, search_parameters: Optional[Dict[str, int]], radius: Optional[float] = None, gt_radius: Optional[float] = None, + range_search_metric_function = None, + gt_rsm = None, ): logger.info("range_search: begin") if radius is None: @@ -293,16 +290,32 @@ def range_search( ) ) logger.info(f"Radius={radius}") - return index.range_search( + lims, D, I, R, P, requires = index.range_search( + dry_run=dry_run, search_parameters=search_parameters, query_vectors=self.query_vectors, radius=radius, ) + if requires is not None: + return None, None, None, None, None, requires + if range_search_metric_function is not None: + range_search_metric = range_search_metric_function(R) + range_search_pr = range_search_pr_curve( + D, range_search_metric, gt_rsm + ) + range_score_sum = np.sum(range_search_metric).item() + P |= { + "range_score_sum": range_score_sum, + "range_score_max_recall": range_score_sum / gt_rsm, + "range_search_pr": range_search_pr, + } + return lims, D, I, R, P, requires def range_ground_truth(self, gt_radius, range_search_metric_function): logger.info("range_ground_truth: begin") flat_desc = self.get_index_desc("Flat") - lims, D, I, R, P = self.range_search( + lims, D, I, R, P, _ = self.range_search( + False, flat_desc.index, search_parameters=None, radius=gt_radius, @@ -311,166 +324,277 @@ def range_ground_truth(self, gt_radius, range_search_metric_function): logger.info("range_ground_truth: end") return gt_rsm - def range_search_benchmark( - self, - results: Dict[str, Any], - index: Index, - metric_key: str, - radius: float, - gt_radius: float, - range_search_metric_function, - gt_rsm: float, - ): - logger.info(f"range_search_benchmark: begin {index.get_index_name()}") - - def experiment(parameters, cost_metric, perf_metric): - nonlocal results - key = index.get_range_search_name( - search_parameters=parameters, - query_vectors=self.query_vectors, - radius=radius, - ) - key += metric_key - if key in results["experiments"]: - metrics = results["experiments"][key] - else: - lims, D, I, R, P = self.range_search( - index, - parameters, - radius=radius, - gt_radius=gt_radius, - ) - range_search_metric = range_search_metric_function(R) - range_search_pr = range_search_pr_curve( - D, range_search_metric, gt_rsm - ) - range_score_sum = np.sum(range_search_metric).item() - metrics = P | { - "range_score_sum": range_score_sum, - "range_score_max_recall": range_score_sum / gt_rsm, - "range_search_pr": range_search_pr, - } - results["experiments"][key] = metrics - return metrics[cost_metric], metrics[perf_metric] - - for cost_metric in ["time"]: - for perf_metric in ["range_score_max_recall"]: - op = index.get_operating_points() - optimizer( - op, - experiment, - cost_metric, - perf_metric, - ) - logger.info("range_search_benchmark: end") - return results - def knn_ground_truth(self): logger.info("knn_ground_truth: begin") flat_desc = self.get_index_desc("Flat") - self.gt_knn_D, self.gt_knn_I, _, _ = flat_desc.index.knn_search( + self.build_index_wrapper(flat_desc) + self.gt_knn_D, self.gt_knn_I, _, _, requires = flat_desc.index.knn_search( + dry_run=False, search_parameters=None, query_vectors=self.query_vectors, k=self.k, ) + assert requires is None logger.info("knn_ground_truth: end") - def knn_search_benchmark(self, results: Dict[str, Any], index: Index): + def search_benchmark( + self, + name, + search_func, + key_func, + cost_metrics, + perf_metrics, + results: Dict[str, Any], + index: Index, + ): index_name = index.get_index_name() - logger.info(f"knn_search_benchmark: begin {index_name}") + logger.info(f"{name}_benchmark: begin {index_name}") def experiment(parameters, cost_metric, perf_metric): nonlocal results - key = index.get_knn_search_name( - parameters, - self.query_vectors, - self.k, - ) - key += "knn" + key = key_func(parameters) if key in results["experiments"]: metrics = results["experiments"][key] else: - D, I, R, P = index.knn_search( - parameters, self.query_vectors, self.k - ) - metrics = P | { - "knn_intersection": knn_intersection_measure( - I, self.gt_knn_I - ), - "distance_ratio": distance_ratio_measure( - I, R, self.gt_knn_D, self.distance_metric_type - ), - } + metrics, requires = search_func(parameters) + if requires is not None: + return None, None, requires results["experiments"][key] = metrics - return metrics[cost_metric], metrics[perf_metric] + return metrics[cost_metric], metrics[perf_metric], None - for cost_metric in ["time"]: - for perf_metric in ["knn_intersection", "distance_ratio"]: + for cost_metric in cost_metrics: + for perf_metric in perf_metrics: op = index.get_operating_points() - optimizer( + requires = optimizer( op, experiment, cost_metric, perf_metric, ) - logger.info("knn_search_benchmark: end") - return results + if requires is not None: + break + logger.info(f"{name}_benchmark: end") + return results, requires + + def knn_search_benchmark(self, dry_run, results: Dict[str, Any], index: Index): + return self.search_benchmark( + name="knn_search", + search_func=lambda parameters: index.knn_search( + dry_run, parameters, self.query_vectors, self.k, self.gt_knn_I, self.gt_knn_D, + )[3:], + key_func=lambda parameters: index.get_knn_search_name( + search_parameters=parameters, + query_vectors=self.query_vectors, + k=self.k, + reconstruct=False, + ), + cost_metrics=["time"], + perf_metrics=["knn_intersection", "distance_ratio"], + results=results, + index=index, + ) - def train(self, results): - xq = self.io.get_dataset(self.query_vectors) - self.d = xq.shape[1] - if self.get_index_desc("Flat") is None: - self.index_descs.append(IndexDescriptor(factory="Flat")) - for index_desc in self.index_descs: - if index_desc.factory is not None: - index = IndexFromFactory( - d=self.d, - metric=self.distance_metric, - database_vectors=self.database_vectors, - search_params=index_desc.search_params, - construction_params=index_desc.construction_params, - factory=index_desc.factory, - training_vectors=self.training_vectors, - ) - index.set_io(self.io) - index.train() - index_desc.index = index - results["indices"][index.get_codec_name()] = { - "code_size": index.get_code_size() - } + def reconstruct_benchmark(self, dry_run, results: Dict[str, Any], index: Index): + return self.search_benchmark( + name="reconstruct", + search_func=lambda parameters: index.reconstruct( + dry_run, parameters, self.query_vectors, self.k, self.gt_knn_I, + ), + key_func=lambda parameters: index.get_knn_search_name( + search_parameters=parameters, + query_vectors=self.query_vectors, + k=self.k, + reconstruct=True, + ), + cost_metrics=["encode_time"], + perf_metrics=["sym_recall"], + results=results, + index=index, + ) + + def range_search_benchmark( + self, + dry_run, + results: Dict[str, Any], + index: Index, + metric_key: str, + radius: float, + gt_radius: float, + range_search_metric_function, + gt_rsm: float, + ): + return self.search_benchmark( + name="range_search", + search_func=lambda parameters: self.range_search( + dry_run=dry_run, + index=index, + search_parameters=parameters, + radius=radius, + gt_radius=gt_radius, + range_search_metric_function=range_search_metric_function, + gt_rsm=gt_rsm, + )[4:], + key_func=lambda parameters: index.get_range_search_name( + search_parameters=parameters, + query_vectors=self.query_vectors, + radius=radius, + ) + metric_key, + cost_metrics=["time"], + perf_metrics=["range_score_max_recall"], + results=results, + index=index, + ) + + def build_index_wrapper(self, index_desc: IndexDescriptor): + if hasattr(index_desc, 'index'): + return + if index_desc.factory is not None: + training_vectors = copy(self.training_vectors) + training_vectors.num_vectors = index_desc.training_size + index = IndexFromFactory( + num_threads=self.num_threads, + d=self.d, + metric=self.distance_metric, + database_vectors=self.database_vectors, + search_params=index_desc.search_params, + construction_params=index_desc.construction_params, + factory=index_desc.factory, + training_vectors=training_vectors, + ) + else: + index = IndexFromCodec( + num_threads=self.num_threads, + d=self.d, + metric=self.distance_metric, + database_vectors=self.database_vectors, + search_params=index_desc.search_params, + construction_params=index_desc.construction_params, + path=index_desc.path, + bucket=index_desc.bucket, + ) + index.set_io(self.io) + index_desc.index = index + + def clone_one(self, index_desc): + benchmark = Benchmark( + num_threads=self.num_threads, + training_vectors=self.training_vectors, + database_vectors=self.database_vectors, + query_vectors=self.query_vectors, + index_descs = [self.get_index_desc("Flat"), index_desc], + range_ref_index_desc=self.range_ref_index_desc, + k=self.k, + distance_metric=self.distance_metric, + ) + benchmark.set_io(self.io) + return benchmark + + def benchmark_one(self, dry_run, results: Dict[str, Any], index_desc: IndexDescriptor, train, reconstruct, knn, range): + faiss.omp_set_num_threads(self.num_threads) + if not dry_run: + self.knn_ground_truth() + self.build_index_wrapper(index_desc) + meta, requires = index_desc.index.fetch_meta(dry_run=dry_run) + if requires is not None: + return results, (requires if train else None) + results["indices"][index_desc.index.get_codec_name()] = meta + + # results, requires = self.reconstruct_benchmark( + # dry_run=True, + # results=results, + # index=index_desc.index, + # ) + # if reconstruct and requires is not None: + # if dry_run: + # return results, requires + # else: + # results, requires = self.reconstruct_benchmark( + # dry_run=False, + # results=results, + # index=index_desc.index, + # ) + # assert requires is None + + results, requires = self.knn_search_benchmark( + dry_run=True, + results=results, + index=index_desc.index, + ) + if knn and requires is not None: + if dry_run: + return results, requires else: - index = IndexFromCodec( - d=self.d, - metric=self.distance_metric, - database_vectors=self.database_vectors, - search_params=index_desc.search_params, - construction_params=index_desc.construction_params, - path=index_desc.path, - bucket=index_desc.bucket, + results, requires = self.knn_search_benchmark( + dry_run=False, + results=results, + index=index_desc.index, ) - index.set_io(self.io) - index_desc.index = index - results["indices"][index.get_codec_name()] = { - "code_size": index.get_code_size() - } - return results + assert requires is None + + if self.range_ref_index_desc is None or not index_desc.index.supports_range_search(): + return results, None + + ref_index_desc = self.get_index_desc(self.range_ref_index_desc) + if ref_index_desc is None: + raise ValueError( + f"Unknown range index {self.range_ref_index_desc}" + ) + if ref_index_desc.range_metrics is None: + raise ValueError( + f"Range index {ref_index_desc.factory} has no radius_score" + ) + for metric_key, range_metric in ref_index_desc.range_metrics.items(): + ( + gt_radius, + range_search_metric_function, + coefficients, + coefficients_training_data, + ) = self.range_search_reference( + ref_index_desc.index, ref_index_desc.search_params, range_metric + ) + gt_rsm = self.range_ground_truth( + gt_radius, range_search_metric_function + ) + results, requires = self.range_search_benchmark( + dry_run=True, + results=results, + index=index_desc.index, + metric_key=metric_key, + radius=index_desc.radius, + gt_radius=gt_radius, + range_search_metric_function=range_search_metric_function, + gt_rsm=gt_rsm, + ) + if range and requires is not None: + if dry_run: + return results, requires + else: + results, requires = self.range_search_benchmark( + dry_run=False, + results=results, + index=index_desc.index, + metric_key=metric_key, + radius=index_desc.radius, + gt_radius=gt_radius, + range_search_metric_function=range_search_metric_function, + gt_rsm=gt_rsm, + ) + assert requires is None - def benchmark(self, result_file=None): + return results, None + + def benchmark(self, result_file=None, local=False, train=False, reconstruct=False, knn=False, range=False): logger.info("begin evaluate") - faiss.omp_set_num_threads(24) + faiss.omp_set_num_threads(self.num_threads) results = {"indices": {}, "experiments": {}} - results = self.train(results) + xq = self.io.get_dataset(self.query_vectors) + self.d = xq.shape[1] + if self.get_index_desc("Flat") is None: + self.index_descs.append(IndexDescriptor(factory="Flat")) - # knn search self.knn_ground_truth() - for index_desc in self.index_descs: - results = self.knn_search_benchmark( - results=results, - index=index_desc.index, - ) - # range search if self.range_ref_index_desc is not None: index_desc = self.get_index_desc(self.range_ref_index_desc) if index_desc is None: @@ -498,19 +622,63 @@ def benchmark(self, result_file=None): gt_rsm = self.range_ground_truth( gt_radius, range_search_metric_function ) - for index_desc in self.index_descs: - if not index_desc.index.supports_range_search(): - continue - results = self.range_search_benchmark( - results=results, - index=index_desc.index, - metric_key=metric_key, - radius=index_desc.radius, - gt_radius=gt_radius, - range_search_metric_function=range_search_metric_function, - gt_rsm=gt_rsm, - ) + + self.index_descs = list(dict.fromkeys(self.index_descs)) + + todo = self.index_descs + for index_desc in self.index_descs: + index_desc.requires = None + + queued = set() + while todo: + current_todo = [] + next_todo = [] + for index_desc in todo: + results, requires = self.benchmark_one( + dry_run=True, + results=results, + index_desc=index_desc, + train=train, + reconstruct=reconstruct, + knn=knn, + range=range, + ) + if requires is None: + continue + if requires in queued: + if index_desc.requires != requires: + index_desc.requires = requires + next_todo.append(index_desc) + else: + queued.add(requires) + index_desc.requires = requires + current_todo.append(index_desc) + + if current_todo: + results_one = {"indices": {}, "experiments": {}} + params = [(self.clone_one(index_desc), results_one, index_desc, train, reconstruct, knn, range) for index_desc in current_todo] + for result in self.io.launch_jobs(run_benchmark_one, params, local=local): + dict_merge(results, result) + + todo = next_todo + if result_file is not None: self.io.write_json(results, result_file, overwrite=True) logger.info("end evaluate") return results + +def run_benchmark_one(params): + logger.info(params) + benchmark, results, index_desc, train, reconstruct, knn, range = params + results, requires = benchmark.benchmark_one( + dry_run=False, + results=results, + index_desc=index_desc, + train=train, + reconstruct=reconstruct, + knn=knn, + range=range, + ) + assert requires is None + assert results is not None + return results diff --git a/benchs/bench_fw/benchmark_io.py b/benchs/bench_fw/benchmark_io.py index 370efffce5..483acba8c7 100644 --- a/benchs/bench_fw/benchmark_io.py +++ b/benchs/bench_fw/benchmark_io.py @@ -10,6 +10,7 @@ import os import pickle from dataclasses import dataclass +import submitit from typing import Any, List, Optional from zipfile import ZipFile @@ -106,7 +107,7 @@ def write_file( fn = self.get_local_filename(filename) with ZipFile(fn, "w") as zip_file: for key, value in zip(keys, values, strict=True): - with zip_file.open(key, "w") as f: + with zip_file.open(key, "w", force_zip64=True) as f: if key in ["D", "I", "R", "lims"]: np.save(f, value) elif key in ["P"]: @@ -117,22 +118,22 @@ def write_file( self.upload_file_to_blobstore(filename, overwrite=overwrite) def get_dataset(self, dataset): - if dataset.namespace is not None and dataset.namespace[:4] == "std_": - if dataset.tablename not in self.cached_ds: - self.cached_ds[dataset.tablename] = dataset_from_name( - dataset.tablename, - ) - p = dataset.namespace[4] - if p == "t": - return self.cached_ds[dataset.tablename].get_train() - elif p == "d": - return self.cached_ds[dataset.tablename].get_database() - elif p == "q": - return self.cached_ds[dataset.tablename].get_queries() - else: - raise ValueError - elif dataset not in self.cached_ds: - if dataset.namespace == "syn": + if dataset not in self.cached_ds: + if dataset.namespace is not None and dataset.namespace[:4] == "std_": + if dataset.tablename not in self.cached_ds: + self.cached_ds[dataset.tablename] = dataset_from_name( + dataset.tablename, + ) + p = dataset.namespace[4] + if p == "t": + self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_train(dataset.num_vectors) + elif p == "d": + self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_database() + elif p == "q": + self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_queries() + else: + raise ValueError + elif dataset.namespace == "syn": d, seed = dataset.tablename.split("_") d = int(d) seed = int(seed) @@ -225,3 +226,31 @@ def write_index( logger.info(f"Saving index to {fn}") faiss.write_index(index, fn) self.upload_file_to_blobstore(filename) + assert os.path.exists(fn) + return os.path.getsize(fn) + + def launch_jobs(self, func, params, local=True): + if local: + results = [func(p) for p in params] + return results + print(f'launching {len(params)} jobs') + executor = submitit.AutoExecutor(folder='/checkpoint/gsz/jobs') + executor.update_parameters( + nodes=1, + gpus_per_node=8, + cpus_per_task=80, + # mem_gb=640, + tasks_per_node=1, + name="faiss_benchmark", + slurm_array_parallelism=512, + slurm_partition="scavenge", + slurm_time=4 * 60, + slurm_constraint="bldg1", + ) + jobs = executor.map_array(func, params) + print(f'launched {len(jobs)} jobs') + # for job, param in zip(jobs, params): + # print(f"{job.job_id=} {param=}") + results = [job.result() for job in jobs] + print(f'received {len(results)} results') + return results diff --git a/benchs/bench_fw/descriptors.py b/benchs/bench_fw/descriptors.py index 15e5b9330b..113f46b545 100644 --- a/benchs/bench_fw/descriptors.py +++ b/benchs/bench_fw/descriptors.py @@ -4,8 +4,13 @@ # LICENSE file in the root directory of this source tree. from dataclasses import dataclass +import logging from typing import Any, Dict, List, Optional +import faiss # @manual=//faiss/python:pyfaiss_gpu +from .utils import timer +logger = logging.getLogger(__name__) + @dataclass class IndexDescriptor: @@ -33,6 +38,10 @@ class IndexDescriptor: # [radius2_from, radius2_to) -> score2 range_metrics: Optional[Dict[str, Any]] = None radius: Optional[float] = None + training_size: Optional[int] = None + + def __hash__(self): + return hash(str(self)) @dataclass @@ -85,3 +94,21 @@ def get_filename( filename += f"_{self.num_vectors}" filename += "." return filename + + def k_means(self, io, k, dry_run): + logger.info(f"k_means {k} {self}") + kmeans_vectors = DatasetDescriptor( + tablename=f"{self.get_filename()}kmeans_{k}.npy" + ) + meta_filename = kmeans_vectors.tablename + ".json" + if not io.file_exist(kmeans_vectors.tablename) or not io.file_exist(meta_filename): + if dry_run: + return None, None, kmeans_vectors.tablename + x = io.get_dataset(self) + kmeans = faiss.Kmeans(d=x.shape[1], k=k, gpu=True) + _, t, _ = timer("k_means", lambda: kmeans.train(x)) + io.write_nparray(kmeans.centroids, kmeans_vectors.tablename) + io.write_json({"k_means_time": t}, meta_filename) + else: + t = io.read_json(meta_filename)["k_means_time"] + return kmeans_vectors, t, None diff --git a/benchs/bench_fw/index.py b/benchs/bench_fw/index.py index 3405f59561..4c536aa753 100644 --- a/benchs/bench_fw/index.py +++ b/benchs/bench_fw/index.py @@ -4,11 +4,11 @@ # LICENSE file in the root directory of this source tree. +from copy import copy import logging import os +from collections import OrderedDict from dataclasses import dataclass -from multiprocessing.pool import ThreadPool -from time import perf_counter from typing import ClassVar, Dict, List, Optional import faiss # @manual=//faiss/python:pyfaiss_gpu @@ -16,8 +16,8 @@ import numpy as np from faiss.contrib.evaluation import ( # @manual=//faiss/contrib:faiss_contrib_gpu OperatingPointsWithRanges, + knn_intersection_measure, ) - from faiss.contrib.factory_tools import ( # @manual=//faiss/contrib:faiss_contrib_gpu reverse_index_factory, ) @@ -27,67 +27,11 @@ ) from .descriptors import DatasetDescriptor +from .utils import distance_ratio_measure, get_cpu_info, timer, refine_distances_knn, refine_distances_range logger = logging.getLogger(__name__) -def timer(name, func, once=False) -> float: - logger.info(f"Measuring {name}") - t1 = perf_counter() - res = func() - t2 = perf_counter() - t = t2 - t1 - repeat = 1 - if not once and t < 1.0: - repeat = int(2.0 // t) - logger.info( - f"Time for {name}: {t:.3f} seconds, repeating {repeat} times" - ) - t1 = perf_counter() - for _ in range(repeat): - res = func() - t2 = perf_counter() - t = (t2 - t1) / repeat - logger.info(f"Time for {name}: {t:.3f} seconds") - return res, t, repeat - - -def refine_distances_knn( - D: np.ndarray, I: np.ndarray, xq: np.ndarray, xb: np.ndarray, metric -): - return np.where( - I >= 0, - np.square(np.linalg.norm(xq[:, None] - xb[I], axis=2)) - if metric == faiss.METRIC_L2 - else np.einsum("qd,qkd->qk", xq, xb[I]), - D, - ) - - -def refine_distances_range( - lims: np.ndarray, - D: np.ndarray, - I: np.ndarray, - xq: np.ndarray, - xb: np.ndarray, - metric, -): - with ThreadPool(32) as pool: - R = pool.map( - lambda i: ( - np.sum(np.square(xq[i] - xb[I[lims[i]:lims[i + 1]]]), axis=1) - if metric == faiss.METRIC_L2 - else np.tensordot( - xq[i], xb[I[lims[i]:lims[i + 1]]], axes=(0, 1) - ) - ) - if lims[i + 1] > lims[i] - else [], - range(len(lims) - 1), - ) - return np.hstack(R) - - # The classes below are wrappers around Faiss indices, with different # implementations for the case when we start with an already trained # index (IndexFromCodec) vs factory strings (IndexFromFactory). @@ -107,6 +51,7 @@ def param_dict_list_to_name(param_dict_list): n = "" for param_dict in param_dict_list: n += IndexBase.param_dict_to_name(param_dict, f"cp{l}") + l += 1 return n @staticmethod @@ -115,65 +60,120 @@ def param_dict_to_name(param_dict, prefix="sp"): return "" n = prefix for name, val in param_dict.items(): - if name != "noop": - n += f"_{name}_{val}" + if name == "snap": + continue + if name == "lsq_gpu" and val == 0: + continue + if name == "use_beam_LUT" and val == 0: + continue + n += f"_{name}_{val}" if n == prefix: return "" n += "." return n @staticmethod - def set_index_param_dict_list(index, param_dict_list): + def set_index_param_dict_list(index, param_dict_list, assert_same=False): if not param_dict_list: return index = faiss.downcast_index(index) for param_dict in param_dict_list: assert index is not None - IndexBase.set_index_param_dict(index, param_dict) + IndexBase.set_index_param_dict(index, param_dict, assert_same) index = faiss.try_extract_index_ivf(index) + if index is not None: + index = index.quantizer @staticmethod - def set_index_param_dict(index, param_dict): + def set_index_param_dict(index, param_dict, assert_same=False): if not param_dict: return for name, val in param_dict.items(): - IndexBase.set_index_param(index, name, val) + IndexBase.set_index_param(index, name, val, assert_same) @staticmethod - def set_index_param(index, name, val): + def set_index_param(index, name, val, assert_same=False): index = faiss.downcast_index(index) - + val = int(val) if isinstance(index, faiss.IndexPreTransform): Index.set_index_param(index.index, name, val) - elif name == "efSearch": - index.hnsw.efSearch - index.hnsw.efSearch = int(val) - elif name == "efConstruction": - index.hnsw.efConstruction - index.hnsw.efConstruction = int(val) - elif name == "nprobe": - index_ivf = faiss.extract_index_ivf(index) - index_ivf.nprobe - index_ivf.nprobe = int(val) - elif name == "k_factor": - index.k_factor - index.k_factor = int(val) - elif name == "parallel_mode": - index_ivf = faiss.extract_index_ivf(index) - index_ivf.parallel_mode - index_ivf.parallel_mode = int(val) - elif name == "noop": - pass + return + elif name == "snap": + return + elif name == "lsq_gpu": + if val == 1: + ngpus = faiss.get_num_gpus() + icm_encoder_factory = faiss.GpuIcmEncoderFactory(ngpus) + if isinstance(index, faiss.IndexProductLocalSearchQuantizer): + for i in range(index.plsq.nsplits): + lsq = faiss.downcast_Quantizer(index.plsq.subquantizer(i)) + if lsq.icm_encoder_factory is None: + lsq.icm_encoder_factory = icm_encoder_factory + else: + if index.lsq.icm_encoder_factory is None: + index.lsq.icm_encoder_factory = icm_encoder_factory + return + elif name in ["efSearch", "efConstruction"]: + obj = index.hnsw + elif name in ["nprobe", "parallel_mode"]: + obj = faiss.extract_index_ivf(index) + elif name in ["use_beam_LUT", "max_beam_size"]: + if isinstance(index, faiss.IndexProductResidualQuantizer): + obj = [faiss.downcast_Quantizer(index.prq.subquantizer(i)) for i in range(index.prq.nsplits)] + else: + obj = index.rq + elif name == "encode_ils_iters": + if isinstance(index, faiss.IndexProductLocalSearchQuantizer): + obj = [faiss.downcast_Quantizer(index.plsq.subquantizer(i)) for i in range(index.plsq.nsplits)] + else: + obj = index.lsq else: - raise RuntimeError(f"could not set param {name} on {index}") + obj = index + + if not isinstance(obj, list): + obj = [obj] + for o in obj: + test = getattr(o, name) + if assert_same and not name == 'use_beam_LUT': + assert test == val + else: + setattr(o, name, val) + + @staticmethod + def filter_index_param_dict_list(param_dict_list): + if param_dict_list is not None and param_dict_list[0] is not None and "k_factor" in param_dict_list[0]: + filtered = copy(param_dict_list) + del filtered[0]["k_factor"] + return filtered + else: + return param_dict_list def is_flat(self): - codec = faiss.downcast_index(self.get_model()) - return isinstance(codec, faiss.IndexFlat) + model = faiss.downcast_index(self.get_model()) + return isinstance(model, faiss.IndexFlat) def is_ivf(self): - codec = self.get_model() - return faiss.try_extract_index_ivf(codec) is not None + model = self.get_model() + return faiss.try_extract_index_ivf(model) is not None + + def is_2layer(self): + def is_2layer_(index): + index = faiss.downcast_index(index) + if isinstance(index, faiss.IndexPreTransform): + return is_2layer_(index.index) + return isinstance(index, faiss.Index2Layer) + + model = self.get_model() + return is_2layer_(model) + + def is_decode_supported(self): + model = self.get_model() + if isinstance(model, faiss.IndexPreTransform): + for i in range(model.chain.size()): + vt = faiss.downcast_VectorTransform(model.chain.at(i)) + if isinstance(vt, faiss.ITQTransform): + return False + return True def is_pretransform(self): codec = self.get_model() @@ -208,12 +208,15 @@ def get_model_name(self): def get_model(self): raise NotImplementedError + def get_construction_params(self): + raise NotImplementedError + def transform(self, vectors): transformed_vectors = DatasetDescriptor( tablename=f"{vectors.get_filename()}{self.get_codec_name()}transform.npy" ) if not self.io.file_exist(transformed_vectors.tablename): - codec = self.fetch_codec() + codec = self.get_codec() assert isinstance(codec, faiss.IndexPreTransform) transform = faiss.downcast_VectorTransform(codec.chain.at(0)) x = self.io.get_dataset(vectors) @@ -221,7 +224,18 @@ def transform(self, vectors): self.io.write_nparray(xt, transformed_vectors.tablename) return transformed_vectors - def knn_search_quantizer(self, index, query_vectors, k): + def snap(self, vectors): + transformed_vectors = DatasetDescriptor( + tablename=f"{vectors.get_filename()}{self.get_codec_name()}snap.npy" + ) + if not self.io.file_exist(transformed_vectors.tablename): + codec = self.get_codec() + x = self.io.get_dataset(vectors) + xt = codec.sa_decode(codec.sa_encode(x)) + self.io.write_nparray(xt, transformed_vectors.tablename) + return transformed_vectors + + def knn_search_quantizer(self, query_vectors, k): if self.is_pretransform(): pretransform = self.get_pretransform() quantizer_query_vectors = pretransform.transform(query_vectors) @@ -229,7 +243,9 @@ def knn_search_quantizer(self, index, query_vectors, k): pretransform = None quantizer_query_vectors = query_vectors - QD, QI, _, QP = self.get_quantizer(pretransform).knn_search( + quantizer, _, _ = self.get_quantizer(dry_run=False, pretransform=pretransform) + QD, QI, _, QP, _ = quantizer.knn_search( + dry_run=False, search_parameters=None, query_vectors=quantizer_query_vectors, k=k, @@ -242,20 +258,31 @@ def get_knn_search_name( search_parameters: Optional[Dict[str, int]], query_vectors: DatasetDescriptor, k: int, + reconstruct: bool = False, ): name = self.get_index_name() name += Index.param_dict_to_name(search_parameters) name += query_vectors.get_filename("q") name += f"k_{k}." + name += f"t_{self.num_threads}." + if reconstruct: + name += "rec." + else: + name += "knn." return name def knn_search( self, + dry_run, search_parameters: Optional[Dict[str, int]], query_vectors: DatasetDescriptor, k: int, + I_gt=None, + D_gt=None, ): - logger.info("knn_seach: begin") + logger.info("knn_search: begin") + if search_parameters is not None and search_parameters["snap"] == 1: + query_vectors = self.snap(query_vectors) filename = ( self.get_knn_search_name(search_parameters, query_vectors, k) + "zip" @@ -264,15 +291,28 @@ def knn_search( logger.info(f"Using cached results for {filename}") D, I, R, P = self.io.read_file(filename, ["D", "I", "R", "P"]) else: - xq = self.io.get_dataset(query_vectors) + if dry_run: + return None, None, None, None, filename index = self.get_index() Index.set_index_param_dict(index, search_parameters) - if self.is_ivf(): + if self.is_2layer(): + # Index2Layer doesn't support search + xq = self.io.get_dataset(query_vectors) + xb = index.reconstruct_n(0, index.ntotal) + (D, I), t, _ = timer("knn_search 2layer", lambda: faiss.knn(xq, xb, k)) + elif self.is_ivf() and not isinstance(index, faiss.IndexRefine): + index_ivf = faiss.extract_index_ivf(index) + nprobe = ( + search_parameters["nprobe"] + if search_parameters is not None + and "nprobe" in search_parameters + else index_ivf.nprobe + ) xqt, QD, QI, QP = self.knn_search_quantizer( - index, query_vectors, search_parameters["nprobe"] + query_vectors=query_vectors, + k=nprobe, ) - index_ivf = faiss.extract_index_ivf(index) if index_ivf.parallel_mode != 2: logger.info("Setting IVF parallel mode") index_ivf.parallel_mode = 2 @@ -281,22 +321,23 @@ def knn_search( "knn_search_preassigned", lambda: index_ivf.search_preassigned(xqt, k, QI, QD), ) + # Dref, Iref = index.search(xq, k) + # np.testing.assert_array_equal(I, Iref) + # np.testing.assert_allclose(D, Dref) else: + xq = self.io.get_dataset(query_vectors) (D, I), t, _ = timer("knn_search", lambda: index.search(xq, k)) if self.is_flat() or not hasattr(self, "database_vectors"): # TODO R = D else: + xq = self.io.get_dataset(query_vectors) xb = self.io.get_dataset(self.database_vectors) - R = refine_distances_knn(D, I, xq, xb, self.metric_type) + R = refine_distances_knn(xq, xb, I, self.metric_type) P = { "time": t, - "index": self.get_index_name(), - "codec": self.get_codec_name(), - "factory": self.factory if hasattr(self, "factory") else "", - "search_params": search_parameters, "k": k, } - if self.is_ivf(): + if self.is_ivf() and not isinstance(index, faiss.IndexRefine): stats = faiss.cvar.indexIVF_stats P |= { "quantizer": QP, @@ -310,16 +351,113 @@ def knn_search( "search_time": int(stats.search_time // repeat), } self.io.write_file(filename, ["D", "I", "R", "P"], [D, I, R, P]) - logger.info("knn_seach: end") - return D, I, R, P + P |= { + "index": self.get_index_name(), + "codec": self.get_codec_name(), + "factory": self.get_model_name(), + "construction_params": self.get_construction_params(), + "search_params": search_parameters, + "knn_intersection": knn_intersection_measure( + I, I_gt, + ) if I_gt is not None else None, + "distance_ratio": distance_ratio_measure( + I, R, D_gt, self.metric_type, + ) if D_gt is not None else None, + } + logger.info("knn_search: end") + return D, I, R, P, None + + def reconstruct( + self, + dry_run, + parameters: Optional[Dict[str, int]], + query_vectors: DatasetDescriptor, + k: int, + I_gt, + ): + logger.info("reconstruct: begin") + filename = ( + self.get_knn_search_name(parameters, query_vectors, k, reconstruct=True) + + "zip" + ) + if self.io.file_exist(filename): + logger.info(f"Using cached results for {filename}") + P, = self.io.read_file(filename, ["P"]) + P["index"] = self.get_index_name() + P["codec"] = self.get_codec_name() + P["factory"] = self.get_model_name() + P["reconstruct_params"] = parameters + P["construction_params"] = self.get_construction_params() + else: + if dry_run: + return None, filename + codec = self.get_codec() + codec_meta = self.fetch_meta() + Index.set_index_param_dict(codec, parameters) + xb = self.io.get_dataset(self.database_vectors) + xb_encoded, encode_t, _ = timer("sa_encode", lambda: codec.sa_encode(xb)) + xq = self.io.get_dataset(query_vectors) + if self.is_decode_supported(): + xb_decoded, decode_t, _ = timer("sa_decode", lambda: codec.sa_decode(xb_encoded)) + mse = np.square(xb_decoded - xb).sum(axis=1).mean().item() + _, I = faiss.knn(xq, xb_decoded, k, metric=self.metric_type) + asym_recall = knn_intersection_measure(I, I_gt) + xq_decoded = codec.sa_decode(codec.sa_encode(xq)) + _, I = faiss.knn(xq_decoded, xb_decoded, k, metric=self.metric_type) + else: + mse = None + asym_recall = None + decode_t = None + # assume hamming for sym + xq_encoded = codec.sa_encode(xq) + bin = faiss.IndexBinaryFlat(xq_encoded.shape[1] * 8) + bin.add(xb_encoded) + _, I = bin.search(xq_encoded, k) + sym_recall = knn_intersection_measure(I, I_gt) + P = { + "encode_time": encode_t, + "decode_time": decode_t, + "mse": mse, + "sym_recall": sym_recall, + "asym_recall": asym_recall, + "cpu": get_cpu_info(), + "num_threads": self.num_threads, + "index": self.get_index_name(), + "codec": self.get_codec_name(), + "factory": self.get_model_name(), + "reconstruct_params": parameters, + "construction_params": self.get_construction_params(), + "codec_meta": codec_meta, + } + self.io.write_file(filename, ["P"], [P]) + logger.info("reconstruct: end") + return P, None + + def get_range_search_name( + self, + search_parameters: Optional[Dict[str, int]], + query_vectors: DatasetDescriptor, + radius: Optional[float] = None, + ): + name = self.get_index_name() + name += Index.param_dict_to_name(search_parameters) + name += query_vectors.get_filename("q") + if radius is not None: + name += f"r_{int(radius * 1000)}." + else: + name += "r_auto." + return name def range_search( self, + dry_run, search_parameters: Optional[Dict[str, int]], query_vectors: DatasetDescriptor, radius: Optional[float] = None, ): logger.info("range_search: begin") + if search_parameters is not None and search_parameters["snap"] == 1: + query_vectors = self.snap(query_vectors) filename = ( self.get_range_search_name( search_parameters, query_vectors, radius @@ -332,13 +470,15 @@ def range_search( filename, ["lims", "D", "I", "R", "P"] ) else: + if dry_run: + return None, None, None, None, None, filename xq = self.io.get_dataset(query_vectors) index = self.get_index() Index.set_index_param_dict(index, search_parameters) if self.is_ivf(): xqt, QD, QI, QP = self.knn_search_quantizer( - index, query_vectors, search_parameters["nprobe"] + query_vectors, search_parameters["nprobe"] ) index_ivf = faiss.extract_index_ivf(index) if index_ivf.parallel_mode != 2: @@ -364,9 +504,6 @@ def range_search( ) P = { "time": t, - "index": self.get_codec_name(), - "codec": self.get_codec_name(), - "search_params": search_parameters, "radius": radius, "count": len(I), } @@ -386,8 +523,15 @@ def range_search( self.io.write_file( filename, ["lims", "D", "I", "R", "P"], [lims, D, I, R, P] ) + P |= { + "index": self.get_index_name(), + "codec": self.get_codec_name(), + "factory": self.get_model_name(), + "construction_params": self.get_construction_params(), + "search_params": search_parameters, + } logger.info("range_seach: end") - return lims, D, I, R, P + return lims, D, I, R, P, None # Common base for IndexFromCodec and IndexFromFactory, @@ -396,16 +540,15 @@ def range_search( # they share the configuration of their parent IndexFromCodec @dataclass class Index(IndexBase): + num_threads: int d: int metric: str database_vectors: DatasetDescriptor construction_params: List[Dict[str, int]] search_params: Dict[str, int] - cached_codec_name: ClassVar[str] = None - cached_codec: ClassVar[faiss.Index] = None - cached_index_name: ClassVar[str] = None - cached_index: ClassVar[faiss.Index] = None + cached_codec: ClassVar[OrderedDict[str, faiss.Index]] = OrderedDict() + cached_index: ClassVar[OrderedDict[str, faiss.Index]] = OrderedDict() def __post_init__(self): if isinstance(self.metric, str): @@ -438,16 +581,13 @@ def supports_range_search(self): def fetch_codec(self): raise NotImplementedError - def train(self): - # get triggers a train, if necessary - self.get_codec() - def get_codec(self): codec_name = self.get_codec_name() - if Index.cached_codec_name != codec_name: - Index.cached_codec = self.fetch_codec() - Index.cached_codec_name = codec_name - return Index.cached_codec + if codec_name not in Index.cached_codec: + Index.cached_codec[codec_name], _, _ = self.fetch_codec() + if len(Index.cached_codec) > 1: + Index.cached_codec.popitem(last=False) + return Index.cached_codec[codec_name] def get_index_name(self): name = self.get_codec_name() @@ -456,14 +596,16 @@ def get_index_name(self): return name def fetch_index(self): - index = faiss.clone_index(self.get_codec()) + index = self.get_codec() + index.reset() assert index.ntotal == 0 logger.info("Adding vectors to index") xb = self.io.get_dataset(self.database_vectors) - if self.is_ivf(): + if self.is_ivf() and not isinstance(index, faiss.IndexRefine): xbt, QD, QI, QP = self.knn_search_quantizer( - index, self.database_vectors, 1 + query_vectors=self.database_vectors, + k=1, ) index_ivf = faiss.extract_index_ivf(index) if index_ivf.parallel_mode != 2: @@ -483,31 +625,43 @@ def fetch_index(self): ) assert index.ntotal == xb.shape[0] or index_ivf.ntotal == xb.shape[0] logger.info("Added vectors to index") - return index + return index, t def get_index(self): index_name = self.get_index_name() - if Index.cached_index_name != index_name: - Index.cached_index = self.fetch_index() - Index.cached_index_name = index_name - return Index.cached_index - - def get_code_size(self): - def get_index_code_size(index): - index = faiss.downcast_index(index) - if isinstance(index, faiss.IndexPreTransform): - return get_index_code_size(index.index) - elif isinstance(index, faiss.IndexHNSWFlat): - return index.d * 4 # TODO - elif type(index) in [faiss.IndexRefine, faiss.IndexRefineFlat]: - return get_index_code_size( - index.base_index - ) + get_index_code_size(index.refine_index) - else: - return index.code_size - - codec = self.get_codec() - return get_index_code_size(codec) + if index_name not in Index.cached_index: + Index.cached_index[index_name], _ = self.fetch_index() + if len(Index.cached_index) > 3: + Index.cached_index.popitem(last=False) + return Index.cached_index[index_name] + + def get_construction_params(self): + return self.construction_params + + # def get_code_size(self): + # def get_index_code_size(index): + # index = faiss.downcast_index(index) + # if isinstance(index, faiss.IndexPreTransform): + # return get_index_code_size(index.index) + # elif isinstance(index, faiss.IndexHNSWFlat): + # return index.d * 4 # TODO + # elif type(index) in [faiss.IndexRefine, faiss.IndexRefineFlat]: + # return get_index_code_size( + # index.base_index + # ) + get_index_code_size(index.refine_index) + # else: + # return index.code_size + + # codec = self.get_codec() + # return get_index_code_size(codec) + + def get_sa_code_size(self, codec=None): + if codec is None: + codec = self.get_codec() + try: + return codec.sa_code_size() + except: + return None def get_operating_points(self): op = OperatingPointsWithRanges() @@ -520,45 +674,70 @@ def add_range_or_val(name, range): else range, ) - op.add_range("noop", [0]) - codec = faiss.downcast_index(self.get_codec()) - codec_ivf = faiss.try_extract_index_ivf(codec) - if codec_ivf is not None: + add_range_or_val("snap", [0]) + model = self.get_model() + model_ivf = faiss.try_extract_index_ivf(model) + if model_ivf is not None: add_range_or_val( "nprobe", - [ + # [ + # 2**i + # for i in range(12) + # if 2**i <= model_ivf.nlist * 0.5 + # ], + [1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28] + [ + i + for i in range(32, 64, 8) + if i <= model_ivf.nlist * 0.1 + ] + [ + i + for i in range(64, 128, 16) + if i <= model_ivf.nlist * 0.1 + ] + [ + i + for i in range(128, 256, 32) + if i <= model_ivf.nlist * 0.1 + ] + [ + i + for i in range(256, 512, 64) + if i <= model_ivf.nlist * 0.1 + ] + [ 2**i - for i in range(12) - if 2**i <= codec_ivf.nlist * 0.25 + for i in range(9, 12) + if 2**i <= model_ivf.nlist * 0.1 ], ) - if isinstance(codec, faiss.IndexRefine): + model = faiss.downcast_index(model) + if isinstance(model, faiss.IndexRefine): add_range_or_val( "k_factor", - [2**i for i in range(11)], + [2**i for i in range(13)], ) - if isinstance(codec, faiss.IndexHNSWFlat): + elif isinstance(model, faiss.IndexHNSWFlat): add_range_or_val( "efSearch", [2**i for i in range(3, 11)], ) + elif isinstance(model, faiss.IndexResidualQuantizer) or isinstance(model, faiss.IndexProductResidualQuantizer): + add_range_or_val( + "max_beam_size", + [1, 2, 4, 8, 16, 32], + ) + add_range_or_val( + "use_beam_LUT", + [1], + ) + elif isinstance(model, faiss.IndexLocalSearchQuantizer) or isinstance(model, faiss.IndexProductLocalSearchQuantizer): + add_range_or_val( + "encode_ils_iters", + [2, 4, 8, 16], + ) + add_range_or_val( + "lsq_gpu", + [1], + ) return op - def get_range_search_name( - self, - search_parameters: Optional[Dict[str, int]], - query_vectors: DatasetDescriptor, - radius: Optional[float] = None, - ): - name = self.get_index_name() - name += Index.param_dict_to_name(search_parameters) - name += query_vectors.get_filename("q") - if radius is not None: - name += f"r_{int(radius * 1000)}." - else: - name += "r_auto." - return name - # IndexFromCodec, IndexFromQuantizer and IndexFromPreTransform # are used to wrap pre-trained Faiss indices (codecs) @@ -581,6 +760,9 @@ def get_pretransform(self): quantizer.set_io(self.io) return quantizer + def get_model_name(self): + return os.path.basename(self.path) + def get_codec_name(self): assert self.path is not None name = os.path.basename(self.path) @@ -596,7 +778,7 @@ def fetch_codec(self): assert self.d == codec.d assert self.metric_type == codec.metric_type Index.set_index_param_dict_list(codec, self.construction_params) - return codec + return codec, None, None def get_model(self): return self.get_codec() @@ -609,6 +791,9 @@ def __init__(self, ivf_index: Index): self.ivf_index = ivf_index super().__init__() + def get_model_name(self): + return self.get_index_name() + def get_codec_name(self): return self.get_index_name() @@ -657,17 +842,49 @@ def get_codec_name(self): name += Index.param_dict_list_to_name(self.construction_params) return name - def fetch_codec(self): + def fetch_meta(self, dry_run=False): + meta_filename = self.get_codec_name() + "json" + if self.io.file_exist(meta_filename): + meta = self.io.read_json(meta_filename) + report = None + else: + _, meta, report = self.fetch_codec(dry_run=dry_run) + return meta, report + + def fetch_codec(self, dry_run=False): codec_filename = self.get_codec_name() + "codec" - if self.io.file_exist(codec_filename): + meta_filename = self.get_codec_name() + "json" + if self.io.file_exist(codec_filename) and self.io.file_exist(meta_filename): codec = self.io.read_index(codec_filename) assert self.d == codec.d assert self.metric_type == codec.metric_type + meta = self.io.read_json(meta_filename) else: - codec = self.assemble() - if self.factory != "Flat": - self.io.write_index(codec, codec_filename) - return codec + codec, training_time, requires = self.assemble(dry_run=dry_run) + if requires is not None: + assert dry_run + if requires == "": + return None, None, codec_filename + else: + return None, None, requires + codec_size = self.io.write_index(codec, codec_filename) + assert codec_size is not None + meta = { + "training_time": training_time, + "training_size": self.training_vectors.num_vectors, + "codec_size": codec_size, + "sa_code_size": self.get_sa_code_size(codec), + "cpu": get_cpu_info(), + } + self.io.write_json(meta, meta_filename, overwrite=True) + + Index.set_index_param_dict_list( + codec, self.construction_params, assert_same=True + ) + return codec, meta, None + + def get_model_name(self): + return self.factory def get_model(self): model = faiss.index_factory(self.d, self.factory, self.metric_type) @@ -675,27 +892,27 @@ def get_model(self): return model def get_pretransform(self): - model = faiss.index_factory(self.d, self.factory, self.metric_type) + model = self.get_model() assert isinstance(model, faiss.IndexPreTransform) sub_index = faiss.downcast_index(model.index) if isinstance(sub_index, faiss.IndexFlat): return self # replace the sub-index with Flat - codec = faiss.clone_index(model) - codec.index = faiss.IndexFlat(codec.index.d, codec.index.metric_type) + model.index = faiss.IndexFlat(model.index.d, model.index.metric_type) pretransform = IndexFromFactory( - d=codec.d, - metric=codec.metric_type, + num_threads=self.num_threads, + d=model.d, + metric=model.metric_type, database_vectors=self.database_vectors, construction_params=self.construction_params, - search_params=self.search_params, - factory=reverse_index_factory(codec), + search_params=None, + factory=reverse_index_factory(model), training_vectors=self.training_vectors, ) pretransform.set_io(self.io) return pretransform - def get_quantizer(self, pretransform=None): + def get_quantizer(self, dry_run, pretransform=None): model = self.get_model() model_ivf = faiss.extract_index_ivf(model) assert isinstance(model_ivf, faiss.IndexIVF) @@ -704,82 +921,114 @@ def get_quantizer(self, pretransform=None): training_vectors = self.training_vectors else: training_vectors = pretransform.transform(self.training_vectors) - centroids = self.k_means(training_vectors, model_ivf.nlist) + centroids, t, requires = training_vectors.k_means(self.io, model_ivf.nlist, dry_run) + if requires is not None: + return None, None, requires quantizer = IndexFromFactory( + num_threads=self.num_threads, d=model_ivf.quantizer.d, metric=model_ivf.quantizer.metric_type, database_vectors=centroids, - construction_params=None, # self.construction_params[1:], - search_params=None, # self.construction_params[0], # TODO: verify + construction_params=self.construction_params[1:] + if self.construction_params is not None + else None, + search_params=None, factory=reverse_index_factory(model_ivf.quantizer), training_vectors=centroids, ) quantizer.set_io(self.io) - return quantizer + return quantizer, t, None - def k_means(self, vectors, k): - kmeans_vectors = DatasetDescriptor( - tablename=f"{vectors.get_filename()}kmeans_{k}.npy" - ) - if not self.io.file_exist(kmeans_vectors.tablename): - x = self.io.get_dataset(vectors) - kmeans = faiss.Kmeans(d=x.shape[1], k=k, gpu=True) - kmeans.train(x) - self.io.write_nparray(kmeans.centroids, kmeans_vectors.tablename) - return kmeans_vectors - - def assemble(self): + def assemble(self, dry_run): + logger.info(f"assemble {self.factory}") model = self.get_model() - codec = faiss.clone_index(model) - if isinstance(model, faiss.IndexPreTransform): - sub_index = faiss.downcast_index(model.index) - if not isinstance(sub_index, faiss.IndexFlat): - # replace the sub-index with Flat and fetch pre-trained - pretransform = self.get_pretransform() - codec = pretransform.fetch_codec() - assert codec.is_trained - transformed_training_vectors = pretransform.transform( - self.training_vectors - ) - transformed_database_vectors = pretransform.transform( - self.database_vectors - ) - # replace the Flat index with the required sub-index + opaque = True + t_aggregate = 0 + try: + reverse_index_factory(model) + opaque = False + except NotImplementedError: + opaque = True + if opaque: + codec = model + else: + if isinstance(model, faiss.IndexPreTransform): + logger.info(f"assemble: pretransform {self.factory}") + sub_index = faiss.downcast_index(model.index) + if not isinstance(sub_index, faiss.IndexFlat): + # replace the sub-index with Flat and fetch pre-trained + pretransform = self.get_pretransform() + codec, meta, report = pretransform.fetch_codec(dry_run=dry_run) + if report is not None: + return None, None, report + t_aggregate += meta["training_time"] + assert codec.is_trained + transformed_training_vectors = pretransform.transform( + self.training_vectors + ) + # replace the Flat index with the required sub-index + wrapper = IndexFromFactory( + num_threads=self.num_threads, + d=sub_index.d, + metric=sub_index.metric_type, + database_vectors=None, + construction_params=self.construction_params, + search_params=None, + factory=reverse_index_factory(sub_index), + training_vectors=transformed_training_vectors, + ) + wrapper.set_io(self.io) + codec.index, meta, report = wrapper.fetch_codec(dry_run=dry_run) + if report is not None: + return None, None, report + t_aggregate += meta["training_time"] + assert codec.index.is_trained + else: + codec = model + elif isinstance(model, faiss.IndexIVF): + logger.info(f"assemble: ivf {self.factory}") + # replace the quantizer + quantizer, t, requires = self.get_quantizer(dry_run=dry_run) + if requires is not None: + return None, None, requires + t_aggregate += t + codec = faiss.clone_index(model) + quantizer_index, t = quantizer.fetch_index() + t_aggregate += t + replace_ivf_quantizer(codec, quantizer_index) + assert codec.quantizer.is_trained + assert codec.nlist == codec.quantizer.ntotal + elif isinstance(model, faiss.IndexRefine) or isinstance( + model, faiss.IndexRefineFlat + ): + logger.info(f"assemble: refine {self.factory}") + # replace base_index wrapper = IndexFromFactory( - d=sub_index.d, - metric=sub_index.metric_type, - database_vectors=transformed_database_vectors, - construction_params=self.construction_params, - search_params=self.search_params, - factory=reverse_index_factory(sub_index), - training_vectors=transformed_training_vectors, + num_threads=self.num_threads, + d=model.base_index.d, + metric=model.base_index.metric_type, + database_vectors=self.database_vectors, + construction_params=IndexBase.filter_index_param_dict_list(self.construction_params), + search_params=None, + factory=reverse_index_factory(model.base_index), + training_vectors=self.training_vectors, ) wrapper.set_io(self.io) - codec.index = wrapper.fetch_codec() - assert codec.index.is_trained - elif isinstance(model, faiss.IndexIVF): - # replace the quantizer - quantizer = self.get_quantizer() - replace_ivf_quantizer(codec, quantizer.fetch_index()) - assert codec.quantizer.is_trained - assert codec.nlist == codec.quantizer.ntotal - elif isinstance(model, faiss.IndexRefine) or isinstance( - model, faiss.IndexRefineFlat - ): - # replace base_index - wrapper = IndexFromFactory( - d=model.base_index.d, - metric=model.base_index.metric_type, - database_vectors=self.database_vectors, - construction_params=self.construction_params, - search_params=self.search_params, - factory=reverse_index_factory(model.base_index), - training_vectors=self.training_vectors, - ) - wrapper.set_io(self.io) - codec.base_index = wrapper.fetch_codec() - assert codec.base_index.is_trained + codec = faiss.clone_index(model) + codec.base_index, meta, requires = wrapper.fetch_codec(dry_run=dry_run) + if requires is not None: + return None, None, requires + t_aggregate += meta["training_time"] + assert codec.base_index.is_trained + else: + codec = model - xt = self.io.get_dataset(self.training_vectors) - codec.train(xt) - return codec + if self.factory != "Flat": + if dry_run: + return None, None, "" + logger.info(f"assemble, train {self.factory}") + xt = self.io.get_dataset(self.training_vectors) + _, t, _ = timer("train", lambda: codec.train(xt), once=True) + t_aggregate += t + + return codec, t_aggregate, None diff --git a/benchs/bench_fw/utils.py b/benchs/bench_fw/utils.py new file mode 100644 index 0000000000..e1e513169b --- /dev/null +++ b/benchs/bench_fw/utils.py @@ -0,0 +1,107 @@ +# 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. + +from time import perf_counter +import logging +from multiprocessing.pool import ThreadPool +import numpy as np +import faiss # @manual=//faiss/python:pyfaiss_gpu +import functools + +logger = logging.getLogger(__name__) + +def timer(name, func, once=False) -> float: + logger.info(f"Measuring {name}") + t1 = perf_counter() + res = func() + t2 = perf_counter() + t = t2 - t1 + repeat = 1 + if not once and t < 1.0: + repeat = int(2.0 // t) + logger.info( + f"Time for {name}: {t:.3f} seconds, repeating {repeat} times" + ) + t1 = perf_counter() + for _ in range(repeat): + res = func() + t2 = perf_counter() + t = (t2 - t1) / repeat + logger.info(f"Time for {name}: {t:.3f} seconds") + return res, t, repeat + + +def refine_distances_knn( + xq: np.ndarray, xb: np.ndarray, I: np.ndarray, metric, +): + """ Recompute distances between xq[i] and xb[I[i, :]] """ + nq, k = I.shape + xq = np.ascontiguousarray(xq, dtype='float32') + nq2, d = xq.shape + xb = np.ascontiguousarray(xb, dtype='float32') + nb, d2 = xb.shape + I = np.ascontiguousarray(I, dtype='int64') + assert nq2 == nq + assert d2 == d + D = np.empty(I.shape, dtype='float32') + D[:] = np.inf + if metric == faiss.METRIC_L2: + faiss.fvec_L2sqr_by_idx( + faiss.swig_ptr(D), faiss.swig_ptr(xq), faiss.swig_ptr(xb), + faiss.swig_ptr(I), d, nq, k + ) + else: + faiss.fvec_inner_products_by_idx( + faiss.swig_ptr(D), faiss.swig_ptr(xq), faiss.swig_ptr(xb), + faiss.swig_ptr(I), d, nq, k + ) + return D + + +def refine_distances_range( + lims: np.ndarray, + D: np.ndarray, + I: np.ndarray, + xq: np.ndarray, + xb: np.ndarray, + metric, +): + with ThreadPool(32) as pool: + R = pool.map( + lambda i: ( + np.sum(np.square(xq[i] - xb[I[lims[i] : lims[i + 1]]]), axis=1) + if metric == faiss.METRIC_L2 + else np.tensordot( + xq[i], xb[I[lims[i] : lims[i + 1]]], axes=(0, 1) + ) + ) + if lims[i + 1] > lims[i] + else [], + range(len(lims) - 1), + ) + return np.hstack(R) + + +def distance_ratio_measure(I, R, D_GT, metric): + sum_of_R = np.sum(np.where(I >= 0, R, 0)) + sum_of_D_GT = np.sum(np.where(I >= 0, D_GT, 0)) + if metric == faiss.METRIC_INNER_PRODUCT: + return (sum_of_R / sum_of_D_GT).item() + elif metric == faiss.METRIC_L2: + return (sum_of_D_GT / sum_of_R).item() + else: + raise RuntimeError(f"unknown metric {metric}") + + +@functools.cache +def get_cpu_info(): + return [l for l in open("/proc/cpuinfo", "r") if "model name" in l][0][13:].strip() + +def dict_merge(target, source): + for k, v in source.items(): + if isinstance(v, dict) and k in target: + dict_merge(target[k], v) + else: + target[k] = v diff --git a/benchs/bench_fw_codecs.py b/benchs/bench_fw_codecs.py new file mode 100644 index 0000000000..80741e23f7 --- /dev/null +++ b/benchs/bench_fw_codecs.py @@ -0,0 +1,146 @@ +# 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 logging +import argparse +import os + +from bench_fw.benchmark import Benchmark +from bench_fw.benchmark_io import BenchmarkIO +from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor +from bench_fw.index import IndexFromFactory + +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=[ + IndexDescriptor( + 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=False, 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") diff --git a/benchs/bench_fw_ivf.py b/benchs/bench_fw_ivf.py new file mode 100644 index 0000000000..8c84743e27 --- /dev/null +++ b/benchs/bench_fw_ivf.py @@ -0,0 +1,120 @@ +# 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 logging +import argparse +import os + +from bench_fw.benchmark import Benchmark +from bench_fw.benchmark_io import BenchmarkIO +from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor + +logging.basicConfig(level=logging.INFO) + +def sift1M(bio): + benchmark = Benchmark( + num_threads=32, + training_vectors=DatasetDescriptor( + namespace="std_d", tablename="sift1M" + ), + database_vectors=DatasetDescriptor( + namespace="std_d", tablename="sift1M" + ), + query_vectors=DatasetDescriptor( + namespace="std_q", tablename="sift1M" + ), + index_descs=[ + IndexDescriptor( + factory=f"IVF{2 ** nlist},Flat", + ) + for nlist in range(8, 15) + ], + k=1, + distance_metric="L2", + ) + benchmark.set_io(bio) + benchmark.benchmark(result_file="result.json", local=False, train=True, reconstruct=False, knn=True, range=False) + +def bigann(bio): + for scale in [1, 2, 5, 10, 20, 50]: + benchmark = Benchmark( + num_threads=32, + training_vectors=DatasetDescriptor( + namespace="std_t", tablename="bigann1M" + ), + database_vectors=DatasetDescriptor( + namespace="std_d", tablename=f"bigann{scale}M" + ), + query_vectors=DatasetDescriptor( + namespace="std_q", tablename="bigann1M" + ), + index_descs=[ + IndexDescriptor( + factory=f"IVF{2 ** nlist},Flat", + ) for nlist in range(11, 19) + ] + [ + IndexDescriptor( + factory=f"IVF{2 ** nlist}_HNSW32,Flat", + construction_params=[None, {"efConstruction": 200, "efSearch": 40}], + ) for nlist in range(11, 19) + ], + k=1, + distance_metric="L2", + ) + benchmark.set_io(bio) + benchmark.benchmark(f"result{scale}.json", local=False, train=True, reconstruct=False, knn=True, range=False) + +def ssnpp(bio): + benchmark = Benchmark( + num_threads=32, + training_vectors=DatasetDescriptor( + tablename="ssnpp_training_5M.npy" + ), + database_vectors=DatasetDescriptor( + tablename="ssnpp_database_5M.npy" + ), + query_vectors=DatasetDescriptor( + tablename="ssnpp_queries_10K.npy" + ), + index_descs=[ + IndexDescriptor( + factory=f"IVF{2 ** nlist},PQ256x4fs,Refine(SQfp16)", + ) for nlist in range(9, 16) + ] + [ + IndexDescriptor( + factory=f"IVF{2 ** nlist},Flat", + ) for nlist in range(9, 16) + ] + [ + IndexDescriptor( + factory=f"PQ256x4fs,Refine(SQfp16)", + ), + IndexDescriptor( + factory=f"HNSW32", + ), + ], + k=1, + distance_metric="L2", + ) + benchmark.set_io(bio) + benchmark.benchmark("result.json", local=False, train=True, reconstruct=False, knn=True, range=False) + +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": + sift1M(bio) + elif args.experiment == "bigann": + bigann(bio) + elif args.experiment == "ssnpp": + ssnpp(bio) diff --git a/benchs/bench_fw_ivf_flat.py b/benchs/bench_fw_ivf_flat.py deleted file mode 100644 index 37b4bd7862..0000000000 --- a/benchs/bench_fw_ivf_flat.py +++ /dev/null @@ -1,37 +0,0 @@ -# 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 logging - -from bench_fw.benchmark import Benchmark -from bench_fw.benchmark_io import BenchmarkIO -from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor - -logging.basicConfig(level=logging.INFO) - -benchmark = Benchmark( - training_vectors=DatasetDescriptor( - namespace="std_d", tablename="sift1M" - ), - database_vectors=DatasetDescriptor( - namespace="std_d", tablename="sift1M" - ), - query_vectors=DatasetDescriptor( - namespace="std_q", tablename="sift1M" - ), - index_descs=[ - IndexDescriptor( - factory=f"IVF{2 ** nlist},Flat", - ) - for nlist in range(8, 15) - ], - k=1, - distance_metric="L2", -) -io = BenchmarkIO( - path="/checkpoint", -) -benchmark.set_io(io) -print(benchmark.benchmark("result.json")) diff --git a/benchs/bench_fw_notebook.ipynb b/benchs/bench_fw_notebook.ipynb index 7cc39ea2cb..c6183a8eb9 100644 --- a/benchs/bench_fw_notebook.ipynb +++ b/benchs/bench_fw_notebook.ipynb @@ -4,24 +4,35 @@ "cell_type": "code", "execution_count": null, "id": "be081589-e1b2-4569-acb7-44203e273899", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import itertools\n", "from faiss.contrib.evaluation import OperatingPoints\n", "from enum import Enum\n", - "from bench_fw.benchmark_io import BenchmarkIO as BIO" + "from bench_fw.benchmark_io import BenchmarkIO as BIO\n", + "from copy import copy\n", + "import numpy as np\n", + "import datetime\n", + "import glob\n", + "import io\n", + "import json\n", + "from zipfile import ZipFile" ] }, { "cell_type": "code", "execution_count": null, "id": "a6492e95-24c7-4425-bf0a-27e10e879ca6", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "root = \"/checkpoint\"\n", + "root = \"/checkpoint/gsz/bench_fw/range/ssnpp\"\n", "results = BIO(root).read_json(\"result.json\")\n", "results.keys()" ] @@ -30,17 +41,21 @@ "cell_type": "code", "execution_count": null, "id": "0875d269-aef4-426d-83dd-866970f43777", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "results['indices']" + "results['experiments']" ] }, { "cell_type": "code", "execution_count": null, "id": "a7ff7078-29c7-407c-a079-201877b764ad", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "class Cost:\n", @@ -89,7 +104,7 @@ " time_metric = lambda v: v['time'] * scaling_factor + (v['quantizer']['time'] if 'quantizer' in v else 0)\n", "\n", " if space_metric is None:\n", - " space_metric = lambda v: results['indices'][v['codec']]['code_size']\n", + " space_metric = lambda v: results['indices'][v['codec']]['sa_code_size']\n", " \n", " fe = []\n", " ops = {}\n", @@ -102,12 +117,16 @@ " if min_accuracy > 0 and accuracy < min_accuracy:\n", " continue\n", " space = space_metric(v)\n", + " if space is None:\n", + " space = 0 \n", " if max_space > 0 and space > max_space:\n", " continue\n", " time = time_metric(v)\n", " if max_time > 0 and time > max_time:\n", " continue\n", - " idx_name = v['index']\n", + " idx_name = v['index'] + (\"snap\" if 'search_params' in v and v['search_params'][\"snap\"] == 1 else \"\")\n", + " # if idx_name.startswith(\"HNSW\"):\n", + " # continue\n", " experiment = (accuracy, space, time, k, v)\n", " if pareto_mode == ParetoMode.DISABLE:\n", " fe.append(experiment)\n", @@ -136,14 +155,18 @@ "cell_type": "code", "execution_count": null, "id": "f080a6e2-1565-418b-8732-4adeff03a099", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "def plot_metric(experiments, accuracy_title, cost_title, plot_space=False):\n", + "def plot_metric(experiments, accuracy_title, cost_title, plot_space=False, plot=None):\n", + " if plot is None:\n", + " plot = plt.subplot()\n", " x = {}\n", " y = {}\n", " for accuracy, space, time, k, v in experiments:\n", - " idx_name = v['index']\n", + " idx_name = v['index'] + (\"snap\" if 'search_params' in v and v['search_params'][\"snap\"] == 1 else \"\")\n", " if idx_name not in x:\n", " x[idx_name] = []\n", " y[idx_name] = []\n", @@ -154,26 +177,43 @@ " y[idx_name].append(time)\n", "\n", " #plt.figure(figsize=(10,6))\n", - " plt.yscale(\"log\")\n", - " plt.title(accuracy_title)\n", - " plt.xlabel(accuracy_title)\n", - " plt.ylabel(cost_title)\n", + " #plt.title(accuracy_title)\n", + " plot.set_xlabel(accuracy_title)\n", + " plot.set_ylabel(cost_title)\n", " marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", " for index in x.keys():\n", - " plt.plot(x[index], y[index], marker=next(marker), label=index)\n", - " plt.legend(bbox_to_anchor=(1, 1), loc='upper left')" + " plot.plot(x[index], y[index], marker=next(marker), label=index, linewidth=0)\n", + " plot.legend(bbox_to_anchor=(1, 1), loc='upper left')" ] }, { "cell_type": "code", "execution_count": null, "id": "61007155-5edc-449e-835e-c141a01a2ae5", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ + "# index local optima\n", "accuracy_metric = \"knn_intersection\"\n", "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 16 cores)\")" + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\", plot_space=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9f94dcc-5abe-4cad-9619-f5d1d24fb8c1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# global optima\n", + "accuracy_metric = \"knn_intersection\"\n", + "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.5, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\")" ] }, { @@ -183,6 +223,7 @@ "metadata": {}, "outputs": [], "source": [ + "# index local optima @ precision 0.8\n", "precision = 0.8\n", "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", @@ -196,7 +237,7 @@ "metadata": {}, "outputs": [], "source": [ - "# index local optima\n", + "# index local optima @ precision 0.2\n", "precision = 0.2\n", "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", @@ -210,7 +251,7 @@ "metadata": {}, "outputs": [], "source": [ - "# global optima\n", + "# global optima @ precision 0.8\n", "precision = 0.8\n", "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", @@ -260,6 +301,293 @@ "cell_type": "code", "execution_count": null, "id": "fdf8148a-0da6-4c5e-8d60-f8f85314574c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", + "fig.tight_layout()\n", + "for plot, scale in zip(plots, scales, strict=True):\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e503828c-ee61-45f7-814b-cce6461109bc", + "metadata": {}, + "outputs": [], + "source": [ + "x = {}\n", + "y = {}\n", + "accuracy=0.9\n", + "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "#fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", + "#fig.tight_layout()\n", + "for scale in scales:\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " scale *= 1_000_000\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=accuracy, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " seen = set()\n", + " print(scale)\n", + " for _, _, _, _, exp in fr:\n", + " fact = exp[\"factory\"]\n", + " # \"HNSW\" in fact or \n", + " if fact in seen or fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", + " continue\n", + " seen.add(fact)\n", + " if fact not in x:\n", + " x[fact] = []\n", + " y[fact] = []\n", + " x[fact].append(scale)\n", + " y[fact].append(exp[\"time\"] + exp[\"quantizer\"][\"time\"])\n", + " if (exp[\"knn_intersection\"] > 0.92):\n", + " print(fact)\n", + " print(exp[\"search_params\"])\n", + " print(exp[\"knn_intersection\"])\n", + "\n", + " #plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)\n", + " \n", + "plt.title(f\"recall @ 1 = {accuracy*100}%\")\n", + "plt.xlabel(\"database size\")\n", + "plt.ylabel(\"time\")\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", + "\n", + "marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", + "for index in x.keys():\n", + " if \"HNSW\" in index:\n", + " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker), linestyle=\"dashed\")\n", + " else:\n", + " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker))\n", + "plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper left')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37a99bb2-f998-461b-a345-7cc6e702cb3a", + "metadata": {}, + "outputs": [], + "source": [ + "# global optima\n", + "accuracy_metric = \"sym_recall\"\n", + "fr = filter_results(results, evaluation=\"rec\", accuracy_metric=accuracy_metric, time_metric=lambda e:e['encode_time'], min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.SPACE, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"space\", plot_space=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c973ce4e-3566-4f02-bd93-f113e3e0c791", + "metadata": {}, + "outputs": [], + "source": [ + "def pretty_time(s):\n", + " if s is None:\n", + " return \"None\"\n", + " s = int(s * 1000) / 1000\n", + " m, s = divmod(s, 60)\n", + " h, m = divmod(m, 60)\n", + " d, h = divmod(h, 24)\n", + " r = \"\"\n", + " if d > 0:\n", + " r += f\"{int(d)}d \"\n", + " if h > 0:\n", + " r += f\"{int(h)}h \"\n", + " if m > 0:\n", + " r += f\"{int(m)}m \"\n", + " if s > 0 or len(r) == 0:\n", + " r += f\"{s:.3f}s\"\n", + " return r\n", + "\n", + "def pretty_size(s):\n", + " if s > 1024 * 1024:\n", + " return f\"{s / 1024 / 1024:.1f}\".rstrip('0').rstrip('.') + \"MB\"\n", + " if s > 1024:\n", + " return f\"{s / 1024:.1f}\".rstrip('0').rstrip('.') + \"KB\"\n", + " return f\"{s}\"\n", + "\n", + "def pretty_mse(m):\n", + " if m is None:\n", + " return \"None\"\n", + " else:\n", + " return f\"{m:.6f}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ddcf226-fb97-4a59-9fc3-3ed8f7d5e703", + "metadata": {}, + "outputs": [], + "source": [ + "data = {}\n", + "root = \"/checkpoint/gsz/bench_fw/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "for scale in scales:\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " d = {}\n", + " data[f\"{scale}M\"] = d\n", + " for _, _, _, _, exp in fr:\n", + " fact = exp[\"factory\"]\n", + " # \"HNSW\" in fact or \n", + " if fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", + " continue\n", + " if fact not in d:\n", + " d[fact] = []\n", + " d[fact].append({\n", + " \"nprobe\": exp[\"search_params\"][\"nprobe\"],\n", + " \"recall\": exp[\"knn_intersection\"],\n", + " \"time\": exp[\"time\"] + exp[\"quantizer\"][\"time\"],\n", + " })\n", + "data\n", + "# with open(\"/checkpoint/gsz/bench_fw/codecs.json\", \"w\") as f:\n", + "# json.dump(data, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e54eebb6-0a9f-4a72-84d2-f12c5bd44510", + "metadata": {}, + "outputs": [], + "source": [ + "ds = \"deep1b\"\n", + "data = []\n", + "jss = []\n", + "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", + "results = BIO(root).read_json(f\"result.json\")\n", + "for k, e in results[\"experiments\"].items():\n", + " if \"rec\" in k and e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", + " code_size = results['indices'][e['codec']]['sa_code_size']\n", + " codec_size = results['indices'][e['codec']]['codec_size']\n", + " training_time = results['indices'][e['codec']]['training_time']\n", + " # training_size = results['indices'][e['codec']]['training_size']\n", + " cpu = e['cpu'] if 'cpu' in e else \"\"\n", + " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", + " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", + " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{training_size}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", + " jss.append({\n", + " 'factory': e['factory'],\n", + " 'parameters': e['construction_params'][0] if e['construction_params'] else \"\",\n", + " 'evaluation_params': e['reconstruct_params'],\n", + " 'code_size': code_size,\n", + " 'codec_size': codec_size,\n", + " 'training_time': training_time,\n", + " 'training_size': training_size,\n", + " 'mse': e['mse'],\n", + " 'sym_recall': e['sym_recall'],\n", + " 'asym_recall': e['asym_recall'],\n", + " 'encode_time': e['encode_time'],\n", + " 'decode_time': e['decode_time'],\n", + " 'cpu': cpu,\n", + " })\n", + "\n", + "print(\"|factory key|construction parameters|evaluation parameters|code size|codec size|training time|training size|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", + "print(\"|-|-|-|-|-|-|-|-|-|\")\n", + "data.sort()\n", + "for d in data:\n", + " print(d[1])\n", + "\n", + "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_test.json\", \"w\") as f:\n", + " json.dump(jss, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d1216733-9670-407c-b3d2-5f87bce0321c", + "metadata": {}, + "outputs": [], + "source": [ + "def read_file(filename: str, keys):\n", + " results = []\n", + " with ZipFile(filename, \"r\") as zip_file:\n", + " for key in keys:\n", + " with zip_file.open(key, \"r\") as f:\n", + " if key in [\"D\", \"I\", \"R\", \"lims\"]:\n", + " results.append(np.load(f))\n", + " elif key in [\"P\"]:\n", + " t = io.TextIOWrapper(f)\n", + " results.append(json.load(t))\n", + " else:\n", + " raise AssertionError()\n", + " return results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56de051e-22db-4bef-b242-1ddabc9e0bb9", + "metadata": {}, + "outputs": [], + "source": [ + "ds = \"contriever\"\n", + "data = []\n", + "jss = []\n", + "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", + "for lf in glob.glob(root + '/*rec*.zip'):\n", + " e, = read_file(lf, ['P'])\n", + " if e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", + " code_size = e['codec_meta']['sa_code_size']\n", + " codec_size = e['codec_meta']['codec_size']\n", + " training_time = e['codec_meta']['training_time']\n", + " training_size = None # e['codec_meta']['training_size']\n", + " cpu = e['cpu'] if 'cpu' in e else \"\"\n", + " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", + " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", + " if eps in ps and eps != \"encode_ils_iters=16\" and eps != \"max_beam_size=32\":\n", + " eps = \" \"\n", + " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", + " eps = e['reconstruct_params']\n", + " del eps['snap']\n", + " params = copy(e['construction_params'][0]) if e['construction_params'] else {}\n", + " for k, v in e['reconstruct_params'].items():\n", + " params[k] = v\n", + " jss.append({\n", + " 'factory': e['factory'],\n", + " 'params': params,\n", + " 'construction_params': e['construction_params'][0] if e['construction_params'] else {},\n", + " 'evaluation_params': e['reconstruct_params'],\n", + " 'code_size': code_size,\n", + " 'codec_size': codec_size,\n", + " 'training_time': training_time,\n", + " # 'training_size': training_size,\n", + " 'mse': e['mse'],\n", + " 'sym_recall': e['sym_recall'],\n", + " 'asym_recall': e['asym_recall'],\n", + " 'encode_time': e['encode_time'],\n", + " 'decode_time': e['decode_time'],\n", + " 'cpu': cpu,\n", + " })\n", + "\n", + "print(\"|factory key|construction parameters|encode/decode parameters|code size|codec size|training time|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", + "print(\"|-|-|-|-|-|-|-|-|-|\")\n", + "data.sort()\n", + "# for d in data:\n", + "# print(d[1])\n", + "\n", + "print(len(data))\n", + "\n", + "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_5.json\", \"w\") as f:\n", + " json.dump(jss, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fd712bf-f147-4c1b-9dbf-b04428e4c1eb", "metadata": {}, "outputs": [], "source": [] @@ -267,9 +595,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python [conda env:faiss_cpu_from_source] *", + "display_name": "Python [conda env:.conda-faiss_from_source] *", "language": "python", - "name": "conda-env-faiss_cpu_from_source-py" + "name": "conda-env-.conda-faiss_from_source-py" }, "language_info": { "codemirror_mode": { diff --git a/benchs/bench_fw_range.py b/benchs/bench_fw_range.py new file mode 100644 index 0000000000..f38de114f9 --- /dev/null +++ b/benchs/bench_fw_range.py @@ -0,0 +1,83 @@ +# 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 logging +import argparse +import os + +from bench_fw.benchmark import Benchmark +from bench_fw.benchmark_io import BenchmarkIO +from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor + +logging.basicConfig(level=logging.INFO) + +def ssnpp(bio): + benchmark = Benchmark( + num_threads=32, + training_vectors=DatasetDescriptor( + tablename="ssnpp_training_5M.npy", + ), + database_vectors=DatasetDescriptor( + tablename="ssnpp_xb_range_filtered_119201.npy", + ), + query_vectors=DatasetDescriptor(tablename="ssnpp_xq_range_filtered_33615.npy"), + index_descs=[ + IndexDescriptor( + factory="Flat", + range_metrics={ + "weighted": [ + [0.05, 0.971], + [0.1, 0.956], + [0.15, 0.923], + [0.2, 0.887], + [0.25, 0.801], + [0.3, 0.729], + [0.35, 0.651], + [0.4, 0.55], + [0.45, 0.459], + [0.5, 0.372], + [0.55, 0.283], + [0.6, 0.189], + [0.65, 0.143], + [0.7, 0.106], + [0.75, 0.116], + [0.8, 0.088], + [0.85, 0.064], + [0.9, 0.05], + [0.95, 0.04], + [1.0, 0.028], + [1.05, 0.02], + [1.1, 0.013], + [1.15, 0.007], + [1.2, 0.004], + [1.3, 0], + ] + }, + ), + IndexDescriptor( + factory="IVF262144(PQ256x4fs),PQ32", + ), + ], + k=10, + distance_metric="L2", + range_ref_index_desc="Flat", + ) + benchmark.set_io(bio) + benchmark.benchmark("result.json", local=False, train=True, reconstruct=False, knn=False, range=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 == "ssnpp": + ssnpp(bio) diff --git a/benchs/bench_fw_test.py b/benchs/bench_fw_test.py deleted file mode 100644 index 55b9e16e65..0000000000 --- a/benchs/bench_fw_test.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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 logging - -from bench_fw.benchmark import Benchmark -from bench_fw.benchmark_io import BenchmarkIO -from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor - -logging.basicConfig(level=logging.INFO) - -benchmark = Benchmark( - training_vectors=DatasetDescriptor( - tablename="training.npy", num_vectors=200000 - ), - database_vectors=DatasetDescriptor( - tablename="database.npy", num_vectors=200000 - ), - query_vectors=DatasetDescriptor(tablename="query.npy", num_vectors=2000), - index_descs=[ - IndexDescriptor( - factory="Flat", - range_metrics={ - "weighted": [ - [0.1, 0.928], - [0.2, 0.865], - [0.3, 0.788], - [0.4, 0.689], - [0.5, 0.49], - [0.6, 0.308], - [0.7, 0.193], - [0.8, 0.0], - ] - }, - ), - IndexDescriptor( - factory="OPQ32_128,IVF512,PQ32", - ), - IndexDescriptor( - factory="OPQ32_256,IVF512,PQ32", - ), - IndexDescriptor( - factory="HNSW32", - construction_params=[ - { - "efConstruction": 64, - } - ], - ), - ], - k=10, - distance_metric="L2", - range_ref_index_desc="Flat", -) -io = BenchmarkIO( - path="/checkpoint", -) -benchmark.set_io(io) -print(benchmark.benchmark("result.json")) diff --git a/contrib/factory_tools.py b/contrib/factory_tools.py index da90e986f8..745dc7f7ff 100644 --- a/contrib/factory_tools.py +++ b/contrib/factory_tools.py @@ -101,12 +101,23 @@ def reverse_index_factory(index): return prefix + ",SQ8" if isinstance(index, faiss.IndexIVFPQ): return prefix + f",PQ{index.pq.M}x{index.pq.nbits}" + if isinstance(index, faiss.IndexIVFPQFastScan): + return prefix + f",PQ{index.pq.M}x{index.pq.nbits}fs" elif isinstance(index, faiss.IndexPreTransform): - assert index.chain.size() == 1 + if index.chain.size() != 1: + raise NotImplementedError() vt = faiss.downcast_VectorTransform(index.chain.at(0)) if isinstance(vt, faiss.OPQMatrix): - return f"OPQ{vt.M}_{vt.d_out},{reverse_index_factory(index.index)}" + prefix = f"OPQ{vt.M}_{vt.d_out}" + elif isinstance(vt, faiss.ITQTransform): + prefix = f"ITQ{vt.itq.d_out}" + elif isinstance(vt, faiss.PCAMatrix): + assert vt.eigen_power == 0 + prefix = "PCA" + ("R" if vt.random_rotation else "") + str(vt.d_out) + else: + raise NotImplementedError() + return f"{prefix},{reverse_index_factory(index.index)}" elif isinstance(index, faiss.IndexHNSW): return f"HNSW{get_hnsw_M(index)}" @@ -117,6 +128,12 @@ def reverse_index_factory(index): elif isinstance(index, faiss.IndexPQFastScan): return f"PQ{index.pq.M}x{index.pq.nbits}fs" + elif isinstance(index, faiss.IndexPQ): + return f"PQ{index.pq.M}x{index.pq.nbits}" + + elif isinstance(index, faiss.IndexLSH): + return "LSH" + ("r" if index.rotate_data else "") + ("t" if index.train_thresholds else "") + elif isinstance(index, faiss.IndexScalarQuantizer): sqtypes = { faiss.ScalarQuantizer.QT_8bit: "8", From db09984c7d1a81b2620e4b34fe50876e8f38f75a Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 7 Jan 2024 20:53:05 -0800 Subject: [PATCH 011/206] Fix shadowed variable in faiss/impl/simd_result_handlers.h Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: dmm-fb Differential Revision: D52582819 fbshipit-source-id: 34c4d5eca31bcc2df5872c9eb3a286335c8ae131 --- faiss/impl/simd_result_handlers.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/faiss/impl/simd_result_handlers.h b/faiss/impl/simd_result_handlers.h index f2b302b3d3..94a2541e03 100644 --- a/faiss/impl/simd_result_handlers.h +++ b/faiss/impl/simd_result_handlers.h @@ -61,9 +61,9 @@ struct StoreResultHandler { d1.store(data + ofs + 16); } - void set_block_origin(size_t i0, size_t j0) { - this->i0 = i0; - this->j0 = j0; + void set_block_origin(size_t i0_2, size_t j0_2) { + this->i0 = i0_2; + this->j0 = j0_2; } }; @@ -78,8 +78,8 @@ struct FixedStorageHandler { dis[q + i0][2 * b + 1] = d1; } - void set_block_origin(size_t i0, size_t j0) { - this->i0 = i0; + void set_block_origin(size_t i0_2, size_t j0) { + this->i0 = i0_2; assert(j0 == 0); } @@ -112,9 +112,9 @@ struct SIMDResultHandler { explicit SIMDResultHandler(size_t ntotal) : ntotal(ntotal), id_map(nullptr), q_map(nullptr), dbias(nullptr) {} - void set_block_origin(size_t i0, size_t j0) { - this->i0 = i0; - this->j0 = j0; + void set_block_origin(size_t i0_2, size_t j0_2) { + this->i0 = i0_2; + this->j0 = j0_2; } // adjust handler data for IVF. From 952941ba3f263937895bbc0a9a66bd894e5ccae9 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 9 Jan 2024 08:17:54 -0800 Subject: [PATCH 012/206] Fix shadowed variable in faiss/MatrixStats.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52582890 fbshipit-source-id: ef7e44805fb212c6415030b98f65c00b2fd4a9b7 --- faiss/MatrixStats.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/faiss/MatrixStats.cpp b/faiss/MatrixStats.cpp index cc87e1797c..f2f9a431e5 100644 --- a/faiss/MatrixStats.cpp +++ b/faiss/MatrixStats.cpp @@ -181,12 +181,12 @@ MatrixStats::MatrixStats(size_t n, size_t d, const float* x) : n(n), d(d) { double max_std = 0, min_std = HUGE_VAL; - size_t n_dangerous_range = 0, n_0_range = 0, n0 = 0; + size_t n_dangerous_range = 0, n_0_range = 0, n0_2 = 0; for (size_t j = 0; j < d; j++) { PerDimStats& st = per_dim_stats[j]; st.compute_mean_std(); - n0 += st.n0; + n0_2 += st.n0; if (st.max == st.min) { n_0_range++; @@ -200,12 +200,12 @@ MatrixStats::MatrixStats(size_t n, size_t d, const float* x) : n(n), d(d) { min_std = st.stddev; } - if (n0 == 0) { + if (n0_2 == 0) { do_comment("matrix contains no 0s\n"); } else { do_comment( "matrix contains %.2f %% 0 entries\n", - n0 * 100.0 / (n * d)); + n0_2 * 100.0 / (n * d)); } if (n_0_range == 0) { From c399b110a028e01180272e68f851ef34ad2ef50a Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 9 Jan 2024 08:26:20 -0800 Subject: [PATCH 013/206] Fix shadowed variable in faiss/utils/hamming.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52582797 fbshipit-source-id: 4ade95834fee68a4ac86b4d03a00df0760941f4e --- faiss/utils/hamming.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/faiss/utils/hamming.cpp b/faiss/utils/hamming.cpp index 14b84f7ab6..79e10a4f01 100644 --- a/faiss/utils/hamming.cpp +++ b/faiss/utils/hamming.cpp @@ -271,10 +271,10 @@ void hammings_knn_mc( HCounterState& csi = cs[i]; int nres = 0; - for (int b = 0; b < nBuckets && nres < k; b++) { - for (int l = 0; l < csi.counters[b] && nres < k; l++) { - labels[i * k + nres] = csi.ids_per_dis[b * k + l]; - distances[i * k + nres] = b; + for (int b_2 = 0; b_2 < nBuckets && nres < k; b_2++) { + for (int l = 0; l < csi.counters[b_2] && nres < k; l++) { + labels[i * k + nres] = csi.ids_per_dis[b_2 * k + l]; + distances[i * k + nres] = b_2; nres++; } } From 42b62163ca46837d28edb4c7a3b947dfea831d95 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 9 Jan 2024 08:27:25 -0800 Subject: [PATCH 014/206] Fix shadowed variable in faiss/impl/ScalarQuantizer.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52582823 fbshipit-source-id: 575c286c0445e2388038aac10327d6c1bd63d6df --- faiss/impl/ScalarQuantizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/impl/ScalarQuantizer.cpp b/faiss/impl/ScalarQuantizer.cpp index b6fc6183d9..fc7b28eff4 100644 --- a/faiss/impl/ScalarQuantizer.cpp +++ b/faiss/impl/ScalarQuantizer.cpp @@ -710,8 +710,8 @@ struct SimilarityL2<8> { accu8 = _mm256_fmadd_ps(tmp, tmp, accu8); } - FAISS_ALWAYS_INLINE void add_8_components_2(__m256 x, __m256 y) { - __m256 tmp = _mm256_sub_ps(y, x); + FAISS_ALWAYS_INLINE void add_8_components_2(__m256 x, __m256 y_2) { + __m256 tmp = _mm256_sub_ps(y_2, x); accu8 = _mm256_fmadd_ps(tmp, tmp, accu8); } From 0710cbd48a1a9a5ef7811080f6a280c661f0bf68 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 9 Jan 2024 08:30:59 -0800 Subject: [PATCH 015/206] Fix shadowed variable in faiss/impl/ResultHandler.h Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52582910 fbshipit-source-id: 92ee06e819f15c411a3fee75a6c9e17fba96a7f3 --- faiss/impl/ResultHandler.h | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/faiss/impl/ResultHandler.h b/faiss/impl/ResultHandler.h index 53ed520826..c6f731de91 100644 --- a/faiss/impl/ResultHandler.h +++ b/faiss/impl/ResultHandler.h @@ -82,10 +82,10 @@ struct HeapResultHandler { size_t i0, i1; /// begin - void begin_multiple(size_t i0, size_t i1) { - this->i0 = i0; - this->i1 = i1; - for (size_t i = i0; i < i1; i++) { + void begin_multiple(size_t i0_2, size_t i1_2) { + this->i0 = i0_2; + this->i1 = i1_2; + for (size_t i = i0_2; i < i1_2; i++) { heap_heapify(k, heap_dis_tab + i * k, heap_ids_tab + i * k); } } @@ -231,13 +231,13 @@ struct ReservoirResultHandler { size_t i; /// begin results for query # i - void begin(size_t i) { + void begin(size_t i_2) { res1 = ReservoirTopN( hr.k, hr.capacity, reservoir_dis.data(), reservoir_ids.data()); - this->i = i; + this->i = i_2; } /// add one result for query i @@ -264,18 +264,18 @@ struct ReservoirResultHandler { std::vector> reservoirs; /// begin - void begin_multiple(size_t i0, size_t i1) { - this->i0 = i0; - this->i1 = i1; - reservoir_dis.resize((i1 - i0) * capacity); - reservoir_ids.resize((i1 - i0) * capacity); + void begin_multiple(size_t i0_2, size_t i1_2) { + this->i0 = i0_2; + this->i1 = i1_2; + reservoir_dis.resize((i1_2 - i0_2) * capacity); + reservoir_ids.resize((i1_2 - i0_2) * capacity); reservoirs.clear(); - for (size_t i = i0; i < i1; i++) { + for (size_t i = i0_2; i < i1_2; i++) { reservoirs.emplace_back( k, capacity, - reservoir_dis.data() + (i - i0) * capacity, - reservoir_ids.data() + (i - i0) * capacity); + reservoir_dis.data() + (i - i0_2) * capacity, + reservoir_ids.data() + (i - i0_2) * capacity); } } @@ -363,9 +363,9 @@ struct RangeSearchResultHandler { int pr = 0; /// begin - void begin_multiple(size_t i0, size_t i1) { - this->i0 = i0; - this->i1 = i1; + void begin_multiple(size_t i0_2, size_t i1_2) { + this->i0 = i0_2; + this->i1 = i1_2; } /// add results for query i0..i1 and j0..j1 @@ -443,8 +443,8 @@ struct SingleBestResultHandler { SingleResultHandler(SingleBestResultHandler& hr) : hr(hr) {} /// begin results for query # i - void begin(const size_t current_idx) { - this->current_idx = current_idx; + void begin(const size_t current_idx_2) { + this->current_idx = current_idx_2; min_dis = HUGE_VALF; min_idx = -1; } @@ -467,19 +467,19 @@ struct SingleBestResultHandler { size_t i0, i1; /// begin - void begin_multiple(size_t i0, size_t i1) { - this->i0 = i0; - this->i1 = i1; + void begin_multiple(size_t i0_2, size_t i1_2) { + this->i0 = i0_2; + this->i1 = i1_2; - for (size_t i = i0; i < i1; i++) { + for (size_t i = i0_2; i < i1_2; i++) { this->dis_tab[i] = HUGE_VALF; } } /// add results for query i0..i1 and j0..j1 - void add_results(size_t j0, size_t j1, const T* dis_tab) { + void add_results(size_t j0, size_t j1, const T* dis_tab_2) { for (int64_t i = i0; i < i1; i++) { - const T* dis_tab_i = dis_tab + (j1 - j0) * (i - i0) - j0; + const T* dis_tab_i = dis_tab_2 + (j1 - j0) * (i - i0) - j0; auto& min_distance = this->dis_tab[i]; auto& min_index = this->ids_tab[i]; From 0013c702f47bedbf6159ac356e61f378ccd12ac8 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 11 Jan 2024 08:26:33 -0800 Subject: [PATCH 016/206] avx512 CI + conda packages (#3197) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3197 Reviewed By: mlomeli1 Differential Revision: D52689379 Pulled By: algoriddle fbshipit-source-id: 54e27c6d310d6da14777ae10ae62f46e7076cacf --- .circleci/config.yml | 4 ++++ .gitignore | 1 + conda/faiss-gpu-raft/build-lib.sh | 6 +++--- conda/faiss-gpu-raft/build-pkg.sh | 6 +++--- conda/faiss-gpu-raft/test_cpu_dispatch.sh | 5 +++-- conda/faiss-gpu/build-lib.sh | 6 +++--- conda/faiss-gpu/build-pkg.sh | 6 +++--- conda/faiss-gpu/test_cpu_dispatch.sh | 5 +++-- conda/faiss/build-lib-osx.sh | 6 +++--- conda/faiss/build-lib.sh | 6 +++--- conda/faiss/build-pkg-arm64.sh | 2 +- conda/faiss/build-pkg-osx.sh | 6 +++--- conda/faiss/build-pkg.sh | 6 +++--- conda/faiss/test_cpu_dispatch.sh | 5 +++-- faiss/CMakeLists.txt | 2 +- faiss/utils/utils.cpp | 2 +- tests/test_index_accuracy.py | 4 ++-- 17 files changed, 43 insertions(+), 35 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ddcb5ba83..406817e09d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -314,6 +314,10 @@ workflows: name: Linux x86_64 AVX2 (cmake) exec: linux-x86_64-cpu opt_level: "avx2" + - build_cmake: + name: Linux x86_64 AVX512 (cmake) + exec: linux-x86_64-cpu + opt_level: "avx512" - build_cmake: name: Linux x86_64 GPU (cmake) exec: linux-x86_64-gpu diff --git a/.gitignore b/.gitignore index 183e2066e1..caab1304c8 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ /tests/test /tests/gtest/ faiss/python/swigfaiss_avx2.swig +faiss/python/swigfaiss_avx512.swig diff --git a/conda/faiss-gpu-raft/build-lib.sh b/conda/faiss-gpu-raft/build-lib.sh index 7ca17180a4..79ca8da2cd 100644 --- a/conda/faiss-gpu-raft/build-lib.sh +++ b/conda/faiss-gpu-raft/build-lib.sh @@ -7,11 +7,11 @@ set -e -# Build libfaiss.so/libfaiss_avx2.so. +# Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so cmake -B _build \ -DBUILD_SHARED_LIBS=ON \ -DBUILD_TESTING=OFF \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=ON \ -DFAISS_ENABLE_RAFT=ON \ -DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}" \ @@ -20,7 +20,7 @@ cmake -B _build \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_BUILD_TYPE=Release . -make -C _build -j$(nproc) faiss faiss_avx2 +make -C _build -j$(nproc) faiss faiss_avx2 faiss_avx512 cmake --install _build --prefix $PREFIX cmake --install _build --prefix _libfaiss_stage/ diff --git a/conda/faiss-gpu-raft/build-pkg.sh b/conda/faiss-gpu-raft/build-pkg.sh index 3bb61588e5..da5fdefca9 100644 --- a/conda/faiss-gpu-raft/build-pkg.sh +++ b/conda/faiss-gpu-raft/build-pkg.sh @@ -7,17 +7,17 @@ set -e -# Build swigfaiss.so/swigfaiss_avx2.so. +# Build swigfaiss.so/swigfaiss_avx2.so/swigfaiss_avx512.so cmake -B _build_python_${PY_VER} \ -Dfaiss_ROOT=_libfaiss_stage/ \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=ON \ -DFAISS_ENABLE_RAFT=ON \ -DCMAKE_BUILD_TYPE=Release \ -DPython_EXECUTABLE=$PYTHON \ faiss/python -make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 +make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 swigfaiss_avx512 # Build actual python module. cd _build_python_${PY_VER}/ diff --git a/conda/faiss-gpu-raft/test_cpu_dispatch.sh b/conda/faiss-gpu-raft/test_cpu_dispatch.sh index b2891919d5..a7c1b2da72 100755 --- a/conda/faiss-gpu-raft/test_cpu_dispatch.sh +++ b/conda/faiss-gpu-raft/test_cpu_dispatch.sh @@ -6,5 +6,6 @@ set -e -FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so -LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL= LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so +FAISS_OPT_LEVEL=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL=AVX512 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx512.so diff --git a/conda/faiss-gpu/build-lib.sh b/conda/faiss-gpu/build-lib.sh index 6b6b1c28d0..2d25e9c5e6 100755 --- a/conda/faiss-gpu/build-lib.sh +++ b/conda/faiss-gpu/build-lib.sh @@ -7,11 +7,11 @@ set -e -# Build libfaiss.so/libfaiss_avx2.so. +# Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so cmake -B _build \ -DBUILD_SHARED_LIBS=ON \ -DBUILD_TESTING=OFF \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=ON \ -DFAISS_ENABLE_RAFT=OFF \ -DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}" \ @@ -20,7 +20,7 @@ cmake -B _build \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_BUILD_TYPE=Release . -make -C _build -j$(nproc) faiss faiss_avx2 +make -C _build -j$(nproc) faiss faiss_avx2 faiss_avx512 cmake --install _build --prefix $PREFIX cmake --install _build --prefix _libfaiss_stage/ diff --git a/conda/faiss-gpu/build-pkg.sh b/conda/faiss-gpu/build-pkg.sh index 3a41511921..e529a83d80 100755 --- a/conda/faiss-gpu/build-pkg.sh +++ b/conda/faiss-gpu/build-pkg.sh @@ -7,17 +7,17 @@ set -e -# Build swigfaiss.so/swigfaiss_avx2.so. +# Build swigfaiss.so/swigfaiss_avx2.so/swigfaiss_avx512.so cmake -B _build_python_${PY_VER} \ -Dfaiss_ROOT=_libfaiss_stage/ \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=ON \ -DFAISS_ENABLE_RAFT=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DPython_EXECUTABLE=$PYTHON \ faiss/python -make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 +make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 swigfaiss_avx512 # Build actual python module. cd _build_python_${PY_VER}/ diff --git a/conda/faiss-gpu/test_cpu_dispatch.sh b/conda/faiss-gpu/test_cpu_dispatch.sh index b2891919d5..a7c1b2da72 100755 --- a/conda/faiss-gpu/test_cpu_dispatch.sh +++ b/conda/faiss-gpu/test_cpu_dispatch.sh @@ -6,5 +6,6 @@ set -e -FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so -LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL= LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so +FAISS_OPT_LEVEL=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL=AVX512 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx512.so diff --git a/conda/faiss/build-lib-osx.sh b/conda/faiss/build-lib-osx.sh index a30de2d000..e858106bf2 100755 --- a/conda/faiss/build-lib-osx.sh +++ b/conda/faiss/build-lib-osx.sh @@ -7,11 +7,11 @@ set -e -# Build libfaiss.so/libfaiss_avx2.so. +# Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so cmake -B _build \ -DBUILD_SHARED_LIBS=ON \ -DBUILD_TESTING=OFF \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=OFF \ -DFAISS_ENABLE_PYTHON=OFF \ -DBLA_VENDOR=Intel10_64lp \ @@ -21,7 +21,7 @@ cmake -B _build \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_BUILD_TYPE=Release . -make -C _build -j$(nproc) faiss faiss_avx2 +make -C _build -j$(nproc) faiss faiss_avx2 faiss_avx512 cmake --install _build --prefix $PREFIX cmake --install _build --prefix _libfaiss_stage/ diff --git a/conda/faiss/build-lib.sh b/conda/faiss/build-lib.sh index 8aed84ba41..5028891d93 100755 --- a/conda/faiss/build-lib.sh +++ b/conda/faiss/build-lib.sh @@ -7,18 +7,18 @@ set -e -# Build libfaiss.so/libfaiss_avx2.so. +# Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so cmake -B _build \ -DBUILD_SHARED_LIBS=ON \ -DBUILD_TESTING=OFF \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=OFF \ -DFAISS_ENABLE_PYTHON=OFF \ -DBLA_VENDOR=Intel10_64lp \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_BUILD_TYPE=Release . -make -C _build -j$(nproc) faiss faiss_avx2 +make -C _build -j$(nproc) faiss faiss_avx2 faiss_avx512 cmake --install _build --prefix $PREFIX cmake --install _build --prefix _libfaiss_stage/ diff --git a/conda/faiss/build-pkg-arm64.sh b/conda/faiss/build-pkg-arm64.sh index c63380ab01..70fc7312e5 100755 --- a/conda/faiss/build-pkg-arm64.sh +++ b/conda/faiss/build-pkg-arm64.sh @@ -7,7 +7,7 @@ set -e -# Build swigfaiss.so/swigfaiss_avx2.so. +# Build swigfaiss.so cmake -B _build_python_${PY_VER} \ -Dfaiss_ROOT=_libfaiss_stage/ \ -DFAISS_ENABLE_GPU=OFF \ diff --git a/conda/faiss/build-pkg-osx.sh b/conda/faiss/build-pkg-osx.sh index 15016face9..914aed174d 100755 --- a/conda/faiss/build-pkg-osx.sh +++ b/conda/faiss/build-pkg-osx.sh @@ -7,10 +7,10 @@ set -e -# Build swigfaiss.so/swigfaiss_avx2.so. +# Build swigfaiss.so/swigfaiss_avx2.so/swigfaiss_avx512 cmake -B _build_python_${PY_VER} \ -Dfaiss_ROOT=_libfaiss_stage/ \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=OFF \ -DOpenMP_CXX_FLAGS=-fopenmp=libiomp5 \ -DOpenMP_CXX_LIB_NAMES=libiomp5 \ @@ -19,7 +19,7 @@ cmake -B _build_python_${PY_VER} \ -DPython_EXECUTABLE=$PYTHON \ faiss/python -make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 +make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 swigfaiss_avx512 # Build actual python module. cd _build_python_${PY_VER}/ diff --git a/conda/faiss/build-pkg.sh b/conda/faiss/build-pkg.sh index 005aec2fcc..92e0febfa8 100755 --- a/conda/faiss/build-pkg.sh +++ b/conda/faiss/build-pkg.sh @@ -7,16 +7,16 @@ set -e -# Build swigfaiss.so/swigfaiss_avx2.so. +# Build swigfaiss.so/swigfaiss_avx2.so/swigfaiss_avx512.so cmake -B _build_python_${PY_VER} \ -Dfaiss_ROOT=_libfaiss_stage/ \ - -DFAISS_OPT_LEVEL=avx2 \ + -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_GPU=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DPython_EXECUTABLE=$PYTHON \ faiss/python -make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 +make -C _build_python_${PY_VER} -j$(nproc) swigfaiss swigfaiss_avx2 swigfaiss_avx512 # Build actual python module. cd _build_python_${PY_VER}/ diff --git a/conda/faiss/test_cpu_dispatch.sh b/conda/faiss/test_cpu_dispatch.sh index b2891919d5..a7c1b2da72 100755 --- a/conda/faiss/test_cpu_dispatch.sh +++ b/conda/faiss/test_cpu_dispatch.sh @@ -6,5 +6,6 @@ set -e -FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so -LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL= LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss.so +FAISS_OPT_LEVEL=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx2.so +FAISS_OPT_LEVEL=AVX512 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep libfaiss_avx512.so diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index 27701586c8..db5133d68b 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -328,7 +328,7 @@ if(FAISS_OPT_LEVEL STREQUAL "avx2") ) endif() if(FAISS_OPT_LEVEL STREQUAL "avx512") - install(TARGETS faiss_avx512 + install(TARGETS faiss_avx2 faiss_avx512 EXPORT faiss-targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/faiss/utils/utils.cpp b/faiss/utils/utils.cpp index efbff502b0..c39a1bf5eb 100644 --- a/faiss/utils/utils.cpp +++ b/faiss/utils/utils.cpp @@ -117,7 +117,7 @@ std::string get_compile_options() { #ifdef __AVX2__ options += "AVX2 "; #elif __AVX512F__ - options += "AVX512"; + options += "AVX512 "; #elif defined(__aarch64__) options += "NEON "; #else diff --git a/tests/test_index_accuracy.py b/tests/test_index_accuracy.py index 44b4ca365f..3f7bfbd303 100644 --- a/tests/test_index_accuracy.py +++ b/tests/test_index_accuracy.py @@ -639,14 +639,14 @@ def test_OIVFPQ(self): d = ev.d quantizer = faiss.IndexFlatL2(d) index = faiss.IndexIVFPQ(quantizer, d, ncentroids, M, 8) - index.nprobe = 5 + index.nprobe = 12 res = ev.launch("IVFPQ", index) e_ivfpq = ev.evalres(res) quantizer = faiss.IndexFlatL2(d) index_ivfpq = faiss.IndexIVFPQ(quantizer, d, ncentroids, M, 8) - index_ivfpq.nprobe = 5 + index_ivfpq.nprobe = 12 opq_matrix = faiss.OPQMatrix(d, M) opq_matrix.niter = 10 index = faiss.IndexPreTransform(opq_matrix, index_ivfpq) From 32f0e8cf92cd2275b60364517bb1cce67aa29a55 Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Thu, 11 Jan 2024 11:46:30 -0800 Subject: [PATCH 017/206] Generalize ResultHanlder, support range search for HNSW and Fast Scan (#3190) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3190 This diff adds more result handlers in order to expose them externally. This enables range search for HSNW and Fast Scan, and nprobe parameter support for FastScan. Reviewed By: pemazare Differential Revision: D52547384 fbshipit-source-id: 271da5ffea6411df3d8e50641abade18bd7b774b --- CHANGELOG.md | 1 + benchs/link_and_code/README.md | 2 + contrib/evaluation.py | 1 + faiss/IndexAdditiveQuantizer.cpp | 27 +- faiss/IndexAdditiveQuantizerFastScan.cpp | 4 +- faiss/IndexBinaryHNSW.cpp | 23 +- faiss/IndexFastScan.cpp | 231 ++--- faiss/IndexFastScan.h | 17 +- faiss/IndexHNSW.cpp | 348 ++----- faiss/IndexHNSW.h | 52 +- faiss/IndexIVFAdditiveQuantizerFastScan.cpp | 18 +- faiss/IndexIVFAdditiveQuantizerFastScan.h | 3 +- faiss/IndexIVFFastScan.cpp | 878 ++++++++---------- faiss/IndexIVFFastScan.h | 81 +- faiss/IndexIVFPQ.cpp | 2 +- faiss/IndexIVFPQFastScan.cpp | 16 +- faiss/IndexIVFPQFastScan.h | 3 +- faiss/impl/AuxIndexStructures.h | 1 - faiss/impl/HNSW.cpp | 86 +- faiss/impl/HNSW.h | 15 +- faiss/impl/Quantizer.h | 2 +- faiss/impl/ResultHandler.h | 392 ++++---- faiss/impl/pq4_fast_scan.cpp | 3 + faiss/impl/pq4_fast_scan.h | 13 +- faiss/impl/pq4_fast_scan_search_1.cpp | 88 +- faiss/impl/pq4_fast_scan_search_qbs.cpp | 83 +- faiss/impl/simd_result_handlers.h | 576 ++++++++---- faiss/python/swigfaiss.swig | 8 + faiss/utils/distances.cpp | 107 ++- faiss/utils/distances_fused/avx512.cpp | 8 +- faiss/utils/distances_fused/avx512.h | 2 +- .../utils/distances_fused/distances_fused.cpp | 2 +- faiss/utils/distances_fused/distances_fused.h | 2 +- faiss/utils/distances_fused/simdlib_based.cpp | 8 +- faiss/utils/distances_fused/simdlib_based.h | 2 +- tests/test_fast_scan_ivf.py | 79 +- tests/test_graph_based.py | 426 +++++++++ tests/test_index.py | 400 -------- 38 files changed, 1995 insertions(+), 2015 deletions(-) create mode 100644 tests/test_graph_based.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a38f4e2d5..ae418b09b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ We try to indicate most contributions here with the contributor names who are no the Facebook Faiss team. Feel free to add entries here if you submit a PR. ## [Unreleased] +- Support for range search in HNSW and Fast scan IVF. ## [1.7.4] - 2023-04-12 ### Added - Added big batch IVF search for conducting efficient search with big batches of queries diff --git a/benchs/link_and_code/README.md b/benchs/link_and_code/README.md index bbf034bc60..697c7bdfc6 100644 --- a/benchs/link_and_code/README.md +++ b/benchs/link_and_code/README.md @@ -39,6 +39,8 @@ The code runs on top of Faiss. The HNSW index can be extended with a `ReconstructFromNeighbors` C++ object that refines the distances. The training is implemented in Python. +Update: 2023-12-28: the current Faiss dropped support for reconstruction with +this method. Reproducing Table 2 in the paper -------------------------------- diff --git a/contrib/evaluation.py b/contrib/evaluation.py index 50e8a93319..435c390594 100644 --- a/contrib/evaluation.py +++ b/contrib/evaluation.py @@ -261,6 +261,7 @@ def check_ref_knn_with_draws(Dref, Iref, Dnew, Inew, rtol=1e-5): mask = DrefC == dis testcase.assertEqual(set(Iref[i, mask]), set(Inew[i, mask])) + def check_ref_range_results(Lref, Dref, Iref, Lnew, Dnew, Inew): """ compare range search results wrt. a reference result, diff --git a/faiss/IndexAdditiveQuantizer.cpp b/faiss/IndexAdditiveQuantizer.cpp index 5bf06c4a4a..719dcafbc9 100644 --- a/faiss/IndexAdditiveQuantizer.cpp +++ b/faiss/IndexAdditiveQuantizer.cpp @@ -114,18 +114,19 @@ struct AQDistanceComputerLUT : FlatCodesDistanceComputer { * scanning implementation for search ************************************************************/ -template +template void search_with_decompress( const IndexAdditiveQuantizer& ir, const float* xq, VectorDistance& vd, - ResultHandler& res) { + BlockResultHandler& res) { const uint8_t* codes = ir.codes.data(); size_t ntotal = ir.ntotal; size_t code_size = ir.code_size; const AdditiveQuantizer* aq = ir.aq; - using SingleResultHandler = typename ResultHandler::SingleResultHandler; + using SingleResultHandler = + typename BlockResultHandler::SingleResultHandler; #pragma omp parallel for if (res.nq > 100) for (int64_t q = 0; q < res.nq; q++) { @@ -142,11 +143,14 @@ void search_with_decompress( } } -template +template < + bool is_IP, + AdditiveQuantizer::Search_type_t st, + class BlockResultHandler> void search_with_LUT( const IndexAdditiveQuantizer& ir, const float* xq, - ResultHandler& res) { + BlockResultHandler& res) { const AdditiveQuantizer& aq = *ir.aq; const uint8_t* codes = ir.codes.data(); size_t ntotal = ir.ntotal; @@ -154,7 +158,8 @@ void search_with_LUT( size_t nq = res.nq; size_t d = ir.d; - using SingleResultHandler = typename ResultHandler::SingleResultHandler; + using SingleResultHandler = + typename BlockResultHandler::SingleResultHandler; std::unique_ptr LUT(new float[nq * aq.total_codebook_size]); aq.compute_LUT(nq, xq, LUT.get()); @@ -241,21 +246,23 @@ void IndexAdditiveQuantizer::search( if (metric_type == METRIC_L2) { using VD = VectorDistance; VD vd = {size_t(d), metric_arg}; - HeapResultHandler rh(n, distances, labels, k); + HeapBlockResultHandler rh(n, distances, labels, k); search_with_decompress(*this, x, vd, rh); } else if (metric_type == METRIC_INNER_PRODUCT) { using VD = VectorDistance; VD vd = {size_t(d), metric_arg}; - HeapResultHandler rh(n, distances, labels, k); + HeapBlockResultHandler rh(n, distances, labels, k); search_with_decompress(*this, x, vd, rh); } } else { if (metric_type == METRIC_INNER_PRODUCT) { - HeapResultHandler> rh(n, distances, labels, k); + HeapBlockResultHandler> rh( + n, distances, labels, k); search_with_LUT( *this, x, rh); } else { - HeapResultHandler> rh(n, distances, labels, k); + HeapBlockResultHandler> rh( + n, distances, labels, k); switch (aq->search_type) { #define DISPATCH(st) \ case AdditiveQuantizer::st: \ diff --git a/faiss/IndexAdditiveQuantizerFastScan.cpp b/faiss/IndexAdditiveQuantizerFastScan.cpp index 709ccc87e2..85a78647f3 100644 --- a/faiss/IndexAdditiveQuantizerFastScan.cpp +++ b/faiss/IndexAdditiveQuantizerFastScan.cpp @@ -203,9 +203,9 @@ void IndexAdditiveQuantizerFastScan::search( NormTableScaler scaler(norm_scale); if (metric_type == METRIC_L2) { - search_dispatch_implem(n, x, k, distances, labels, scaler); + search_dispatch_implem(n, x, k, distances, labels, &scaler); } else { - search_dispatch_implem(n, x, k, distances, labels, scaler); + search_dispatch_implem(n, x, k, distances, labels, &scaler); } } diff --git a/faiss/IndexBinaryHNSW.cpp b/faiss/IndexBinaryHNSW.cpp index e6fda8e4bf..f1bda08fbc 100644 --- a/faiss/IndexBinaryHNSW.cpp +++ b/faiss/IndexBinaryHNSW.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -28,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -201,27 +200,31 @@ void IndexBinaryHNSW::search( !params, "search params not supported for this index"); FAISS_THROW_IF_NOT(k > 0); + // we use the buffer for distances as float but convert them back + // to int in the end + float* distances_f = (float*)distances; + + using RH = HeapBlockResultHandler; + RH bres(n, distances_f, labels, k); + #pragma omp parallel { VisitedTable vt(ntotal); std::unique_ptr dis(get_distance_computer()); + RH::SingleResultHandler res(bres); #pragma omp for for (idx_t i = 0; i < n; i++) { - idx_t* idxi = labels + i * k; - float* simi = (float*)(distances + i * k); - + res.begin(i); dis->set_query((float*)(x + i * code_size)); - - maxheap_heapify(k, simi, idxi); - hnsw.search(*dis, k, idxi, simi, vt); - maxheap_reorder(k, simi, idxi); + hnsw.search(*dis, res, vt); + res.end(); } } #pragma omp parallel for for (int i = 0; i < n * k; ++i) { - distances[i] = std::round(((float*)distances)[i]); + distances[i] = std::round(distances_f[i]); } } diff --git a/faiss/IndexFastScan.cpp b/faiss/IndexFastScan.cpp index 02840767d1..ca02af4168 100644 --- a/faiss/IndexFastScan.cpp +++ b/faiss/IndexFastScan.cpp @@ -158,7 +158,7 @@ void IndexFastScan::merge_from(Index& otherIndex, idx_t add_id) { namespace { -template +template void estimators_from_tables_generic( const IndexFastScan& index, const uint8_t* codes, @@ -167,25 +167,28 @@ void estimators_from_tables_generic( size_t k, typename C::T* heap_dis, int64_t* heap_ids, - const Scaler& scaler) { + const NormTableScaler* scaler) { using accu_t = typename C::T; for (size_t j = 0; j < ncodes; ++j) { BitstringReader bsr(codes + j * index.code_size, index.code_size); accu_t dis = 0; const dis_t* dt = dis_table; - for (size_t m = 0; m < index.M - scaler.nscale; m++) { + int nscale = scaler ? scaler->nscale : 0; + + for (size_t m = 0; m < index.M - nscale; m++) { uint64_t c = bsr.read(index.nbits); dis += dt[c]; dt += index.ksub; } - for (size_t m = 0; m < scaler.nscale; m++) { - uint64_t c = bsr.read(index.nbits); - dis += scaler.scale_one(dt[c]); - dt += index.ksub; + if (nscale) { + for (size_t m = 0; m < nscale; m++) { + uint64_t c = bsr.read(index.nbits); + dis += scaler->scale_one(dt[c]); + dt += index.ksub; + } } - if (C::cmp(heap_dis[0], dis)) { heap_pop(k, heap_dis, heap_ids); heap_push(k, heap_dis, heap_ids, dis, j); @@ -193,6 +196,27 @@ void estimators_from_tables_generic( } } +template +ResultHandlerCompare* make_knn_handler( + int impl, + idx_t n, + idx_t k, + size_t ntotal, + float* distances, + idx_t* labels) { + using HeapHC = HeapHandler; + using ReservoirHC = ReservoirHandler; + using SingleResultHC = SingleResultHandler; + + if (k == 1) { + return new SingleResultHC(n, ntotal, distances, labels); + } else if (impl % 2 == 0) { + return new HeapHC(n, ntotal, k, distances, labels); + } else /* if (impl % 2 == 1) */ { + return new ReservoirHC(n, ntotal, k, 2 * k, distances, labels); + } +} + } // anonymous namespace using namespace quantize_lut; @@ -241,22 +265,21 @@ void IndexFastScan::search( !params, "search params not supported for this index"); FAISS_THROW_IF_NOT(k > 0); - DummyScaler scaler; if (metric_type == METRIC_L2) { - search_dispatch_implem(n, x, k, distances, labels, scaler); + search_dispatch_implem(n, x, k, distances, labels, nullptr); } else { - search_dispatch_implem(n, x, k, distances, labels, scaler); + search_dispatch_implem(n, x, k, distances, labels, nullptr); } } -template +template void IndexFastScan::search_dispatch_implem( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { using Cfloat = typename std::conditional< is_max, CMax, @@ -319,14 +342,14 @@ void IndexFastScan::search_dispatch_implem( } } -template +template void IndexFastScan::search_implem_234( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { FAISS_THROW_IF_NOT(implem == 2 || implem == 3 || implem == 4); const size_t dim12 = ksub * M; @@ -378,7 +401,7 @@ void IndexFastScan::search_implem_234( } } -template +template void IndexFastScan::search_implem_12( idx_t n, const float* x, @@ -386,7 +409,8 @@ void IndexFastScan::search_implem_12( float* distances, idx_t* labels, int impl, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { + using RH = ResultHandlerCompare; FAISS_THROW_IF_NOT(bbs == 32); // handle qbs2 blocking by recursive call @@ -432,63 +456,31 @@ void IndexFastScan::search_implem_12( pq4_pack_LUT_qbs(qbs, M2, quantized_dis_tables.get(), LUT.get()); FAISS_THROW_IF_NOT(LUT_nq == n); - if (k == 1) { - SingleResultHandler handler(n, ntotal); - if (skip & 4) { - // pass - } else { - handler.disable = bool(skip & 2); - pq4_accumulate_loop_qbs( - qbs, ntotal2, M2, codes.get(), LUT.get(), handler, scaler); - } + std::unique_ptr handler( + make_knn_handler(impl, n, k, ntotal, distances, labels)); + handler->disable = bool(skip & 2); + handler->normalizers = normalizers.get(); - handler.to_flat_arrays(distances, labels, normalizers.get()); - - } else if (impl == 12) { - std::vector tmp_dis(n * k); - std::vector tmp_ids(n * k); - - if (skip & 4) { - // skip - } else { - HeapHandler handler( - n, tmp_dis.data(), tmp_ids.data(), k, ntotal); - handler.disable = bool(skip & 2); - - pq4_accumulate_loop_qbs( - qbs, ntotal2, M2, codes.get(), LUT.get(), handler, scaler); - - if (!(skip & 8)) { - handler.to_flat_arrays(distances, labels, normalizers.get()); - } - } - - } else { // impl == 13 - - ReservoirHandler handler(n, ntotal, k, 2 * k); - handler.disable = bool(skip & 2); - - if (skip & 4) { - // skip - } else { - pq4_accumulate_loop_qbs( - qbs, ntotal2, M2, codes.get(), LUT.get(), handler, scaler); - } - - if (!(skip & 8)) { - handler.to_flat_arrays(distances, labels, normalizers.get()); - } - - FastScan_stats.t0 += handler.times[0]; - FastScan_stats.t1 += handler.times[1]; - FastScan_stats.t2 += handler.times[2]; - FastScan_stats.t3 += handler.times[3]; + if (skip & 4) { + // pass + } else { + pq4_accumulate_loop_qbs( + qbs, + ntotal2, + M2, + codes.get(), + LUT.get(), + *handler.get(), + scaler); + } + if (!(skip & 8)) { + handler->end(); } } FastScanStats FastScan_stats; -template +template void IndexFastScan::search_implem_14( idx_t n, const float* x, @@ -496,7 +488,8 @@ void IndexFastScan::search_implem_14( float* distances, idx_t* labels, int impl, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { + using RH = ResultHandlerCompare; FAISS_THROW_IF_NOT(bbs % 32 == 0); int qbs2 = qbs == 0 ? 4 : qbs; @@ -531,91 +524,29 @@ void IndexFastScan::search_implem_14( AlignedTable LUT(n * dim12); pq4_pack_LUT(n, M2, quantized_dis_tables.get(), LUT.get()); - if (k == 1) { - SingleResultHandler handler(n, ntotal); - if (skip & 4) { - // pass - } else { - handler.disable = bool(skip & 2); - pq4_accumulate_loop( - n, - ntotal2, - bbs, - M2, - codes.get(), - LUT.get(), - handler, - scaler); - } - handler.to_flat_arrays(distances, labels, normalizers.get()); - - } else if (impl == 14) { - std::vector tmp_dis(n * k); - std::vector tmp_ids(n * k); - - if (skip & 4) { - // skip - } else if (k > 1) { - HeapHandler handler( - n, tmp_dis.data(), tmp_ids.data(), k, ntotal); - handler.disable = bool(skip & 2); - - pq4_accumulate_loop( - n, - ntotal2, - bbs, - M2, - codes.get(), - LUT.get(), - handler, - scaler); - - if (!(skip & 8)) { - handler.to_flat_arrays(distances, labels, normalizers.get()); - } - } - - } else { // impl == 15 - - ReservoirHandler handler(n, ntotal, k, 2 * k); - handler.disable = bool(skip & 2); - - if (skip & 4) { - // skip - } else { - pq4_accumulate_loop( - n, - ntotal2, - bbs, - M2, - codes.get(), - LUT.get(), - handler, - scaler); - } + std::unique_ptr handler( + make_knn_handler(impl, n, k, ntotal, distances, labels)); + handler->disable = bool(skip & 2); + handler->normalizers = normalizers.get(); - if (!(skip & 8)) { - handler.to_flat_arrays(distances, labels, normalizers.get()); - } + if (skip & 4) { + // pass + } else { + pq4_accumulate_loop( + n, + ntotal2, + bbs, + M2, + codes.get(), + LUT.get(), + *handler.get(), + scaler); + } + if (!(skip & 8)) { + handler->end(); } } -template void IndexFastScan::search_dispatch_implem( - idx_t n, - const float* x, - idx_t k, - float* distances, - idx_t* labels, - const NormTableScaler& scaler) const; - -template void IndexFastScan::search_dispatch_implem( - idx_t n, - const float* x, - idx_t k, - float* distances, - idx_t* labels, - const NormTableScaler& scaler) const; - void IndexFastScan::reconstruct(idx_t key, float* recons) const { std::vector code(code_size, 0); BitstringWriter bsw(code.data(), code_size); diff --git a/faiss/IndexFastScan.h b/faiss/IndexFastScan.h index 19aad2a8ee..3c89dcf928 100644 --- a/faiss/IndexFastScan.h +++ b/faiss/IndexFastScan.h @@ -13,6 +13,7 @@ namespace faiss { struct CodePacker; +struct NormTableScaler; /** Fast scan version of IndexPQ and IndexAQ. Works for 4-bit PQ and AQ for now. * @@ -87,25 +88,25 @@ struct IndexFastScan : Index { uint8_t* lut, float* normalizers) const; - template + template void search_dispatch_implem( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; - template + template void search_implem_234( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; - template + template void search_implem_12( idx_t n, const float* x, @@ -113,9 +114,9 @@ struct IndexFastScan : Index { float* distances, idx_t* labels, int impl, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; - template + template void search_implem_14( idx_t n, const float* x, @@ -123,7 +124,7 @@ struct IndexFastScan : Index { float* distances, idx_t* labels, int impl, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; void reconstruct(idx_t key, float* recons) const override; size_t remove_ids(const IDSelector& sel) override; diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index 8c0e0afde8..c40136749b 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -286,18 +286,20 @@ void IndexHNSW::train(idx_t n, const float* x) { is_trained = true; } -void IndexHNSW::search( +namespace { + +template +void hnsw_search( + const IndexHNSW* index, idx_t n, const float* x, - idx_t k, - float* distances, - idx_t* labels, - const SearchParameters* params_in) const { - FAISS_THROW_IF_NOT(k > 0); + BlockResultHandler& bres, + const SearchParameters* params_in) { FAISS_THROW_IF_NOT_MSG( - storage, + index->storage, "Please use IndexHNSWFlat (or variants) instead of IndexHNSW directly"); const SearchParametersHNSW* params = nullptr; + const HNSW& hnsw = index->hnsw; int efSearch = hnsw.efSearch; if (params_in) { @@ -307,61 +309,81 @@ void IndexHNSW::search( } size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0; - idx_t check_period = - InterruptCallback::get_period_hint(hnsw.max_level * d * efSearch); + idx_t check_period = InterruptCallback::get_period_hint( + hnsw.max_level * index->d * efSearch); for (idx_t i0 = 0; i0 < n; i0 += check_period) { idx_t i1 = std::min(i0 + check_period, n); #pragma omp parallel { - VisitedTable vt(ntotal); + VisitedTable vt(index->ntotal); + typename BlockResultHandler::SingleResultHandler res(bres); std::unique_ptr dis( - storage_distance_computer(storage)); + storage_distance_computer(index->storage)); #pragma omp for reduction(+ : n1, n2, n3, ndis, nreorder) schedule(guided) for (idx_t i = i0; i < i1; i++) { - idx_t* idxi = labels + i * k; - float* simi = distances + i * k; - dis->set_query(x + i * d); + res.begin(i); + dis->set_query(x + i * index->d); - maxheap_heapify(k, simi, idxi); - HNSWStats stats = hnsw.search(*dis, k, idxi, simi, vt, params); + HNSWStats stats = hnsw.search(*dis, res, vt, params); n1 += stats.n1; n2 += stats.n2; n3 += stats.n3; ndis += stats.ndis; nreorder += stats.nreorder; - maxheap_reorder(k, simi, idxi); - - if (reconstruct_from_neighbors && - reconstruct_from_neighbors->k_reorder != 0) { - int k_reorder = reconstruct_from_neighbors->k_reorder; - if (k_reorder == -1 || k_reorder > k) - k_reorder = k; - - nreorder += reconstruct_from_neighbors->compute_distances( - k_reorder, idxi, x + i * d, simi); - - // sort top k_reorder - maxheap_heapify( - k_reorder, simi, idxi, simi, idxi, k_reorder); - maxheap_reorder(k_reorder, simi, idxi); - } + res.end(); } } InterruptCallback::check(); } - if (is_similarity_metric(metric_type)) { + hnsw_stats.combine({n1, n2, n3, ndis, nreorder}); +} + +} // anonymous namespace + +void IndexHNSW::search( + idx_t n, + const float* x, + idx_t k, + float* distances, + idx_t* labels, + const SearchParameters* params_in) const { + FAISS_THROW_IF_NOT(k > 0); + + using RH = HeapBlockResultHandler; + RH bres(n, distances, labels, k); + + hnsw_search(this, n, x, bres, params_in); + + if (is_similarity_metric(this->metric_type)) { // we need to revert the negated distances for (size_t i = 0; i < k * n; i++) { distances[i] = -distances[i]; } } +} - hnsw_stats.combine({n1, n2, n3, ndis, nreorder}); +void IndexHNSW::range_search( + idx_t n, + const float* x, + float radius, + RangeSearchResult* result, + const SearchParameters* params) const { + using RH = RangeSearchBlockResultHandler; + RH bres(result, radius); + + hnsw_search(this, n, x, bres, params); + + if (is_similarity_metric(this->metric_type)) { + // we need to revert the negated distances + for (size_t i = 0; i < result->lims[result->nq]; i++) { + result->distances[i] = -result->distances[i]; + } + } } void IndexHNSW::add(idx_t n, const float* x) { @@ -437,35 +459,33 @@ void IndexHNSW::search_level_0( storage_idx_t ntotal = hnsw.levels.size(); + using RH = HeapBlockResultHandler; + RH bres(n, distances, labels, k); + #pragma omp parallel { std::unique_ptr qdis( storage_distance_computer(storage)); HNSWStats search_stats; VisitedTable vt(ntotal); + RH::SingleResultHandler res(bres); #pragma omp for for (idx_t i = 0; i < n; i++) { - idx_t* idxi = labels + i * k; - float* simi = distances + i * k; - + res.begin(i); qdis->set_query(x + i * d); - maxheap_heapify(k, simi, idxi); hnsw.search_level_0( *qdis.get(), - k, - idxi, - simi, + res, nprobe, nearest + i * nprobe, nearest_d + i * nprobe, search_type, search_stats, vt); - + res.end(); vt.advance(); - maxheap_reorder(k, simi, idxi); } #pragma omp critical { hnsw_stats.combine(search_stats); } @@ -630,246 +650,6 @@ void IndexHNSW::permute_entries(const idx_t* perm) { hnsw.permute_entries(perm); } -/************************************************************** - * ReconstructFromNeighbors implementation - **************************************************************/ - -ReconstructFromNeighbors::ReconstructFromNeighbors( - const IndexHNSW& index, - size_t k, - size_t nsq) - : index(index), k(k), nsq(nsq) { - M = index.hnsw.nb_neighbors(0); - FAISS_ASSERT(k <= 256); - code_size = k == 1 ? 0 : nsq; - ntotal = 0; - d = index.d; - FAISS_ASSERT(d % nsq == 0); - dsub = d / nsq; - k_reorder = -1; -} - -void ReconstructFromNeighbors::reconstruct( - storage_idx_t i, - float* x, - float* tmp) const { - const HNSW& hnsw = index.hnsw; - size_t begin, end; - hnsw.neighbor_range(i, 0, &begin, &end); - - if (k == 1 || nsq == 1) { - const float* beta; - if (k == 1) { - beta = codebook.data(); - } else { - int idx = codes[i]; - beta = codebook.data() + idx * (M + 1); - } - - float w0 = beta[0]; // weight of image itself - index.storage->reconstruct(i, tmp); - - for (int l = 0; l < d; l++) - x[l] = w0 * tmp[l]; - - for (size_t j = begin; j < end; j++) { - storage_idx_t ji = hnsw.neighbors[j]; - if (ji < 0) - ji = i; - float w = beta[j - begin + 1]; - index.storage->reconstruct(ji, tmp); - for (int l = 0; l < d; l++) - x[l] += w * tmp[l]; - } - } else if (nsq == 2) { - int idx0 = codes[2 * i]; - int idx1 = codes[2 * i + 1]; - - const float* beta0 = codebook.data() + idx0 * (M + 1); - const float* beta1 = codebook.data() + (idx1 + k) * (M + 1); - - index.storage->reconstruct(i, tmp); - - float w0; - - w0 = beta0[0]; - for (int l = 0; l < dsub; l++) - x[l] = w0 * tmp[l]; - - w0 = beta1[0]; - for (int l = dsub; l < d; l++) - x[l] = w0 * tmp[l]; - - for (size_t j = begin; j < end; j++) { - storage_idx_t ji = hnsw.neighbors[j]; - if (ji < 0) - ji = i; - index.storage->reconstruct(ji, tmp); - float w; - w = beta0[j - begin + 1]; - for (int l = 0; l < dsub; l++) - x[l] += w * tmp[l]; - - w = beta1[j - begin + 1]; - for (int l = dsub; l < d; l++) - x[l] += w * tmp[l]; - } - } else { - std::vector betas(nsq); - { - const float* b = codebook.data(); - const uint8_t* c = &codes[i * code_size]; - for (int sq = 0; sq < nsq; sq++) { - betas[sq] = b + (*c++) * (M + 1); - b += (M + 1) * k; - } - } - - index.storage->reconstruct(i, tmp); - { - int d0 = 0; - for (int sq = 0; sq < nsq; sq++) { - float w = *(betas[sq]++); - int d1 = d0 + dsub; - for (int l = d0; l < d1; l++) { - x[l] = w * tmp[l]; - } - d0 = d1; - } - } - - for (size_t j = begin; j < end; j++) { - storage_idx_t ji = hnsw.neighbors[j]; - if (ji < 0) - ji = i; - - index.storage->reconstruct(ji, tmp); - int d0 = 0; - for (int sq = 0; sq < nsq; sq++) { - float w = *(betas[sq]++); - int d1 = d0 + dsub; - for (int l = d0; l < d1; l++) { - x[l] += w * tmp[l]; - } - d0 = d1; - } - } - } -} - -void ReconstructFromNeighbors::reconstruct_n( - storage_idx_t n0, - storage_idx_t ni, - float* x) const { -#pragma omp parallel - { - std::vector tmp(index.d); -#pragma omp for - for (storage_idx_t i = 0; i < ni; i++) { - reconstruct(n0 + i, x + i * index.d, tmp.data()); - } - } -} - -size_t ReconstructFromNeighbors::compute_distances( - size_t n, - const idx_t* shortlist, - const float* query, - float* distances) const { - std::vector tmp(2 * index.d); - size_t ncomp = 0; - for (int i = 0; i < n; i++) { - if (shortlist[i] < 0) - break; - reconstruct(shortlist[i], tmp.data(), tmp.data() + index.d); - distances[i] = fvec_L2sqr(query, tmp.data(), index.d); - ncomp++; - } - return ncomp; -} - -void ReconstructFromNeighbors::get_neighbor_table(storage_idx_t i, float* tmp1) - const { - const HNSW& hnsw = index.hnsw; - size_t begin, end; - hnsw.neighbor_range(i, 0, &begin, &end); - size_t d = index.d; - - index.storage->reconstruct(i, tmp1); - - for (size_t j = begin; j < end; j++) { - storage_idx_t ji = hnsw.neighbors[j]; - if (ji < 0) - ji = i; - index.storage->reconstruct(ji, tmp1 + (j - begin + 1) * d); - } -} - -/// called by add_codes -void ReconstructFromNeighbors::estimate_code( - const float* x, - storage_idx_t i, - uint8_t* code) const { - // fill in tmp table with the neighbor values - std::unique_ptr tmp1(new float[d * (M + 1) + (d * k)]); - float* tmp2 = tmp1.get() + d * (M + 1); - - // collect coordinates of base - get_neighbor_table(i, tmp1.get()); - - for (size_t sq = 0; sq < nsq; sq++) { - int d0 = sq * dsub; - - { - FINTEGER ki = k, di = d, m1 = M + 1; - FINTEGER dsubi = dsub; - float zero = 0, one = 1; - - sgemm_("N", - "N", - &dsubi, - &ki, - &m1, - &one, - tmp1.get() + d0, - &di, - codebook.data() + sq * (m1 * k), - &m1, - &zero, - tmp2, - &dsubi); - } - - float min = HUGE_VAL; - int argmin = -1; - for (size_t j = 0; j < k; j++) { - float dis = fvec_L2sqr(x + d0, tmp2 + j * dsub, dsub); - if (dis < min) { - min = dis; - argmin = j; - } - } - code[sq] = argmin; - } -} - -void ReconstructFromNeighbors::add_codes(size_t n, const float* x) { - if (k == 1) { // nothing to encode - ntotal += n; - return; - } - codes.resize(codes.size() + code_size * n); -#pragma omp parallel for - for (int i = 0; i < n; i++) { - estimate_code( - x + i * index.d, - ntotal + i, - codes.data() + (ntotal + i) * code_size); - } - ntotal += n; - FAISS_ASSERT(codes.size() == ntotal * code_size); -} - /************************************************************** * IndexHNSWFlat implementation **************************************************************/ diff --git a/faiss/IndexHNSW.h b/faiss/IndexHNSW.h index 13855d3037..e0b65fca9d 100644 --- a/faiss/IndexHNSW.h +++ b/faiss/IndexHNSW.h @@ -21,49 +21,6 @@ namespace faiss { struct IndexHNSW; -struct ReconstructFromNeighbors { - typedef HNSW::storage_idx_t storage_idx_t; - - const IndexHNSW& index; - size_t M; // number of neighbors - size_t k; // number of codebook entries - size_t nsq; // number of subvectors - size_t code_size; - int k_reorder; // nb to reorder. -1 = all - - std::vector codebook; // size nsq * k * (M + 1) - - std::vector codes; // size ntotal * code_size - size_t ntotal; - size_t d, dsub; // derived values - - explicit ReconstructFromNeighbors( - const IndexHNSW& index, - size_t k = 256, - size_t nsq = 1); - - /// codes must be added in the correct order and the IndexHNSW - /// must be populated and sorted - void add_codes(size_t n, const float* x); - - size_t compute_distances( - size_t n, - const idx_t* shortlist, - const float* query, - float* distances) const; - - /// called by add_codes - void estimate_code(const float* x, storage_idx_t i, uint8_t* code) const; - - /// called by compute_distances - void reconstruct(storage_idx_t i, float* x, float* tmp) const; - - void reconstruct_n(storage_idx_t n0, storage_idx_t ni, float* x) const; - - /// get the M+1 -by-d table for neighbor coordinates for vector i - void get_neighbor_table(storage_idx_t i, float* out) const; -}; - /** The HNSW index is a normal random-access index with a HNSW * link structure built on top */ @@ -77,8 +34,6 @@ struct IndexHNSW : Index { bool own_fields = false; Index* storage = nullptr; - ReconstructFromNeighbors* reconstruct_from_neighbors = nullptr; - explicit IndexHNSW(int d = 0, int M = 32, MetricType metric = METRIC_L2); explicit IndexHNSW(Index* storage, int M = 32); @@ -98,6 +53,13 @@ struct IndexHNSW : Index { idx_t* labels, const SearchParameters* params = nullptr) const override; + void range_search( + idx_t n, + const float* x, + float radius, + RangeSearchResult* result, + const SearchParameters* params = nullptr) const override; + void reconstruct(idx_t key, float* recons) const override; void reset() override; diff --git a/faiss/IndexIVFAdditiveQuantizerFastScan.cpp b/faiss/IndexIVFAdditiveQuantizerFastScan.cpp index 25c3aa2b06..23a2de554d 100644 --- a/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +++ b/faiss/IndexIVFAdditiveQuantizerFastScan.cpp @@ -211,7 +211,8 @@ void IndexIVFAdditiveQuantizerFastScan::estimate_norm_scale( size_t index_nprobe = nprobe; nprobe = 1; - compute_LUT(n, x, coarse_ids.data(), coarse_dis.data(), dis_tables, biases); + CoarseQuantized cq{index_nprobe, coarse_dis.data(), coarse_ids.data()}; + compute_LUT(n, x, cq, dis_tables, biases); nprobe = index_nprobe; float scale = 0; @@ -313,13 +314,8 @@ void IndexIVFAdditiveQuantizerFastScan::search( } NormTableScaler scaler(norm_scale); - if (metric_type == METRIC_L2) { - search_dispatch_implem( - n, x, k, distances, labels, nullptr, nullptr, scaler); - } else { - search_dispatch_implem( - n, x, k, distances, labels, nullptr, nullptr, scaler); - } + IndexIVFFastScan::CoarseQuantized cq{nprobe}; + search_dispatch_implem(n, x, k, distances, labels, cq, &scaler); } /********************************************************* @@ -385,12 +381,12 @@ bool IndexIVFAdditiveQuantizerFastScan::lookup_table_is_3d() const { void IndexIVFAdditiveQuantizerFastScan::compute_LUT( size_t n, const float* x, - const idx_t* coarse_ids, - const float*, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases) const { const size_t dim12 = ksub * M; const size_t ip_dim12 = aq->M * ksub; + const size_t nprobe = cq.nprobe; dis_tables.resize(n * dim12); @@ -411,7 +407,7 @@ void IndexIVFAdditiveQuantizerFastScan::compute_LUT( #pragma omp for for (idx_t ij = 0; ij < n * nprobe; ij++) { int i = ij / nprobe; - quantizer->reconstruct(coarse_ids[ij], c); + quantizer->reconstruct(cq.ids[ij], c); biases[ij] = coef * fvec_inner_product(c, x + i * d, d); } } diff --git a/faiss/IndexIVFAdditiveQuantizerFastScan.h b/faiss/IndexIVFAdditiveQuantizerFastScan.h index 24ce7287ec..643628dec1 100644 --- a/faiss/IndexIVFAdditiveQuantizerFastScan.h +++ b/faiss/IndexIVFAdditiveQuantizerFastScan.h @@ -93,8 +93,7 @@ struct IndexIVFAdditiveQuantizerFastScan : IndexIVFFastScan { void compute_LUT( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases) const override; diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 0b9c4e0992..45dae01f27 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -198,7 +198,7 @@ CodePacker* IndexIVFFastScan::get_CodePacker() const { namespace { -template +template void estimators_from_tables_generic( const IndexIVFFastScan& index, const uint8_t* codes, @@ -209,22 +209,26 @@ void estimators_from_tables_generic( size_t k, typename C::T* heap_dis, int64_t* heap_ids, - const Scaler& scaler) { + const NormTableScaler* scaler) { using accu_t = typename C::T; + int nscale = scaler ? scaler->nscale : 0; for (size_t j = 0; j < ncodes; ++j) { BitstringReader bsr(codes + j * index.code_size, index.code_size); accu_t dis = bias; const dis_t* __restrict dt = dis_table; - for (size_t m = 0; m < index.M - scaler.nscale; m++) { + + for (size_t m = 0; m < index.M - nscale; m++) { uint64_t c = bsr.read(index.nbits); dis += dt[c]; dt += index.ksub; } - for (size_t m = 0; m < scaler.nscale; m++) { - uint64_t c = bsr.read(index.nbits); - dis += scaler.scale_one(dt[c]); - dt += index.ksub; + if (scaler) { + for (size_t m = 0; m < nscale; m++) { + uint64_t c = bsr.read(index.nbits); + dis += scaler->scale_one(dt[c]); + dt += index.ksub; + } } if (C::cmp(heap_dis[0], dis)) { @@ -245,18 +249,15 @@ using namespace quantize_lut; void IndexIVFFastScan::compute_LUT_uint8( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases, float* normalizers) const { AlignedTable dis_tables_float; AlignedTable biases_float; - uint64_t t0 = get_cy(); - compute_LUT(n, x, coarse_ids, coarse_dis, dis_tables_float, biases_float); - IVFFastScan_stats.t_compute_distance_tables += get_cy() - t0; - + compute_LUT(n, x, cq, dis_tables_float, biases_float); + size_t nprobe = cq.nprobe; bool lut_is_3d = lookup_table_is_3d(); size_t dim123 = ksub * M; size_t dim123_2 = ksub * M2; @@ -268,7 +269,6 @@ void IndexIVFFastScan::compute_LUT_uint8( if (biases_float.get()) { biases.resize(n * nprobe); } - uint64_t t1 = get_cy(); #pragma omp parallel for if (n > 100) for (int64_t i = 0; i < n; i++) { @@ -294,7 +294,6 @@ void IndexIVFFastScan::compute_LUT_uint8( normalizers + 2 * i, normalizers + 2 * i + 1); } - IVFFastScan_stats.t_round += get_cy() - t1; } /********************************************************* @@ -308,18 +307,10 @@ void IndexIVFFastScan::search( float* distances, idx_t* labels, const SearchParameters* params) const { - FAISS_THROW_IF_NOT_MSG( - !params, "search params not supported for this index"); - FAISS_THROW_IF_NOT(k > 0); - - DummyScaler scaler; - if (metric_type == METRIC_L2) { - search_dispatch_implem( - n, x, k, distances, labels, nullptr, nullptr, scaler); - } else { - search_dispatch_implem( - n, x, k, distances, labels, nullptr, nullptr, scaler); - } + auto paramsi = dynamic_cast(params); + FAISS_THROW_IF_NOT_MSG(!params || paramsi, "need IVFSearchParameters"); + search_preassigned( + n, x, k, nullptr, nullptr, distances, labels, false, paramsi); } void IndexIVFFastScan::search_preassigned( @@ -333,51 +324,144 @@ void IndexIVFFastScan::search_preassigned( bool store_pairs, const IVFSearchParameters* params, IndexIVFStats* stats) const { - FAISS_THROW_IF_NOT_MSG( - !params, "search params not supported for this index"); + size_t nprobe = this->nprobe; + if (params) { + FAISS_THROW_IF_NOT_MSG( + !params->quantizer_params, "quantizer params not supported"); + FAISS_THROW_IF_NOT(params->max_codes == 0); + nprobe = params->nprobe; + } FAISS_THROW_IF_NOT_MSG( !store_pairs, "store_pairs not supported for this index"); FAISS_THROW_IF_NOT_MSG(!stats, "stats not supported for this index"); FAISS_THROW_IF_NOT(k > 0); - DummyScaler scaler; - if (metric_type == METRIC_L2) { - search_dispatch_implem( - n, x, k, distances, labels, assign, centroid_dis, scaler); + const CoarseQuantized cq = {nprobe, centroid_dis, assign}; + search_dispatch_implem(n, x, k, distances, labels, cq, nullptr); +} + +void IndexIVFFastScan::range_search( + idx_t n, + const float* x, + float radius, + RangeSearchResult* result, + const SearchParameters* params) const { + FAISS_THROW_IF_NOT(!params); + const CoarseQuantized cq = {nprobe, nullptr, nullptr}; + range_search_dispatch_implem(n, x, radius, *result, cq, nullptr); +} + +namespace { + +template +ResultHandlerCompare* make_knn_handler_fixC( + int impl, + idx_t n, + idx_t k, + float* distances, + idx_t* labels) { + using HeapHC = HeapHandler; + using ReservoirHC = ReservoirHandler; + using SingleResultHC = SingleResultHandler; + + if (k == 1) { + return new SingleResultHC(n, 0, distances, labels); + } else if (impl % 2 == 0) { + return new HeapHC(n, 0, k, distances, labels); + } else /* if (impl % 2 == 1) */ { + return new ReservoirHC(n, 0, k, 2 * k, distances, labels); + } +} + +SIMDResultHandlerToFloat* make_knn_handler( + bool is_max, + int impl, + idx_t n, + idx_t k, + float* distances, + idx_t* labels) { + if (is_max) { + return make_knn_handler_fixC>( + impl, n, k, distances, labels); } else { - search_dispatch_implem( - n, x, k, distances, labels, assign, centroid_dis, scaler); + return make_knn_handler_fixC>( + impl, n, k, distances, labels); } } -void IndexIVFFastScan::range_search( - idx_t, - const float*, - float, - RangeSearchResult*, - const SearchParameters*) const { - FAISS_THROW_MSG("not implemented"); +using CoarseQuantized = IndexIVFFastScan::CoarseQuantized; + +struct CoarseQuantizedWithBuffer : CoarseQuantized { + explicit CoarseQuantizedWithBuffer(const CoarseQuantized& cq) + : CoarseQuantized(cq) {} + + bool done() const { + return ids != nullptr; + } + + std::vector ids_buffer; + std::vector dis_buffer; + + void quantize(const Index* quantizer, idx_t n, const float* x) { + dis_buffer.resize(nprobe * n); + ids_buffer.resize(nprobe * n); + quantizer->search(n, x, nprobe, dis_buffer.data(), ids_buffer.data()); + dis = dis_buffer.data(); + ids = ids_buffer.data(); + } +}; + +struct CoarseQuantizedSlice : CoarseQuantizedWithBuffer { + size_t i0, i1; + CoarseQuantizedSlice(const CoarseQuantized& cq, size_t i0, size_t i1) + : CoarseQuantizedWithBuffer(cq), i0(i0), i1(i1) { + if (done()) { + dis += nprobe * i0; + ids += nprobe * i0; + } + } + + void quantize_slice(const Index* quantizer, const float* x) { + quantize(quantizer, i1 - i0, x + quantizer->d * i0); + } +}; + +int compute_search_nslice( + const IndexIVFFastScan* index, + size_t n, + size_t nprobe) { + int nslice; + if (n <= omp_get_max_threads()) { + nslice = n; + } else if (index->lookup_table_is_3d()) { + // make sure we don't make too big LUT tables + size_t lut_size_per_query = index->M * index->ksub * nprobe * + (sizeof(float) + sizeof(uint8_t)); + + size_t max_lut_size = precomputed_table_max_bytes; + // how many queries we can handle within mem budget + size_t nq_ok = std::max(max_lut_size / lut_size_per_query, size_t(1)); + nslice = roundup( + std::max(size_t(n / nq_ok), size_t(1)), omp_get_max_threads()); + } else { + // LUTs unlikely to be a limiting factor + nslice = omp_get_max_threads(); + } + return nslice; } -template +}; // namespace + void IndexIVFFastScan::search_dispatch_implem( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const { - using Cfloat = typename std::conditional< - is_max, - CMax, - CMin>::type; - - using C = typename std::conditional< - is_max, - CMax, - CMin>::type; + const CoarseQuantized& cq_in, + const NormTableScaler* scaler) const { + bool is_max = !is_similarity_metric(metric_type); + using RH = SIMDResultHandlerToFloat; if (n == 0) { return; @@ -392,94 +476,74 @@ void IndexIVFFastScan::search_dispatch_implem( } else { impl = 10; } - if (k > 20) { + if (k > 20) { // use reservoir rather than heap impl++; } } + bool multiple_threads = + n > 1 && impl >= 10 && impl <= 13 && omp_get_max_threads() > 1; + if (impl >= 100) { + multiple_threads = false; + impl -= 100; + } + + CoarseQuantizedWithBuffer cq(cq_in); + + if (!cq.done() && !multiple_threads) { + // we do the coarse quantization here execpt when search is + // sliced over threads (then it is more efficient to have each thread do + // its own coarse quantization) + cq.quantize(quantizer, n, x); + } + if (impl == 1) { - search_implem_1( - n, x, k, distances, labels, coarse_ids, coarse_dis, scaler); + if (is_max) { + search_implem_1>( + n, x, k, distances, labels, cq, scaler); + } else { + search_implem_1>( + n, x, k, distances, labels, cq, scaler); + } } else if (impl == 2) { - search_implem_2( - n, x, k, distances, labels, coarse_ids, coarse_dis, scaler); + if (is_max) { + search_implem_2>( + n, x, k, distances, labels, cq, scaler); + } else { + search_implem_2>( + n, x, k, distances, labels, cq, scaler); + } } else if (impl >= 10 && impl <= 15) { size_t ndis = 0, nlist_visited = 0; - if (n < 2) { + if (!multiple_threads) { + // clang-format off if (impl == 12 || impl == 13) { - search_implem_12( - n, - x, - k, - distances, - labels, - coarse_ids, - coarse_dis, - impl, - &ndis, - &nlist_visited, - scaler); + std::unique_ptr handler(make_knn_handler(is_max, impl, n, k, distances, labels)); + search_implem_12( + n, x, *handler.get(), + cq, &ndis, &nlist_visited, scaler); + } else if (impl == 14 || impl == 15) { - search_implem_14( - n, - x, - k, - distances, - labels, - coarse_ids, - coarse_dis, - impl, - scaler); + + search_implem_14( + n, x, k, distances, labels, + cq, impl, scaler); } else { - search_implem_10( - n, - x, - k, - distances, - labels, - coarse_ids, - coarse_dis, - impl, - &ndis, - &nlist_visited, - scaler); + std::unique_ptr handler(make_knn_handler(is_max, impl, n, k, distances, labels)); + search_implem_10( + n, x, *handler.get(), cq, + &ndis, &nlist_visited, scaler); } + // clang-format on } else { // explicitly slice over threads - int nslice; - if (n <= omp_get_max_threads()) { - nslice = n; - } else if (lookup_table_is_3d()) { - // make sure we don't make too big LUT tables - size_t lut_size_per_query = - M * ksub * nprobe * (sizeof(float) + sizeof(uint8_t)); - - size_t max_lut_size = precomputed_table_max_bytes; - // how many queries we can handle within mem budget - size_t nq_ok = - std::max(max_lut_size / lut_size_per_query, size_t(1)); - nslice = - roundup(std::max(size_t(n / nq_ok), size_t(1)), - omp_get_max_threads()); - } else { - // LUTs unlikely to be a limiting factor - nslice = omp_get_max_threads(); - } - if (impl == 14 || - impl == 15) { // this might require slicing if there are too - // many queries (for now we keep this simple) - search_implem_14( - n, - x, - k, - distances, - labels, - coarse_ids, - coarse_dis, - impl, - scaler); + int nslice = compute_search_nslice(this, n, cq.nprobe); + if (impl == 14 || impl == 15) { + // this might require slicing if there are too + // many queries (for now we keep this simple) + search_implem_14(n, x, k, distances, labels, cq, impl, scaler); } else { #pragma omp parallel for reduction(+ : ndis, nlist_visited) for (int slice = 0; slice < nslice; slice++) { @@ -487,39 +551,23 @@ void IndexIVFFastScan::search_dispatch_implem( idx_t i1 = n * (slice + 1) / nslice; float* dis_i = distances + i0 * k; idx_t* lab_i = labels + i0 * k; - const idx_t* coarse_ids_i = coarse_ids != nullptr - ? coarse_ids + i0 * nprobe - : nullptr; - const float* coarse_dis_i = coarse_dis != nullptr - ? coarse_dis + i0 * nprobe - : nullptr; + CoarseQuantizedSlice cq_i(cq, i0, i1); + if (!cq_i.done()) { + cq_i.quantize_slice(quantizer, x); + } + std::unique_ptr handler(make_knn_handler( + is_max, impl, i1 - i0, k, dis_i, lab_i)); + // clang-format off if (impl == 12 || impl == 13) { - search_implem_12( - i1 - i0, - x + i0 * d, - k, - dis_i, - lab_i, - coarse_ids_i, - coarse_dis_i, - impl, - &ndis, - &nlist_visited, - scaler); + search_implem_12( + i1 - i0, x + i0 * d, *handler.get(), + cq_i, &ndis, &nlist_visited, scaler); } else { - search_implem_10( - i1 - i0, - x + i0 * d, - k, - dis_i, - lab_i, - coarse_ids_i, - coarse_dis_i, - impl, - &ndis, - &nlist_visited, - scaler); + search_implem_10( + i1 - i0, x + i0 * d, *handler.get(), + cq_i, &ndis, &nlist_visited, scaler); } + // clang-format on } } } @@ -531,46 +579,139 @@ void IndexIVFFastScan::search_dispatch_implem( } } -#define COARSE_QUANTIZE \ - std::unique_ptr coarse_ids_buffer; \ - std::unique_ptr coarse_dis_buffer; \ - if (coarse_ids == nullptr || coarse_dis == nullptr) { \ - coarse_ids_buffer.reset(new idx_t[n * nprobe]); \ - coarse_dis_buffer.reset(new float[n * nprobe]); \ - quantizer->search( \ - n, \ - x, \ - nprobe, \ - coarse_dis_buffer.get(), \ - coarse_ids_buffer.get()); \ - coarse_ids = coarse_ids_buffer.get(); \ - coarse_dis = coarse_dis_buffer.get(); \ +void IndexIVFFastScan::range_search_dispatch_implem( + idx_t n, + const float* x, + float radius, + RangeSearchResult& rres, + const CoarseQuantized& cq_in, + const NormTableScaler* scaler) const { + bool is_max = !is_similarity_metric(metric_type); + + if (n == 0) { + return; + } + + // actual implementation used + int impl = implem; + + if (impl == 0) { + if (bbs == 32) { + impl = 12; + } else { + impl = 10; + } + } + + CoarseQuantizedWithBuffer cq(cq_in); + + bool multiple_threads = + n > 1 && impl >= 10 && impl <= 13 && omp_get_max_threads() > 1; + if (impl >= 100) { + multiple_threads = false; + impl -= 100; + } + + if (!multiple_threads && !cq.done()) { + cq.quantize(quantizer, n, x); } -template + size_t ndis = 0, nlist_visited = 0; + + if (!multiple_threads) { // single thread + std::unique_ptr handler; + if (is_max) { + handler.reset(new RangeHandler, true>( + rres, radius, 0)); + } else { + handler.reset(new RangeHandler, true>( + rres, radius, 0)); + } + if (impl == 12) { + search_implem_12( + n, x, *handler.get(), cq, &ndis, &nlist_visited, scaler); + } else if (impl == 10) { + search_implem_10( + n, x, *handler.get(), cq, &ndis, &nlist_visited, scaler); + } else { + FAISS_THROW_FMT("Range search implem %d not impemented", impl); + } + } else { + // explicitly slice over threads + int nslice = compute_search_nslice(this, n, cq.nprobe); +#pragma omp parallel + { + RangeSearchPartialResult pres(&rres); + +#pragma omp parallel for reduction(+ : ndis, nlist_visited) + for (int slice = 0; slice < nslice; slice++) { + idx_t i0 = n * slice / nslice; + idx_t i1 = n * (slice + 1) / nslice; + CoarseQuantizedSlice cq_i(cq, i0, i1); + if (!cq_i.done()) { + cq_i.quantize_slice(quantizer, x); + } + std::unique_ptr handler; + if (is_max) { + handler.reset(new PartialRangeHandler< + CMax, + true>(pres, radius, 0, i0, i1)); + } else { + handler.reset(new PartialRangeHandler< + CMin, + true>(pres, radius, 0, i0, i1)); + } + + if (impl == 12 || impl == 13) { + search_implem_12( + i1 - i0, + x + i0 * d, + *handler.get(), + cq_i, + &ndis, + &nlist_visited, + scaler); + } else { + search_implem_10( + i1 - i0, + x + i0 * d, + *handler.get(), + cq_i, + &ndis, + &nlist_visited, + scaler); + } + } + pres.finalize(); + } + } + + indexIVF_stats.nq += n; + indexIVF_stats.ndis += ndis; + indexIVF_stats.nlist += nlist_visited; +} + +template void IndexIVFFastScan::search_implem_1( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const { + const CoarseQuantized& cq, + const NormTableScaler* scaler) const { FAISS_THROW_IF_NOT(orig_invlists); - COARSE_QUANTIZE; - size_t dim12 = ksub * M; AlignedTable dis_tables; AlignedTable biases; - compute_LUT(n, x, coarse_ids, coarse_dis, dis_tables, biases); + compute_LUT(n, x, cq, dis_tables, biases); bool single_LUT = !lookup_table_is_3d(); size_t ndis = 0, nlist_visited = 0; - + size_t nprobe = cq.nprobe; #pragma omp parallel for reduction(+ : ndis, nlist_visited) for (idx_t i = 0; i < n; i++) { int64_t* heap_ids = labels + i * k; @@ -585,7 +726,7 @@ void IndexIVFFastScan::search_implem_1( if (!single_LUT) { LUT = dis_tables.get() + (i * nprobe + j) * dim12; } - idx_t list_no = coarse_ids[i * nprobe + j]; + idx_t list_no = cq.ids[i * nprobe + j]; if (list_no < 0) continue; size_t ls = orig_invlists->list_size(list_no); @@ -617,36 +758,28 @@ void IndexIVFFastScan::search_implem_1( indexIVF_stats.nlist += nlist_visited; } -template +template void IndexIVFFastScan::search_implem_2( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const { + const CoarseQuantized& cq, + const NormTableScaler* scaler) const { FAISS_THROW_IF_NOT(orig_invlists); - COARSE_QUANTIZE; size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; std::unique_ptr normalizers(new float[2 * n]); - compute_LUT_uint8( - n, - x, - coarse_ids, - coarse_dis, - dis_tables, - biases, - normalizers.get()); + compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get()); bool single_LUT = !lookup_table_is_3d(); size_t ndis = 0, nlist_visited = 0; + size_t nprobe = cq.nprobe; #pragma omp parallel for reduction(+ : ndis, nlist_visited) for (idx_t i = 0; i < n; i++) { @@ -663,7 +796,7 @@ void IndexIVFFastScan::search_implem_2( if (!single_LUT) { LUT = dis_tables.get() + (i * nprobe + j) * dim12; } - idx_t list_no = coarse_ids[i * nprobe + j]; + idx_t list_no = cq.ids[i * nprobe + j]; if (list_no < 0) continue; size_t ls = orig_invlists->list_size(list_no); @@ -708,169 +841,100 @@ void IndexIVFFastScan::search_implem_2( indexIVF_stats.nlist += nlist_visited; } -template void IndexIVFFastScan::search_implem_10( idx_t n, const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - int impl, + SIMDResultHandlerToFloat& handler, + const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const Scaler& scaler) const { - memset(distances, -1, sizeof(float) * k * n); - memset(labels, -1, sizeof(idx_t) * k * n); - - using HeapHC = HeapHandler; - using ReservoirHC = ReservoirHandler; - using SingleResultHC = SingleResultHandler; - - uint64_t times[10]; - memset(times, 0, sizeof(times)); - int ti = 0; -#define TIC times[ti++] = get_cy() - TIC; - - COARSE_QUANTIZE; - - TIC; - + const NormTableScaler* scaler) const { size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; std::unique_ptr normalizers(new float[2 * n]); - compute_LUT_uint8( - n, - x, - coarse_ids, - coarse_dis, - dis_tables, - biases, - normalizers.get()); - - TIC; + compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get()); bool single_LUT = !lookup_table_is_3d(); - TIC; size_t ndis = 0, nlist_visited = 0; + int qmap1[1]; - { - AlignedTable tmp_distances(k); - for (idx_t i = 0; i < n; i++) { - const uint8_t* LUT = nullptr; - int qmap1[1] = {0}; - std::unique_ptr> handler; - - if (k == 1) { - handler.reset(new SingleResultHC(1, 0)); - } else if (impl == 10) { - handler.reset(new HeapHC( - 1, tmp_distances.get(), labels + i * k, k, 0)); - } else if (impl == 11) { - handler.reset(new ReservoirHC(1, 0, k, 2 * k)); - } else { - FAISS_THROW_MSG("invalid"); - } + handler.q_map = qmap1; + handler.begin(skip & 16 ? nullptr : normalizers.get()); + size_t nprobe = cq.nprobe; - handler->q_map = qmap1; + for (idx_t i = 0; i < n; i++) { + const uint8_t* LUT = nullptr; + qmap1[0] = i; - if (single_LUT) { - LUT = dis_tables.get() + i * dim12; + if (single_LUT) { + LUT = dis_tables.get() + i * dim12; + } + for (idx_t j = 0; j < nprobe; j++) { + size_t ij = i * nprobe + j; + if (!single_LUT) { + LUT = dis_tables.get() + ij * dim12; + } + if (biases.get()) { + handler.dbias = biases.get() + ij; } - for (idx_t j = 0; j < nprobe; j++) { - size_t ij = i * nprobe + j; - if (!single_LUT) { - LUT = dis_tables.get() + ij * dim12; - } - if (biases.get()) { - handler->dbias = biases.get() + ij; - } - - idx_t list_no = coarse_ids[ij]; - if (list_no < 0) - continue; - size_t ls = invlists->list_size(list_no); - if (ls == 0) - continue; - InvertedLists::ScopedCodes codes(invlists, list_no); - InvertedLists::ScopedIds ids(invlists, list_no); + idx_t list_no = cq.ids[ij]; + if (list_no < 0) { + continue; + } + size_t ls = invlists->list_size(list_no); + if (ls == 0) { + continue; + } - handler->ntotal = ls; - handler->id_map = ids.get(); + InvertedLists::ScopedCodes codes(invlists, list_no); + InvertedLists::ScopedIds ids(invlists, list_no); -#define DISPATCH(classHC) \ - if (dynamic_cast(handler.get())) { \ - auto* res = static_cast(handler.get()); \ - pq4_accumulate_loop( \ - 1, roundup(ls, bbs), bbs, M2, codes.get(), LUT, *res, scaler); \ - } - DISPATCH(HeapHC) - else DISPATCH(ReservoirHC) else DISPATCH(SingleResultHC) -#undef DISPATCH + handler.ntotal = ls; + handler.id_map = ids.get(); - nlist_visited++; - ndis++; - } + pq4_accumulate_loop( + 1, + roundup(ls, bbs), + bbs, + M2, + codes.get(), + LUT, + handler, + scaler); - handler->to_flat_arrays( - distances + i * k, - labels + i * k, - skip & 16 ? nullptr : normalizers.get() + i * 2); + nlist_visited++; + ndis++; } } + handler.end(); *ndis_out = ndis; *nlist_out = nlist; } -template void IndexIVFFastScan::search_implem_12( idx_t n, const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - int impl, + SIMDResultHandlerToFloat& handler, + const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { if (n == 0) { // does not work well with reservoir return; } FAISS_THROW_IF_NOT(bbs == 32); - uint64_t times[10]; - memset(times, 0, sizeof(times)); - int ti = 0; -#define TIC times[ti++] = get_cy() - TIC; - - COARSE_QUANTIZE; - - TIC; - size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; std::unique_ptr normalizers(new float[2 * n]); - compute_LUT_uint8( - n, - x, - coarse_ids, - coarse_dis, - dis_tables, - biases, - normalizers.get()); - - TIC; + compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get()); + handler.begin(skip & 16 ? nullptr : normalizers.get()); struct QC { int qno; // sequence number of the query @@ -878,14 +942,15 @@ void IndexIVFFastScan::search_implem_12( int rank; // this is the rank'th result of the coarse quantizer }; bool single_LUT = !lookup_table_is_3d(); + size_t nprobe = cq.nprobe; std::vector qcs; { int ij = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < nprobe; j++) { - if (coarse_ids[ij] >= 0) { - qcs.push_back(QC{i, int(coarse_ids[ij]), int(j)}); + if (cq.ids[ij] >= 0) { + qcs.push_back(QC{i, int(cq.ids[ij]), int(j)}); } ij++; } @@ -894,42 +959,21 @@ void IndexIVFFastScan::search_implem_12( return a.list_no < b.list_no; }); } - TIC; - // prepare the result handlers - std::unique_ptr> handler; - AlignedTable tmp_distances; - - using HeapHC = HeapHandler; - using ReservoirHC = ReservoirHandler; - using SingleResultHC = SingleResultHandler; - - if (k == 1) { - handler.reset(new SingleResultHC(n, 0)); - } else if (impl == 12) { - tmp_distances.resize(n * k); - handler.reset(new HeapHC(n, tmp_distances.get(), labels, k, 0)); - } else if (impl == 13) { - handler.reset(new ReservoirHC(n, 0, k, 2 * k)); - } - int qbs2 = this->qbs2 ? this->qbs2 : 11; std::vector tmp_bias; if (biases.get()) { tmp_bias.resize(qbs2); - handler->dbias = tmp_bias.data(); + handler.dbias = tmp_bias.data(); } - TIC; size_t ndis = 0; size_t i0 = 0; uint64_t t_copy_pack = 0, t_scan = 0; while (i0 < qcs.size()) { - uint64_t tt0 = get_cy(); - // find all queries that access this inverted list int list_no = qcs[i0].list_no; size_t i1 = i0 + 1; @@ -977,92 +1021,47 @@ void IndexIVFFastScan::search_implem_12( // prepare the handler - handler->ntotal = list_size; - handler->q_map = q_map.data(); - handler->id_map = ids.get(); - uint64_t tt1 = get_cy(); - -#define DISPATCH(classHC) \ - if (dynamic_cast(handler.get())) { \ - auto* res = static_cast(handler.get()); \ - pq4_accumulate_loop_qbs( \ - qbs, list_size, M2, codes.get(), LUT.get(), *res, scaler); \ - } - DISPATCH(HeapHC) - else DISPATCH(ReservoirHC) else DISPATCH(SingleResultHC) - - // prepare for next loop - i0 = i1; + handler.ntotal = list_size; + handler.q_map = q_map.data(); + handler.id_map = ids.get(); - uint64_t tt2 = get_cy(); - t_copy_pack += tt1 - tt0; - t_scan += tt2 - tt1; + pq4_accumulate_loop_qbs( + qbs, list_size, M2, codes.get(), LUT.get(), handler, scaler); + // prepare for next loop + i0 = i1; } - TIC; - - // labels is in-place for HeapHC - handler->to_flat_arrays( - distances, labels, skip & 16 ? nullptr : normalizers.get()); - TIC; + handler.end(); // these stats are not thread-safe - for (int i = 1; i < ti; i++) { - IVFFastScan_stats.times[i] += times[i] - times[i - 1]; - } IVFFastScan_stats.t_copy_pack += t_copy_pack; IVFFastScan_stats.t_scan += t_scan; - if (auto* rh = dynamic_cast(handler.get())) { - for (int i = 0; i < 4; i++) { - IVFFastScan_stats.reservoir_times[i] += rh->times[i]; - } - } - *ndis_out = ndis; *nlist_out = nlist; } -template void IndexIVFFastScan::search_implem_14( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, int impl, - const Scaler& scaler) const { + const NormTableScaler* scaler) const { if (n == 0) { // does not work well with reservoir return; } FAISS_THROW_IF_NOT(bbs == 32); - uint64_t ttg0 = get_cy(); - - COARSE_QUANTIZE; - - uint64_t ttg1 = get_cy(); - uint64_t coarse_search_tt = ttg1 - ttg0; - size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; std::unique_ptr normalizers(new float[2 * n]); - compute_LUT_uint8( - n, - x, - coarse_ids, - coarse_dis, - dis_tables, - biases, - normalizers.get()); - - uint64_t ttg2 = get_cy(); - uint64_t lut_compute_tt = ttg2 - ttg1; + compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get()); struct QC { int qno; // sequence number of the query @@ -1070,14 +1069,15 @@ void IndexIVFFastScan::search_implem_14( int rank; // this is the rank'th result of the coarse quantizer }; bool single_LUT = !lookup_table_is_3d(); + size_t nprobe = cq.nprobe; std::vector qcs; { int ij = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < nprobe; j++) { - if (coarse_ids[ij] >= 0) { - qcs.push_back(QC{i, int(coarse_ids[ij]), int(j)}); + if (cq.ids[ij] >= 0) { + qcs.push_back(QC{i, int(cq.ids[ij]), int(j)}); } ij++; } @@ -1115,14 +1115,13 @@ void IndexIVFFastScan::search_implem_14( ses.push_back(SE{i0_l, i1, list_size}); i0_l = i1; } - uint64_t ttg3 = get_cy(); - uint64_t compute_clusters_tt = ttg3 - ttg2; // function to handle the global heap + bool is_max = !is_similarity_metric(metric_type); using HeapForIP = CMin; using HeapForL2 = CMax; auto init_result = [&](float* simi, idx_t* idxi) { - if (metric_type == METRIC_INNER_PRODUCT) { + if (!is_max) { heap_heapify(k, simi, idxi); } else { heap_heapify(k, simi, idxi); @@ -1133,7 +1132,7 @@ void IndexIVFFastScan::search_implem_14( const idx_t* local_idx, float* simi, idx_t* idxi) { - if (metric_type == METRIC_INNER_PRODUCT) { + if (!is_max) { heap_addn(k, simi, idxi, local_dis, local_idx, k); } else { heap_addn(k, simi, idxi, local_dis, local_idx, k); @@ -1141,14 +1140,12 @@ void IndexIVFFastScan::search_implem_14( }; auto reorder_result = [&](float* simi, idx_t* idxi) { - if (metric_type == METRIC_INNER_PRODUCT) { + if (!is_max) { heap_reorder(k, simi, idxi); } else { heap_reorder(k, simi, idxi); } }; - uint64_t ttg4 = get_cy(); - uint64_t fn_tt = ttg4 - ttg3; size_t ndis = 0; size_t nlist_visited = 0; @@ -1160,22 +1157,9 @@ void IndexIVFFastScan::search_implem_14( std::vector local_dis(k * n); // prepare the result handlers - std::unique_ptr> handler; - AlignedTable tmp_distances; - - using HeapHC = HeapHandler; - using ReservoirHC = ReservoirHandler; - using SingleResultHC = SingleResultHandler; - - if (k == 1) { - handler.reset(new SingleResultHC(n, 0)); - } else if (impl == 14) { - tmp_distances.resize(n * k); - handler.reset( - new HeapHC(n, tmp_distances.get(), local_idx.data(), k, 0)); - } else if (impl == 15) { - handler.reset(new ReservoirHC(n, 0, k, 2 * k)); - } + std::unique_ptr handler(make_knn_handler( + is_max, impl, n, k, local_dis.data(), local_idx.data())); + handler->begin(normalizers.get()); int qbs2 = this->qbs2 ? this->qbs2 : 11; @@ -1184,15 +1168,10 @@ void IndexIVFFastScan::search_implem_14( tmp_bias.resize(qbs2); handler->dbias = tmp_bias.data(); } - - uint64_t ttg5 = get_cy(); - uint64_t handler_tt = ttg5 - ttg4; - std::set q_set; uint64_t t_copy_pack = 0, t_scan = 0; #pragma omp for schedule(dynamic) for (idx_t cluster = 0; cluster < ses.size(); cluster++) { - uint64_t tt0 = get_cy(); size_t i0 = ses[cluster].start; size_t i1 = ses[cluster].end; size_t list_size = ses[cluster].list_size; @@ -1232,28 +1211,21 @@ void IndexIVFFastScan::search_implem_14( handler->ntotal = list_size; handler->q_map = q_map.data(); handler->id_map = ids.get(); - uint64_t tt1 = get_cy(); -#define DISPATCH(classHC) \ - if (dynamic_cast(handler.get())) { \ - auto* res = static_cast(handler.get()); \ - pq4_accumulate_loop_qbs( \ - qbs, list_size, M2, codes.get(), LUT.get(), *res, scaler); \ - } - DISPATCH(HeapHC) - else DISPATCH(ReservoirHC) else DISPATCH(SingleResultHC) - - uint64_t tt2 = get_cy(); - t_copy_pack += tt1 - tt0; - t_scan += tt2 - tt1; + pq4_accumulate_loop_qbs( + qbs, + list_size, + M2, + codes.get(), + LUT.get(), + *handler.get(), + scaler); } // labels is in-place for HeapHC - handler->to_flat_arrays( - local_dis.data(), - local_idx.data(), - skip & 16 ? nullptr : normalizers.get()); + handler->end(); + // merge per-thread results #pragma omp single { // we init the results as a heap @@ -1276,12 +1248,6 @@ void IndexIVFFastScan::search_implem_14( IVFFastScan_stats.t_copy_pack += t_copy_pack; IVFFastScan_stats.t_scan += t_scan; - - if (auto* rh = dynamic_cast(handler.get())) { - for (int i = 0; i < 4; i++) { - IVFFastScan_stats.reservoir_times[i] += rh->times[i]; - } - } } #pragma omp barrier #pragma omp single @@ -1351,24 +1317,4 @@ void IndexIVFFastScan::reconstruct_orig_invlists() { IVFFastScanStats IVFFastScan_stats; -template void IndexIVFFastScan::search_dispatch_implem( - idx_t n, - const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const NormTableScaler& scaler) const; - -template void IndexIVFFastScan::search_dispatch_implem( - idx_t n, - const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const NormTableScaler& scaler) const; - } // namespace faiss diff --git a/faiss/IndexIVFFastScan.h b/faiss/IndexIVFFastScan.h index 824e63ed28..159a3a7098 100644 --- a/faiss/IndexIVFFastScan.h +++ b/faiss/IndexIVFFastScan.h @@ -14,6 +14,9 @@ namespace faiss { +struct NormTableScaler; +struct SIMDResultHandlerToFloat; + /** Fast scan version of IVFPQ and IVFAQ. Works for 4-bit PQ/AQ for now. * * The codes in the inverted lists are not stored sequentially but @@ -28,6 +31,12 @@ namespace faiss { * 11: idem, collect results in reservoir * 12: optimizer int16 search, collect results in heap, uses qbs * 13: idem, collect results in reservoir + * 14: internally multithreaded implem over nq * nprobe + * 15: same with reservoir + * + * For range search, only 10 and 12 are supported. + * add 100 to the implem to force single-thread scanning (the coarse quantizer + * may still use multiple threads). */ struct IndexIVFFastScan : IndexIVF { @@ -80,19 +89,24 @@ struct IndexIVFFastScan : IndexIVF { virtual bool lookup_table_is_3d() const = 0; + // compact way of conveying coarse quantization results + struct CoarseQuantized { + size_t nprobe; + const float* dis = nullptr; + const idx_t* ids = nullptr; + }; + virtual void compute_LUT( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases) const = 0; void compute_LUT_uint8( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases, float* normalizers) const; @@ -117,7 +131,6 @@ struct IndexIVFFastScan : IndexIVF { const IVFSearchParameters* params = nullptr, IndexIVFStats* stats = nullptr) const override; - /// will just fail void range_search( idx_t n, const float* x, @@ -127,81 +140,75 @@ struct IndexIVFFastScan : IndexIVF { // internal search funcs - template + // dispatch to implementations and parallelize void search_dispatch_implem( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const; + const CoarseQuantized& cq, + const NormTableScaler* scaler) const; + + void range_search_dispatch_implem( + idx_t n, + const float* x, + float radius, + RangeSearchResult& rres, + const CoarseQuantized& cq_in, + const NormTableScaler* scaler) const; - template + // impl 1 and 2 are just for verification + template void search_implem_1( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const; + const CoarseQuantized& cq, + const NormTableScaler* scaler) const; - template + template void search_implem_2( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - const Scaler& scaler) const; + const CoarseQuantized& cq, + const NormTableScaler* scaler) const; // implem 10 and 12 are not multithreaded internally, so // export search stats - template void search_implem_10( idx_t n, const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - int impl, + SIMDResultHandlerToFloat& handler, + const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; - template void search_implem_12( idx_t n, const float* x, - idx_t k, - float* distances, - idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, - int impl, + SIMDResultHandlerToFloat& handler, + const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; // implem 14 is multithreaded internally across nprobes and queries - template void search_implem_14( idx_t n, const float* x, idx_t k, float* distances, idx_t* labels, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, int impl, - const Scaler& scaler) const; + const NormTableScaler* scaler) const; // reconstruct vectors from packed invlists void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons) diff --git a/faiss/IndexIVFPQ.cpp b/faiss/IndexIVFPQ.cpp index c433991c9b..6de78b9539 100644 --- a/faiss/IndexIVFPQ.cpp +++ b/faiss/IndexIVFPQ.cpp @@ -749,7 +749,7 @@ struct QueryTables { } }; -// This way of handling the sleector is not optimal since all distances +// This way of handling the selector is not optimal since all distances // are computed even if the id would filter it out. template struct KnnSearchResults { diff --git a/faiss/IndexIVFPQFastScan.cpp b/faiss/IndexIVFPQFastScan.cpp index b44b71ec67..d069db1354 100644 --- a/faiss/IndexIVFPQFastScan.cpp +++ b/faiss/IndexIVFPQFastScan.cpp @@ -171,7 +171,7 @@ void IndexIVFPQFastScan::encode_vectors( * Look-Up Table functions *********************************************************/ -void fvec_madd_avx( +void fvec_madd_simd( size_t n, const float* a, float bf, @@ -202,12 +202,12 @@ bool IndexIVFPQFastScan::lookup_table_is_3d() const { void IndexIVFPQFastScan::compute_LUT( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases) const { size_t dim12 = pq.ksub * pq.M; size_t d = pq.d; + size_t nprobe = this->nprobe; if (by_residual) { if (metric_type == METRIC_L2) { @@ -215,7 +215,7 @@ void IndexIVFPQFastScan::compute_LUT( if (use_precomputed_table == 1) { biases.resize(n * nprobe); - memcpy(biases.get(), coarse_dis, sizeof(float) * n * nprobe); + memcpy(biases.get(), cq.dis, sizeof(float) * n * nprobe); AlignedTable ip_table(n * dim12); pq.compute_inner_prod_tables(n, x, ip_table.get()); @@ -224,10 +224,10 @@ void IndexIVFPQFastScan::compute_LUT( for (idx_t ij = 0; ij < n * nprobe; ij++) { idx_t i = ij / nprobe; float* tab = dis_tables.get() + ij * dim12; - idx_t cij = coarse_ids[ij]; + idx_t cij = cq.ids[ij]; if (cij >= 0) { - fvec_madd_avx( + fvec_madd_simd( dim12, precomputed_table.get() + cij * dim12, -2, @@ -249,7 +249,7 @@ void IndexIVFPQFastScan::compute_LUT( for (idx_t ij = 0; ij < n * nprobe; ij++) { idx_t i = ij / nprobe; float* xij = &xrel[ij * d]; - idx_t cij = coarse_ids[ij]; + idx_t cij = cq.ids[ij]; if (cij >= 0) { quantizer->compute_residual(x + i * d, xij, cij); @@ -269,7 +269,7 @@ void IndexIVFPQFastScan::compute_LUT( // compute_inner_prod_tables(pq, n, x, dis_tables.get()); biases.resize(n * nprobe); - memcpy(biases.get(), coarse_dis, sizeof(float) * n * nprobe); + memcpy(biases.get(), cq.dis, sizeof(float) * n * nprobe); } else { FAISS_THROW_FMT("metric %d not supported", metric_type); } diff --git a/faiss/IndexIVFPQFastScan.h b/faiss/IndexIVFPQFastScan.h index 9a79833591..00dd2f11dd 100644 --- a/faiss/IndexIVFPQFastScan.h +++ b/faiss/IndexIVFPQFastScan.h @@ -77,8 +77,7 @@ struct IndexIVFPQFastScan : IndexIVFFastScan { void compute_LUT( size_t n, const float* x, - const idx_t* coarse_ids, - const float* coarse_dis, + const CoarseQuantized& cq, AlignedTable& dis_tables, AlignedTable& biases) const override; diff --git a/faiss/impl/AuxIndexStructures.h b/faiss/impl/AuxIndexStructures.h index 344a708b78..f8b5cca842 100644 --- a/faiss/impl/AuxIndexStructures.h +++ b/faiss/impl/AuxIndexStructures.h @@ -41,7 +41,6 @@ struct RangeSearchResult { /// called when lims contains the nb of elements result entries /// for each query - virtual void do_allocation(); virtual ~RangeSearchResult(); diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index 9fc201ea39..8c4c5be87f 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -14,6 +12,7 @@ #include #include #include +#include #include #include @@ -513,17 +512,15 @@ void HNSW::add_with_locks( **************************************************************/ namespace { - using MinimaxHeap = HNSW::MinimaxHeap; using Node = HNSW::Node; +using C = HNSW::C; /** Do a BFS on the candidates list */ int search_from_candidates( const HNSW& hnsw, DistanceComputer& qdis, - int k, - idx_t* I, - float* D, + ResultHandler& res, MinimaxHeap& candidates, VisitedTable& vt, HNSWStats& stats, @@ -539,15 +536,16 @@ int search_from_candidates( int efSearch = params ? params->efSearch : hnsw.efSearch; const IDSelector* sel = params ? params->sel : nullptr; + C::T threshold = res.threshold; for (int i = 0; i < candidates.size(); i++) { idx_t v1 = candidates.ids[i]; float d = candidates.dis[i]; FAISS_ASSERT(v1 >= 0); if (!sel || sel->is_member(v1)) { - if (nres < k) { - faiss::maxheap_push(++nres, D, I, d, v1); - } else if (d < D[0]) { - faiss::maxheap_replace_top(nres, D, I, d, v1); + if (d < threshold) { + if (res.add_result(d, v1)) { + threshold = res.threshold; + } } } vt.set(v1); @@ -609,13 +607,14 @@ int search_from_candidates( size_t saved_j[4]; ndis += jmax - begin; + threshold = res.threshold; auto add_to_heap = [&](const size_t idx, const float dis) { if (!sel || sel->is_member(idx)) { - if (nres < k) { - faiss::maxheap_push(++nres, D, I, dis, idx); - } else if (dis < D[0]) { - faiss::maxheap_replace_top(nres, D, I, dis, idx); + if (dis < threshold) { + if (res.add_result(dis, idx)) { + threshold = res.threshold; + } } } candidates.push(idx, dis); @@ -799,19 +798,28 @@ std::priority_queue search_from_candidate_unbounded( return top_candidates; } +// just used as a lower bound for the minmaxheap, but it is set for heap search +int extract_k_from_ResultHandler(ResultHandler& res) { + using RH = HeapBlockResultHandler; + if (auto hres = dynamic_cast(&res)) { + return hres->k; + } + return 1; +} + } // anonymous namespace HNSWStats HNSW::search( DistanceComputer& qdis, - int k, - idx_t* I, - float* D, + ResultHandler& res, VisitedTable& vt, const SearchParametersHNSW* params) const { HNSWStats stats; if (entry_point == -1) { return stats; } + int k = extract_k_from_ResultHandler(res); + if (upper_beam == 1) { // greedy search on upper levels storage_idx_t nearest = entry_point; @@ -828,7 +836,7 @@ HNSWStats HNSW::search( candidates.push(nearest, d_nearest); search_from_candidates( - *this, qdis, k, I, D, candidates, vt, stats, 0, 0, params); + *this, qdis, res, candidates, vt, stats, 0, 0, params); } else { std::priority_queue top_candidates = search_from_candidate_unbounded( @@ -848,7 +856,8 @@ HNSWStats HNSW::search( float d; storage_idx_t label; std::tie(d, label) = top_candidates.top(); - faiss::maxheap_push(++nres, D, I, d, label); + res.add_result(d, label); + nres++; top_candidates.pop(); } } @@ -862,6 +871,10 @@ HNSWStats HNSW::search( std::vector I_to_next(candidates_size); std::vector D_to_next(candidates_size); + HeapBlockResultHandler block_resh( + 1, D_to_next.data(), I_to_next.data(), candidates_size); + HeapBlockResultHandler::SingleResultHandler resh(block_resh); + int nres = 1; I_to_next[0] = entry_point; D_to_next[0] = qdis(entry_point); @@ -877,18 +890,12 @@ HNSWStats HNSW::search( if (level == 0) { nres = search_from_candidates( - *this, qdis, k, I, D, candidates, vt, stats, 0); + *this, qdis, res, candidates, vt, stats, 0); } else { + resh.begin(0); nres = search_from_candidates( - *this, - qdis, - candidates_size, - I_to_next.data(), - D_to_next.data(), - candidates, - vt, - stats, - level); + *this, qdis, resh, candidates, vt, stats, level); + resh.end(); } vt.advance(); } @@ -899,9 +906,7 @@ HNSWStats HNSW::search( void HNSW::search_level_0( DistanceComputer& qdis, - int k, - idx_t* idxi, - float* simi, + ResultHandler& res, idx_t nprobe, const storage_idx_t* nearest_i, const float* nearest_d, @@ -909,7 +914,7 @@ void HNSW::search_level_0( HNSWStats& search_stats, VisitedTable& vt) const { const HNSW& hnsw = *this; - + int k = extract_k_from_ResultHandler(res); if (search_type == 1) { int nres = 0; @@ -922,22 +927,13 @@ void HNSW::search_level_0( if (vt.get(cj)) continue; - int candidates_size = std::max(hnsw.efSearch, int(k)); + int candidates_size = std::max(hnsw.efSearch, k); MinimaxHeap candidates(candidates_size); candidates.push(cj, nearest_d[j]); nres = search_from_candidates( - hnsw, - qdis, - k, - idxi, - simi, - candidates, - vt, - search_stats, - 0, - nres); + hnsw, qdis, res, candidates, vt, search_stats, 0, nres); } } else if (search_type == 2) { int candidates_size = std::max(hnsw.efSearch, int(k)); @@ -953,7 +949,7 @@ void HNSW::search_level_0( } search_from_candidates( - hnsw, qdis, k, idxi, simi, candidates, vt, search_stats, 0); + hnsw, qdis, res, candidates, vt, search_stats, 0); } } diff --git a/faiss/impl/HNSW.h b/faiss/impl/HNSW.h index c923e0a6ae..cb6b422c3d 100644 --- a/faiss/impl/HNSW.h +++ b/faiss/impl/HNSW.h @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #pragma once #include @@ -42,6 +40,8 @@ namespace faiss { struct VisitedTable; struct DistanceComputer; // from AuxIndexStructures struct HNSWStats; +template +struct ResultHandler; struct SearchParametersHNSW : SearchParameters { int efSearch = 16; @@ -54,6 +54,9 @@ struct HNSW { /// internal storage of vectors (32 bits: this is expensive) using storage_idx_t = int32_t; + // for now we do only these distances + using C = CMax; + typedef std::pair Node; /** Heap structure that allows fast @@ -195,18 +198,14 @@ struct HNSW { /// search interface for 1 point, single thread HNSWStats search( DistanceComputer& qdis, - int k, - idx_t* I, - float* D, + ResultHandler& res, VisitedTable& vt, const SearchParametersHNSW* params = nullptr) const; /// search only in level 0 from a given vertex void search_level_0( DistanceComputer& qdis, - int k, - idx_t* idxi, - float* simi, + ResultHandler& res, idx_t nprobe, const storage_idx_t* nearest_i, const float* nearest_d, diff --git a/faiss/impl/Quantizer.h b/faiss/impl/Quantizer.h index 34673211d7..9171448ef5 100644 --- a/faiss/impl/Quantizer.h +++ b/faiss/impl/Quantizer.h @@ -11,7 +11,7 @@ namespace faiss { -/** Product Quantizer. Implemented only for METRIC_L2 */ +/** General interface for quantizer objects */ struct Quantizer { size_t d; ///< size of the input vectors size_t code_size; ///< bytes per indexed vector diff --git a/faiss/impl/ResultHandler.h b/faiss/impl/ResultHandler.h index c6f731de91..a532cf2a95 100644 --- a/faiss/impl/ResultHandler.h +++ b/faiss/impl/ResultHandler.h @@ -17,23 +17,170 @@ namespace faiss { +/***************************************************************** + * The classes below are intended to be used as template arguments + * they handle results for batches of queries (size nq). + * They can be called in two ways: + * - by instanciating a SingleResultHandler that tracks results for a single + * query + * - with begin_multiple/add_results/end_multiple calls where a whole block of + * resutls is submitted + * All classes are templated on C which to define wheter the min or the max of + * results is to be kept. + *****************************************************************/ + +template +struct BlockResultHandler { + size_t nq; // number of queries for which we search + + explicit BlockResultHandler(size_t nq) : nq(nq) {} + + // currently handled query range + size_t i0 = 0, i1 = 0; + + // start collecting results for queries [i0, i1) + virtual void begin_multiple(size_t i0, size_t i1) { + this->i0 = i0; + this->i1 = i1; + } + + // add results for queries [i0, i1) and database [j0, j1) + virtual void add_results(size_t, size_t, const typename C::T*) {} + + // series of results for queries i0..i1 is done + virtual void end_multiple() {} + + virtual ~BlockResultHandler() {} +}; + +// handler for a single query +template +struct ResultHandler { + // if not better than threshold, then not necessary to call add_result + typename C::T threshold = 0; + + // return whether threshold was updated + virtual bool add_result(typename C::T dis, typename C::TI idx) = 0; + + virtual ~ResultHandler() {} +}; + +/***************************************************************** + * Single best result handler. + * Tracks the only best result, thus avoiding storing + * some temporary data in memory. + *****************************************************************/ + +template +struct Top1BlockResultHandler : BlockResultHandler { + using T = typename C::T; + using TI = typename C::TI; + using BlockResultHandler::i0; + using BlockResultHandler::i1; + + // contains exactly nq elements + T* dis_tab; + // contains exactly nq elements + TI* ids_tab; + + Top1BlockResultHandler(size_t nq, T* dis_tab, TI* ids_tab) + : BlockResultHandler(nq), dis_tab(dis_tab), ids_tab(ids_tab) {} + + struct SingleResultHandler : ResultHandler { + Top1BlockResultHandler& hr; + using ResultHandler::threshold; + + TI min_idx; + size_t current_idx = 0; + + explicit SingleResultHandler(Top1BlockResultHandler& hr) : hr(hr) {} + + /// begin results for query # i + void begin(const size_t current_idx) { + this->current_idx = current_idx; + threshold = C::neutral(); + min_idx = -1; + } + + /// add one result for query i + bool add_result(T dis, TI idx) final { + if (C::cmp(this->threshold, dis)) { + threshold = dis; + min_idx = idx; + return true; + } + return false; + } + + /// series of results for query i is done + void end() { + hr.dis_tab[current_idx] = threshold; + hr.ids_tab[current_idx] = min_idx; + } + }; + + /// begin + void begin_multiple(size_t i0, size_t i1) final { + this->i0 = i0; + this->i1 = i1; + + for (size_t i = i0; i < i1; i++) { + this->dis_tab[i] = C::neutral(); + } + } + + /// add results for query i0..i1 and j0..j1 + void add_results(size_t j0, size_t j1, const T* dis_tab) final { + for (int64_t i = i0; i < i1; i++) { + const T* dis_tab_i = dis_tab + (j1 - j0) * (i - i0) - j0; + + auto& min_distance = this->dis_tab[i]; + auto& min_index = this->ids_tab[i]; + + for (size_t j = j0; j < j1; j++) { + const T distance = dis_tab_i[j]; + + if (C::cmp(min_distance, distance)) { + min_distance = distance; + min_index = j; + } + } + } + } + + void add_result(const size_t i, const T dis, const TI idx) { + auto& min_distance = this->dis_tab[i]; + auto& min_index = this->ids_tab[i]; + + if (C::cmp(min_distance, dis)) { + min_distance = dis; + min_index = idx; + } + } +}; + /***************************************************************** * Heap based result handler *****************************************************************/ template -struct HeapResultHandler { +struct HeapBlockResultHandler : BlockResultHandler { using T = typename C::T; using TI = typename C::TI; + using BlockResultHandler::i0; + using BlockResultHandler::i1; - int nq; T* heap_dis_tab; TI* heap_ids_tab; int64_t k; // number of results to keep - HeapResultHandler(size_t nq, T* heap_dis_tab, TI* heap_ids_tab, size_t k) - : nq(nq), + HeapBlockResultHandler( + size_t nq, + T* heap_dis_tab, + TI* heap_ids_tab, + size_t k) + : BlockResultHandler(nq), heap_dis_tab(heap_dis_tab), heap_ids_tab(heap_ids_tab), k(k) {} @@ -43,30 +190,33 @@ struct HeapResultHandler { * called from 1 thread) */ - struct SingleResultHandler { - HeapResultHandler& hr; + struct SingleResultHandler : ResultHandler { + HeapBlockResultHandler& hr; + using ResultHandler::threshold; size_t k; T* heap_dis; TI* heap_ids; - T thresh; - SingleResultHandler(HeapResultHandler& hr) : hr(hr), k(hr.k) {} + explicit SingleResultHandler(HeapBlockResultHandler& hr) + : hr(hr), k(hr.k) {} /// begin results for query # i void begin(size_t i) { heap_dis = hr.heap_dis_tab + i * k; heap_ids = hr.heap_ids_tab + i * k; heap_heapify(k, heap_dis, heap_ids); - thresh = heap_dis[0]; + threshold = heap_dis[0]; } /// add one result for query i - void add_result(T dis, TI idx) { - if (C::cmp(heap_dis[0], dis)) { + bool add_result(T dis, TI idx) final { + if (C::cmp(threshold, dis)) { heap_replace_top(k, heap_dis, heap_ids, dis, idx); - thresh = heap_dis[0]; + threshold = heap_dis[0]; + return true; } + return false; } /// series of results for query i is done @@ -79,19 +229,17 @@ struct HeapResultHandler { * API for multiple results (called from 1 thread) */ - size_t i0, i1; - /// begin - void begin_multiple(size_t i0_2, size_t i1_2) { + void begin_multiple(size_t i0_2, size_t i1_2) final { this->i0 = i0_2; this->i1 = i1_2; - for (size_t i = i0_2; i < i1_2; i++) { + for (size_t i = i0; i < i1; i++) { heap_heapify(k, heap_dis_tab + i * k, heap_ids_tab + i * k); } } /// add results for query i0..i1 and j0..j1 - void add_results(size_t j0, size_t j1, const T* dis_tab) { + void add_results(size_t j0, size_t j1, const T* dis_tab) final { #pragma omp parallel for for (int64_t i = i0; i < i1; i++) { T* heap_dis = heap_dis_tab + i * k; @@ -109,7 +257,7 @@ struct HeapResultHandler { } /// series of results for queries i0..i1 is done - void end_multiple() { + void end_multiple() final { // maybe parallel for for (size_t i = i0; i < i1; i++) { heap_reorder(k, heap_dis_tab + i * k, heap_ids_tab + i * k); @@ -128,9 +276,10 @@ struct HeapResultHandler { /// Reservoir for a single query template -struct ReservoirTopN { +struct ReservoirTopN : ResultHandler { using T = typename C::T; using TI = typename C::TI; + using ResultHandler::threshold; T* vals; TI* ids; @@ -139,8 +288,6 @@ struct ReservoirTopN { size_t n; // number of requested elements size_t capacity; // size of storage - T threshold; // current threshold - ReservoirTopN() {} ReservoirTopN(size_t n, size_t capacity, T* vals, TI* ids) @@ -149,15 +296,22 @@ struct ReservoirTopN { threshold = C::neutral(); } - void add(T val, TI id) { + bool add_result(T val, TI id) final { + bool updated_threshold = false; if (C::cmp(threshold, val)) { if (i == capacity) { shrink_fuzzy(); + updated_threshold = true; } vals[i] = val; ids[i] = id; i++; } + return updated_threshold; + } + + void add(T val, TI id) { + add_result(val, id); } // reduce storage from capacity to anything @@ -169,6 +323,11 @@ struct ReservoirTopN { vals, ids, capacity, n, (capacity + n) / 2, &i); } + void shrink() { + threshold = partition(vals, ids, i, n); + i = n; + } + void to_result(T* heap_dis, TI* heap_ids) const { for (int j = 0; j < std::min(i, n); j++) { heap_push(j + 1, heap_dis, heap_ids, vals[j], ids[j]); @@ -187,23 +346,24 @@ struct ReservoirTopN { }; template -struct ReservoirResultHandler { +struct ReservoirBlockResultHandler : BlockResultHandler { using T = typename C::T; using TI = typename C::TI; + using BlockResultHandler::i0; + using BlockResultHandler::i1; - int nq; T* heap_dis_tab; TI* heap_ids_tab; int64_t k; // number of results to keep size_t capacity; // capacity of the reservoirs - ReservoirResultHandler( + ReservoirBlockResultHandler( size_t nq, T* heap_dis_tab, TI* heap_ids_tab, size_t k) - : nq(nq), + : BlockResultHandler(nq), heap_dis_tab(heap_dis_tab), heap_ids_tab(heap_ids_tab), k(k) { @@ -216,40 +376,34 @@ struct ReservoirResultHandler { * called from 1 thread) */ - struct SingleResultHandler { - ReservoirResultHandler& hr; + struct SingleResultHandler : ReservoirTopN { + ReservoirBlockResultHandler& hr; std::vector reservoir_dis; std::vector reservoir_ids; - ReservoirTopN res1; - SingleResultHandler(ReservoirResultHandler& hr) - : hr(hr), - reservoir_dis(hr.capacity), - reservoir_ids(hr.capacity) {} + explicit SingleResultHandler(ReservoirBlockResultHandler& hr) + : ReservoirTopN(hr.k, hr.capacity, nullptr, nullptr), + hr(hr) {} - size_t i; + size_t qno; /// begin results for query # i - void begin(size_t i_2) { - res1 = ReservoirTopN( - hr.k, - hr.capacity, - reservoir_dis.data(), - reservoir_ids.data()); - this->i = i_2; - } - - /// add one result for query i - void add_result(T dis, TI idx) { - res1.add(dis, idx); + void begin(size_t qno) { + reservoir_dis.resize(hr.capacity); + reservoir_ids.resize(hr.capacity); + this->vals = reservoir_dis.data(); + this->ids = reservoir_ids.data(); + this->i = 0; // size of reservoir + this->threshold = C::neutral(); + this->qno = qno; } - /// series of results for query i is done + /// series of results for query qno is done void end() { - T* heap_dis = hr.heap_dis_tab + i * hr.k; - TI* heap_ids = hr.heap_ids_tab + i * hr.k; - res1.to_result(heap_dis, heap_ids); + T* heap_dis = hr.heap_dis_tab + qno * hr.k; + TI* heap_ids = hr.heap_ids_tab + qno * hr.k; + this->to_result(heap_dis, heap_ids); } }; @@ -257,8 +411,6 @@ struct ReservoirResultHandler { * API for multiple results (called from 1 thread) */ - size_t i0, i1; - std::vector reservoir_dis; std::vector reservoir_ids; std::vector> reservoirs; @@ -267,8 +419,8 @@ struct ReservoirResultHandler { void begin_multiple(size_t i0_2, size_t i1_2) { this->i0 = i0_2; this->i1 = i1_2; - reservoir_dis.resize((i1_2 - i0_2) * capacity); - reservoir_ids.resize((i1_2 - i0_2) * capacity); + reservoir_dis.resize((i1 - i0) * capacity); + reservoir_ids.resize((i1 - i0) * capacity); reservoirs.clear(); for (size_t i = i0_2; i < i1_2; i++) { reservoirs.emplace_back( @@ -281,20 +433,19 @@ struct ReservoirResultHandler { /// add results for query i0..i1 and j0..j1 void add_results(size_t j0, size_t j1, const T* dis_tab) { - // maybe parallel for #pragma omp parallel for for (int64_t i = i0; i < i1; i++) { ReservoirTopN& reservoir = reservoirs[i - i0]; const T* dis_tab_i = dis_tab + (j1 - j0) * (i - i0) - j0; for (size_t j = j0; j < j1; j++) { T dis = dis_tab_i[j]; - reservoir.add(dis, j); + reservoir.add_result(dis, j); } } } /// series of results for queries i0..i1 is done - void end_multiple() { + void end_multiple() final { // maybe parallel for for (size_t i = i0; i < i1; i++) { reservoirs[i - i0].to_result( @@ -308,29 +459,33 @@ struct ReservoirResultHandler { *****************************************************************/ template -struct RangeSearchResultHandler { +struct RangeSearchBlockResultHandler : BlockResultHandler { using T = typename C::T; using TI = typename C::TI; + using BlockResultHandler::i0; + using BlockResultHandler::i1; RangeSearchResult* res; - float radius; + T radius; - RangeSearchResultHandler(RangeSearchResult* res, float radius) - : res(res), radius(radius) {} + RangeSearchBlockResultHandler(RangeSearchResult* res, float radius) + : BlockResultHandler(res->nq), res(res), radius(radius) {} /****************************************************** * API for 1 result at a time (each SingleResultHandler is * called from 1 thread) ******************************************************/ - struct SingleResultHandler { + struct SingleResultHandler : ResultHandler { // almost the same interface as RangeSearchResultHandler + using ResultHandler::threshold; RangeSearchPartialResult pres; - float radius; RangeQueryResult* qr = nullptr; - SingleResultHandler(RangeSearchResultHandler& rh) - : pres(rh.res), radius(rh.radius) {} + explicit SingleResultHandler(RangeSearchBlockResultHandler& rh) + : pres(rh.res) { + threshold = rh.radius; + } /// begin results for query # i void begin(size_t i) { @@ -338,10 +493,11 @@ struct RangeSearchResultHandler { } /// add one result for query i - void add_result(T dis, TI idx) { - if (C::cmp(radius, dis)) { + bool add_result(T dis, TI idx) final { + if (C::cmp(threshold, dis)) { qr->add(dis, idx); } + return false; } /// series of results for query i is done @@ -356,8 +512,6 @@ struct RangeSearchResultHandler { * API for multiple results (called from 1 thread) ******************************************************/ - size_t i0, i1; - std::vector partial_results; std::vector j0s; int pr = 0; @@ -404,109 +558,11 @@ struct RangeSearchResultHandler { } } - void end_multiple() {} - - ~RangeSearchResultHandler() { + ~RangeSearchBlockResultHandler() { if (partial_results.size() > 0) { RangeSearchPartialResult::merge(partial_results); } } }; -/***************************************************************** - * Single best result handler. - * Tracks the only best result, thus avoiding storing - * some temporary data in memory. - *****************************************************************/ - -template -struct SingleBestResultHandler { - using T = typename C::T; - using TI = typename C::TI; - - int nq; - // contains exactly nq elements - T* dis_tab; - // contains exactly nq elements - TI* ids_tab; - - SingleBestResultHandler(size_t nq, T* dis_tab, TI* ids_tab) - : nq(nq), dis_tab(dis_tab), ids_tab(ids_tab) {} - - struct SingleResultHandler { - SingleBestResultHandler& hr; - - T min_dis; - TI min_idx; - size_t current_idx = 0; - - SingleResultHandler(SingleBestResultHandler& hr) : hr(hr) {} - - /// begin results for query # i - void begin(const size_t current_idx_2) { - this->current_idx = current_idx_2; - min_dis = HUGE_VALF; - min_idx = -1; - } - - /// add one result for query i - void add_result(T dis, TI idx) { - if (C::cmp(min_dis, dis)) { - min_dis = dis; - min_idx = idx; - } - } - - /// series of results for query i is done - void end() { - hr.dis_tab[current_idx] = min_dis; - hr.ids_tab[current_idx] = min_idx; - } - }; - - size_t i0, i1; - - /// begin - void begin_multiple(size_t i0_2, size_t i1_2) { - this->i0 = i0_2; - this->i1 = i1_2; - - for (size_t i = i0_2; i < i1_2; i++) { - this->dis_tab[i] = HUGE_VALF; - } - } - - /// add results for query i0..i1 and j0..j1 - void add_results(size_t j0, size_t j1, const T* dis_tab_2) { - for (int64_t i = i0; i < i1; i++) { - const T* dis_tab_i = dis_tab_2 + (j1 - j0) * (i - i0) - j0; - - auto& min_distance = this->dis_tab[i]; - auto& min_index = this->ids_tab[i]; - - for (size_t j = j0; j < j1; j++) { - const T distance = dis_tab_i[j]; - - if (C::cmp(min_distance, distance)) { - min_distance = distance; - min_index = j; - } - } - } - } - - void add_result(const size_t i, const T dis, const TI idx) { - auto& min_distance = this->dis_tab[i]; - auto& min_index = this->ids_tab[i]; - - if (C::cmp(min_distance, dis)) { - min_distance = dis; - min_index = idx; - } - } - - /// series of results for queries i0..i1 is done - void end_multiple() {} -}; - } // namespace faiss diff --git a/faiss/impl/pq4_fast_scan.cpp b/faiss/impl/pq4_fast_scan.cpp index d2cca15de3..6173ecef47 100644 --- a/faiss/impl/pq4_fast_scan.cpp +++ b/faiss/impl/pq4_fast_scan.cpp @@ -54,6 +54,9 @@ void pq4_pack_codes( FAISS_THROW_IF_NOT(nb % bbs == 0); FAISS_THROW_IF_NOT(nsq % 2 == 0); + if (nb == 0) { + return; + } memset(blocks, 0, nb * nsq / 2); const uint8_t perm0[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}; diff --git a/faiss/impl/pq4_fast_scan.h b/faiss/impl/pq4_fast_scan.h index 2e6931f8d3..9f95f76cc1 100644 --- a/faiss/impl/pq4_fast_scan.h +++ b/faiss/impl/pq4_fast_scan.h @@ -24,6 +24,9 @@ namespace faiss { +struct NormTableScaler; +struct SIMDResultHandler; + /** Pack codes for consumption by the SIMD kernels. * The unused bytes are set to 0. * @@ -117,7 +120,6 @@ void pq4_pack_LUT(int nq, int nsq, const uint8_t* src, uint8_t* dest); * @param LUT packed look-up table * @param scaler scaler to scale the encoded norm */ -template void pq4_accumulate_loop( int nq, size_t nb, @@ -125,8 +127,8 @@ void pq4_accumulate_loop( int nsq, const uint8_t* codes, const uint8_t* LUT, - ResultHandler& res, - const Scaler& scaler); + SIMDResultHandler& res, + const NormTableScaler* scaler); /* qbs versions, supported only for bbs=32. * @@ -178,14 +180,13 @@ int pq4_pack_LUT_qbs_q_map( * @param res call-back for the resutls * @param scaler scaler to scale the encoded norm */ -template void pq4_accumulate_loop_qbs( int qbs, size_t nb, int nsq, const uint8_t* codes, const uint8_t* LUT, - ResultHandler& res, - const Scaler& scaler); + SIMDResultHandler& res, + const NormTableScaler* scaler = nullptr); } // namespace faiss diff --git a/faiss/impl/pq4_fast_scan_search_1.cpp b/faiss/impl/pq4_fast_scan_search_1.cpp index 6197c2be78..ca41f287f2 100644 --- a/faiss/impl/pq4_fast_scan_search_1.cpp +++ b/faiss/impl/pq4_fast_scan_search_1.cpp @@ -134,10 +134,8 @@ void accumulate_fixed_blocks( } } -} // anonymous namespace - template -void pq4_accumulate_loop( +void pq4_accumulate_loop_fixed_scaler( int nq, size_t nb, int bbs, @@ -172,39 +170,55 @@ void pq4_accumulate_loop( #undef DISPATCH } -// explicit template instantiations - -#define INSTANTIATE_ACCUMULATE(TH, C, with_id_map, S) \ - template void pq4_accumulate_loop, S>( \ - int, \ - size_t, \ - int, \ - int, \ - const uint8_t*, \ - const uint8_t*, \ - TH&, \ - const S&); - -using DS = DummyScaler; -using NS = NormTableScaler; - -#define INSTANTIATE_3(C, with_id_map) \ - INSTANTIATE_ACCUMULATE(SingleResultHandler, C, with_id_map, DS) \ - INSTANTIATE_ACCUMULATE(HeapHandler, C, with_id_map, DS) \ - INSTANTIATE_ACCUMULATE(ReservoirHandler, C, with_id_map, DS) \ - \ - INSTANTIATE_ACCUMULATE(SingleResultHandler, C, with_id_map, NS) \ - INSTANTIATE_ACCUMULATE(HeapHandler, C, with_id_map, NS) \ - INSTANTIATE_ACCUMULATE(ReservoirHandler, C, with_id_map, NS) - -using Csi = CMax; -INSTANTIATE_3(Csi, false); -using CsiMin = CMin; -INSTANTIATE_3(CsiMin, false); - -using Csl = CMax; -INSTANTIATE_3(Csl, true); -using CslMin = CMin; -INSTANTIATE_3(CslMin, true); +template +void pq4_accumulate_loop_fixed_handler( + int nq, + size_t nb, + int bbs, + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + ResultHandler& res, + const NormTableScaler* scaler) { + if (scaler) { + pq4_accumulate_loop_fixed_scaler( + nq, nb, bbs, nsq, codes, LUT, res, *scaler); + } else { + DummyScaler dscaler; + pq4_accumulate_loop_fixed_scaler( + nq, nb, bbs, nsq, codes, LUT, res, dscaler); + } +} + +struct Run_pq4_accumulate_loop { + template + void f(ResultHandler& res, + int nq, + size_t nb, + int bbs, + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + const NormTableScaler* scaler) { + pq4_accumulate_loop_fixed_handler( + nq, nb, bbs, nsq, codes, LUT, res, scaler); + } +}; + +} // anonymous namespace + +void pq4_accumulate_loop( + int nq, + size_t nb, + int bbs, + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + SIMDResultHandler& res, + const NormTableScaler* scaler) { + Run_pq4_accumulate_loop consumer; + dispatch_SIMDResultHanlder( + res, consumer, nq, nb, bbs, nsq, codes, LUT, scaler); +} } // namespace faiss diff --git a/faiss/impl/pq4_fast_scan_search_qbs.cpp b/faiss/impl/pq4_fast_scan_search_qbs.cpp index 50c0f6217b..d69542c309 100644 --- a/faiss/impl/pq4_fast_scan_search_qbs.cpp +++ b/faiss/impl/pq4_fast_scan_search_qbs.cpp @@ -14,6 +14,9 @@ namespace faiss { +// declared in simd_result_handlers.h +bool simd_result_handlers_accept_virtual = true; + using namespace simd_result_handlers; /************************************************************ @@ -194,10 +197,8 @@ void accumulate( #undef DISPATCH } -} // namespace - template -void pq4_accumulate_loop_qbs( +void pq4_accumulate_loop_qbs_fixed_scaler( int qbs, size_t ntotal2, int nsq, @@ -272,49 +273,39 @@ void pq4_accumulate_loop_qbs( } } -// explicit template instantiations - -#define INSTANTIATE_ACCUMULATE_Q(RH) \ - template void pq4_accumulate_loop_qbs( \ - int, \ - size_t, \ - int, \ - const uint8_t*, \ - const uint8_t*, \ - RH&, \ - const DummyScaler&); \ - template void pq4_accumulate_loop_qbs( \ - int, \ - size_t, \ - int, \ - const uint8_t*, \ - const uint8_t*, \ - RH&, \ - const NormTableScaler&); - -using Csi = CMax; -INSTANTIATE_ACCUMULATE_Q(SingleResultHandler) -INSTANTIATE_ACCUMULATE_Q(HeapHandler) -INSTANTIATE_ACCUMULATE_Q(ReservoirHandler) -using Csi2 = CMin; -INSTANTIATE_ACCUMULATE_Q(SingleResultHandler) -INSTANTIATE_ACCUMULATE_Q(HeapHandler) -INSTANTIATE_ACCUMULATE_Q(ReservoirHandler) - -using Cfl = CMax; -using HHCsl = HeapHandler; -using RHCsl = ReservoirHandler; -using SHCsl = SingleResultHandler; -INSTANTIATE_ACCUMULATE_Q(HHCsl) -INSTANTIATE_ACCUMULATE_Q(RHCsl) -INSTANTIATE_ACCUMULATE_Q(SHCsl) -using Cfl2 = CMin; -using HHCsl2 = HeapHandler; -using RHCsl2 = ReservoirHandler; -using SHCsl2 = SingleResultHandler; -INSTANTIATE_ACCUMULATE_Q(HHCsl2) -INSTANTIATE_ACCUMULATE_Q(RHCsl2) -INSTANTIATE_ACCUMULATE_Q(SHCsl2) +struct Run_pq4_accumulate_loop_qbs { + template + void f(ResultHandler& res, + int qbs, + size_t nb, + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + const NormTableScaler* scaler) { + if (scaler) { + pq4_accumulate_loop_qbs_fixed_scaler( + qbs, nb, nsq, codes, LUT, res, *scaler); + } else { + DummyScaler dummy; + pq4_accumulate_loop_qbs_fixed_scaler( + qbs, nb, nsq, codes, LUT, res, dummy); + } + } +}; + +} // namespace + +void pq4_accumulate_loop_qbs( + int qbs, + size_t nb, + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + SIMDResultHandler& res, + const NormTableScaler* scaler) { + Run_pq4_accumulate_loop_qbs consumer; + dispatch_SIMDResultHanlder(res, consumer, qbs, nb, nsq, codes, LUT, scaler); +} /*************************************************************** * Packing functions diff --git a/faiss/impl/simd_result_handlers.h b/faiss/impl/simd_result_handlers.h index 94a2541e03..2d8e5388d9 100644 --- a/faiss/impl/simd_result_handlers.h +++ b/faiss/impl/simd_result_handlers.h @@ -14,40 +14,86 @@ #include #include +#include +#include #include #include #include /** This file contains callbacks for kernels that compute distances. - * - * The SIMDResultHandler object is intended to be templated and inlined. - * Methods: - * - handle(): called when 32 distances are computed and provided in two - * simd16uint16. (q, b) indicate which entry it is in the block. - * - set_block_origin(): set the sub-matrix that is being computed */ namespace faiss { +struct SIMDResultHandler { + // used to dispatch templates + bool is_CMax = false; + uint8_t sizeof_ids = 0; + bool with_fields = false; + + /** called when 32 distances are computed and provided in two + * simd16uint16. (q, b) indicate which entry it is in the block. */ + virtual void handle( + size_t q, + size_t b, + simd16uint16 d0, + simd16uint16 d1) = 0; + + /// set the sub-matrix that is being computed + virtual void set_block_origin(size_t i0, size_t j0) = 0; + + virtual ~SIMDResultHandler() {} +}; + +/* Result handler that will return float resutls eventually */ +struct SIMDResultHandlerToFloat : SIMDResultHandler { + size_t nq; // number of queries + size_t ntotal; // ignore excess elements after ntotal + + /// these fields are used mainly for the IVF variants (with_id_map=true) + const idx_t* id_map = nullptr; // map offset in invlist to vector id + const int* q_map = nullptr; // map q to global query + const uint16_t* dbias = + nullptr; // table of biases to add to each query (for IVF L2 search) + const float* normalizers = nullptr; // size 2 * nq, to convert + + SIMDResultHandlerToFloat(size_t nq, size_t ntotal) + : nq(nq), ntotal(ntotal) {} + + virtual void begin(const float* norms) { + normalizers = norms; + } + + // called at end of search to convert int16 distances to float, before + // normalizers are deallocated + virtual void end() { + normalizers = nullptr; + } +}; + +FAISS_API extern bool simd_result_handlers_accept_virtual; + namespace simd_result_handlers { -/** Dummy structure that just computes a checksum on results +/** Dummy structure that just computes a chqecksum on results * (to avoid the computation to be optimized away) */ -struct DummyResultHandler { +struct DummyResultHandler : SIMDResultHandler { size_t cs = 0; - void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) { + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { cs += q * 123 + b * 789 + d0.get_scalar_0() + d1.get_scalar_0(); } - void set_block_origin(size_t, size_t) {} + void set_block_origin(size_t, size_t) final {} + + ~DummyResultHandler() {} }; /** memorize results in a nq-by-nb matrix. * * j0 is the current upper-left block of the matrix */ -struct StoreResultHandler { +struct StoreResultHandler : SIMDResultHandler { uint16_t* data; size_t ld; // total number of columns size_t i0 = 0; @@ -55,32 +101,32 @@ struct StoreResultHandler { StoreResultHandler(uint16_t* data, size_t ld) : data(data), ld(ld) {} - void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) { + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { size_t ofs = (q + i0) * ld + j0 + b * 32; d0.store(data + ofs); d1.store(data + ofs + 16); } - void set_block_origin(size_t i0_2, size_t j0_2) { - this->i0 = i0_2; - this->j0 = j0_2; + void set_block_origin(size_t i0_in, size_t j0_in) final { + this->i0 = i0_in; + this->j0 = j0_in; } }; /** stores results in fixed-size matrix. */ template -struct FixedStorageHandler { +struct FixedStorageHandler : SIMDResultHandler { simd16uint16 dis[NQ][BB]; int i0 = 0; - void handle(int q, int b, simd16uint16 d0, simd16uint16 d1) { + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { dis[q + i0][2 * b] = d0; dis[q + i0][2 * b + 1] = d1; } - void set_block_origin(size_t i0_2, size_t j0) { - this->i0 = i0_2; - assert(j0 == 0); + void set_block_origin(size_t i0_in, size_t j0_in) final { + this->i0 = i0_in; + assert(j0_in == 0); } template @@ -91,30 +137,29 @@ struct FixedStorageHandler { } } } + virtual ~FixedStorageHandler() {} }; -/** Record origin of current block */ +/** Result handler that compares distances to check if they need to be kept */ template -struct SIMDResultHandler { +struct ResultHandlerCompare : SIMDResultHandlerToFloat { using TI = typename C::TI; bool disable = false; int64_t i0 = 0; // query origin int64_t j0 = 0; // db origin - size_t ntotal; // ignore excess elements after ntotal - - /// these fields are used mainly for the IVF variants (with_id_map=true) - const TI* id_map; // map offset in invlist to vector id - const int* q_map; // map q to global query - const uint16_t* dbias; // table of biases to add to each query - explicit SIMDResultHandler(size_t ntotal) - : ntotal(ntotal), id_map(nullptr), q_map(nullptr), dbias(nullptr) {} + ResultHandlerCompare(size_t nq, size_t ntotal) + : SIMDResultHandlerToFloat(nq, ntotal) { + this->is_CMax = C::is_max; + this->sizeof_ids = sizeof(typename C::TI); + this->with_fields = with_id_map; + } - void set_block_origin(size_t i0_2, size_t j0_2) { - this->i0 = i0_2; - this->j0 = j0_2; + void set_block_origin(size_t i0_in, size_t j0_in) final { + this->i0 = i0_in; + this->j0 = j0_in; } // adjust handler data for IVF. @@ -172,43 +217,37 @@ struct SIMDResultHandler { return lt_mask; } - virtual void to_flat_arrays( - float* distances, - int64_t* labels, - const float* normalizers = nullptr) = 0; - - virtual ~SIMDResultHandler() {} + virtual ~ResultHandlerCompare() {} }; /** Special version for k=1 */ template -struct SingleResultHandler : SIMDResultHandler { +struct SingleResultHandler : ResultHandlerCompare { using T = typename C::T; using TI = typename C::TI; + using RHC = ResultHandlerCompare; + using RHC::normalizers; - struct Result { - T val; - TI id; - }; - std::vector results; + std::vector idis; + float* dis; + int64_t* ids; - SingleResultHandler(size_t nq, size_t ntotal) - : SIMDResultHandler(ntotal), results(nq) { + SingleResultHandler(size_t nq, size_t ntotal, float* dis, int64_t* ids) + : RHC(nq, ntotal), idis(nq), dis(dis), ids(ids) { for (int i = 0; i < nq; i++) { - Result res = {C::neutral(), -1}; - results[i] = res; + ids[i] = -1; + idis[i] = C::neutral(); } } - void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) { + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { if (this->disable) { return; } this->adjust_with_origin(q, d0, d1); - Result& res = results[q]; - uint32_t lt_mask = this->get_lt_mask(res.val, b, d0, d1); + uint32_t lt_mask = this->get_lt_mask(idis[q], b, d0, d1); if (!lt_mask) { return; } @@ -221,70 +260,61 @@ struct SingleResultHandler : SIMDResultHandler { // find first non-zero int j = __builtin_ctz(lt_mask); lt_mask -= 1 << j; - T dis = d32tab[j]; - if (C::cmp(res.val, dis)) { - res.val = dis; - res.id = this->adjust_id(b, j); + T d = d32tab[j]; + if (C::cmp(idis[q], d)) { + idis[q] = d; + ids[q] = this->adjust_id(b, j); } } } - void to_flat_arrays( - float* distances, - int64_t* labels, - const float* normalizers = nullptr) override { - for (int q = 0; q < results.size(); q++) { + void end() { + for (int q = 0; q < this->nq; q++) { if (!normalizers) { - distances[q] = results[q].val; + dis[q] = idis[q]; } else { float one_a = 1 / normalizers[2 * q]; float b = normalizers[2 * q + 1]; - distances[q] = b + results[q].val * one_a; + dis[q] = b + idis[q] * one_a; } - labels[q] = results[q].id; } } }; /** Structure that collects results in a min- or max-heap */ template -struct HeapHandler : SIMDResultHandler { +struct HeapHandler : ResultHandlerCompare { using T = typename C::T; using TI = typename C::TI; + using RHC = ResultHandlerCompare; + using RHC::normalizers; - int nq; - T* heap_dis_tab; - TI* heap_ids_tab; + std::vector idis; + std::vector iids; + float* dis; + int64_t* ids; int64_t k; // number of results to keep - HeapHandler( - int nq, - T* heap_dis_tab, - TI* heap_ids_tab, - size_t k, - size_t ntotal) - : SIMDResultHandler(ntotal), - nq(nq), - heap_dis_tab(heap_dis_tab), - heap_ids_tab(heap_ids_tab), + HeapHandler(size_t nq, size_t ntotal, int64_t k, float* dis, int64_t* ids) + : RHC(nq, ntotal), + idis(nq * k), + iids(nq * k), + dis(dis), + ids(ids), k(k) { - for (int q = 0; q < nq; q++) { - T* heap_dis_in = heap_dis_tab + q * k; - TI* heap_ids_in = heap_ids_tab + q * k; - heap_heapify(k, heap_dis_in, heap_ids_in); - } + heap_heapify(k * nq, idis.data(), iids.data()); } - void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) { + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { if (this->disable) { return; } this->adjust_with_origin(q, d0, d1); - T* heap_dis = heap_dis_tab + q * k; - TI* heap_ids = heap_ids_tab + q * k; + T* heap_dis = idis.data() + q * k; + TI* heap_ids = iids.data() + q * k; uint16_t cur_thresh = heap_dis[0] < 65536 ? (uint16_t)(heap_dis[0]) : 0xffff; @@ -313,16 +343,13 @@ struct HeapHandler : SIMDResultHandler { } } - void to_flat_arrays( - float* distances, - int64_t* labels, - const float* normalizers = nullptr) override { - for (int q = 0; q < nq; q++) { - T* heap_dis_in = heap_dis_tab + q * k; - TI* heap_ids_in = heap_ids_tab + q * k; + void end() override { + for (int q = 0; q < this->nq; q++) { + T* heap_dis_in = idis.data() + q * k; + TI* heap_ids_in = iids.data() + q * k; heap_reorder(k, heap_dis_in, heap_ids_in); - int64_t* heap_ids = labels + q * k; - float* heap_dis = distances + q * k; + float* heap_dis = dis + q * k; + int64_t* heap_ids = ids + q * k; float one_a = 1.0, b = 0.0; if (normalizers) { @@ -330,8 +357,8 @@ struct HeapHandler : SIMDResultHandler { b = normalizers[2 * q + 1]; } for (int j = 0; j < k; j++) { - heap_ids[j] = heap_ids_in[j]; heap_dis[j] = heap_dis_in[j] * one_a + b; + heap_ids[j] = heap_ids_in[j]; } } } @@ -342,114 +369,45 @@ struct HeapHandler : SIMDResultHandler { * Results are stored when they are below the threshold until the capacity is * reached. Then a partition sort is used to update the threshold. */ -namespace { - -uint64_t get_cy() { -#ifdef MICRO_BENCHMARK - uint32_t high, low; - asm volatile("rdtsc \n\t" : "=a"(low), "=d"(high)); - return ((uint64_t)high << 32) | (low); -#else - return 0; -#endif -} - -} // anonymous namespace - -template -struct ReservoirTopN { - using T = typename C::T; - using TI = typename C::TI; - - T* vals; - TI* ids; - - size_t i; // number of stored elements - size_t n; // number of requested elements - size_t capacity; // size of storage - size_t cycles = 0; - - T threshold; // current threshold - - ReservoirTopN(size_t n, size_t capacity, T* vals, TI* ids) - : vals(vals), ids(ids), i(0), n(n), capacity(capacity) { - assert(n < capacity); - threshold = C::neutral(); - } - - void add(T val, TI id) { - if (C::cmp(threshold, val)) { - if (i == capacity) { - shrink_fuzzy(); - } - vals[i] = val; - ids[i] = id; - i++; - } - } - - /// shrink number of stored elements to n - void shrink_xx() { - uint64_t t0 = get_cy(); - qselect(vals, ids, i, n); - i = n; // forget all elements above i = n - threshold = C::Crev::neutral(); - for (size_t j = 0; j < n; j++) { - if (C::cmp(vals[j], threshold)) { - threshold = vals[j]; - } - } - cycles += get_cy() - t0; - } - - void shrink() { - uint64_t t0 = get_cy(); - threshold = partition(vals, ids, i, n); - i = n; - cycles += get_cy() - t0; - } - - void shrink_fuzzy() { - uint64_t t0 = get_cy(); - assert(i == capacity); - threshold = partition_fuzzy( - vals, ids, capacity, n, (capacity + n) / 2, &i); - cycles += get_cy() - t0; - } -}; - /** Handler built from several ReservoirTopN (one per query) */ template -struct ReservoirHandler : SIMDResultHandler { +struct ReservoirHandler : ResultHandlerCompare { using T = typename C::T; using TI = typename C::TI; + using RHC = ResultHandlerCompare; + using RHC::normalizers; size_t capacity; // rounded up to multiple of 16 + + // where the final results will be written + float* dis; + int64_t* ids; + std::vector all_ids; AlignedTable all_vals; - std::vector> reservoirs; - uint64_t times[4]; - - ReservoirHandler(size_t nq, size_t ntotal, size_t n, size_t capacity_in) - : SIMDResultHandler(ntotal), - capacity((capacity_in + 15) & ~15), - all_ids(nq * capacity), - all_vals(nq * capacity) { + ReservoirHandler( + size_t nq, + size_t ntotal, + size_t k, + size_t cap, + float* dis, + int64_t* ids) + : RHC(nq, ntotal), capacity((cap + 15) & ~15), dis(dis), ids(ids) { assert(capacity % 16 == 0); - for (size_t i = 0; i < nq; i++) { + all_ids.resize(nq * capacity); + all_vals.resize(nq * capacity); + for (size_t q = 0; q < nq; q++) { reservoirs.emplace_back( - n, + k, capacity, - all_vals.get() + i * capacity, - all_ids.data() + i * capacity); + all_vals.get() + q * capacity, + all_ids.data() + q * capacity); } - times[0] = times[1] = times[2] = times[3] = 0; } - void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) { - uint64_t t0 = get_cy(); + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { if (this->disable) { return; } @@ -457,8 +415,6 @@ struct ReservoirHandler : SIMDResultHandler { ReservoirTopN& res = reservoirs[q]; uint32_t lt_mask = this->get_lt_mask(res.threshold, b, d0, d1); - uint64_t t1 = get_cy(); - times[0] += t1 - t0; if (!lt_mask) { return; @@ -474,20 +430,14 @@ struct ReservoirHandler : SIMDResultHandler { T dis = d32tab[j]; res.add(dis, this->adjust_id(b, j)); } - times[1] += get_cy() - t1; } - void to_flat_arrays( - float* distances, - int64_t* labels, - const float* normalizers = nullptr) override { + void end() override { using Cf = typename std::conditional< C::is_max, CMax, CMin>::type; - uint64_t t0 = get_cy(); - uint64_t t3 = 0; std::vector perm(reservoirs[0].n); for (int q = 0; q < reservoirs.size(); q++) { ReservoirTopN& res = reservoirs[q]; @@ -496,8 +446,8 @@ struct ReservoirHandler : SIMDResultHandler { if (res.i > res.n) { res.shrink(); } - int64_t* heap_ids = labels + q * n; - float* heap_dis = distances + q * n; + int64_t* heap_ids = ids + q * n; + float* heap_dis = dis + q * n; float one_a = 1.0, b = 0.0; if (normalizers) { @@ -518,14 +468,236 @@ struct ReservoirHandler : SIMDResultHandler { // possibly add empty results heap_heapify(n - res.i, heap_dis + res.i, heap_ids + res.i); + } + } +}; + +/** Result hanlder for range search. The difficulty is that the range distances + * have to be scaled using the scaler. + */ + +template +struct RangeHandler : ResultHandlerCompare { + using T = typename C::T; + using TI = typename C::TI; + using RHC = ResultHandlerCompare; + using RHC::normalizers; + using RHC::nq; + + RangeSearchResult& rres; + float radius; + std::vector thresholds; + std::vector n_per_query; + size_t q0 = 0; + + // we cannot use the RangeSearchPartialResult interface because queries can + // be performed by batches + struct Triplet { + idx_t q; + idx_t b; + uint16_t dis; + }; + std::vector triplets; + + RangeHandler(RangeSearchResult& rres, float radius, size_t ntotal) + : RHC(rres.nq, ntotal), rres(rres), radius(radius) { + thresholds.resize(nq); + n_per_query.resize(nq + 1); + } + + virtual void begin(const float* norms) { + normalizers = norms; + for (int q = 0; q < nq; ++q) { + thresholds[q] = + normalizers[2 * q] * (radius - normalizers[2 * q + 1]); + } + } + + void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final { + if (this->disable) { + return; + } + this->adjust_with_origin(q, d0, d1); + + uint32_t lt_mask = this->get_lt_mask(thresholds[q], b, d0, d1); + + if (!lt_mask) { + return; + } + ALIGNED(32) uint16_t d32tab[32]; + d0.store(d32tab); + d1.store(d32tab + 16); + + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + T dis = d32tab[j]; + n_per_query[q]++; + triplets.push_back({idx_t(q + q0), this->adjust_id(b, j), dis}); + } + } - t3 += res.cycles; + void end() override { + memcpy(rres.lims, n_per_query.data(), sizeof(n_per_query[0]) * nq); + rres.do_allocation(); + for (auto it = triplets.begin(); it != triplets.end(); ++it) { + size_t& l = rres.lims[it->q]; + rres.distances[l] = it->dis; + rres.labels[l] = it->b; + l++; + } + memmove(rres.lims + 1, rres.lims, sizeof(*rres.lims) * rres.nq); + rres.lims[0] = 0; + + for (int q = 0; q < nq; q++) { + float one_a = 1 / normalizers[2 * q]; + float b = normalizers[2 * q + 1]; + for (size_t i = rres.lims[q]; i < rres.lims[q + 1]; i++) { + rres.distances[i] = rres.distances[i] * one_a + b; + } } - times[2] += get_cy() - t0; - times[3] += t3; } }; +#ifndef SWIG + +// handler for a subset of queries +template +struct PartialRangeHandler : RangeHandler { + using T = typename C::T; + using TI = typename C::TI; + using RHC = RangeHandler; + using RHC::normalizers; + using RHC::nq, RHC::q0, RHC::triplets, RHC::n_per_query; + + RangeSearchPartialResult& pres; + + PartialRangeHandler( + RangeSearchPartialResult& pres, + float radius, + size_t ntotal, + size_t q0, + size_t q1) + : RangeHandler(*pres.res, radius, ntotal), + pres(pres) { + nq = q1 - q0; + this->q0 = q0; + } + + // shift left n_per_query + void shift_n_per_query() { + memmove(n_per_query.data() + 1, + n_per_query.data(), + nq * sizeof(n_per_query[0])); + n_per_query[0] = 0; + } + + // commit to partial result instead of full RangeResult + void end() override { + std::vector sorted_triplets(triplets.size()); + for (int q = 0; q < nq; q++) { + n_per_query[q + 1] += n_per_query[q]; + } + shift_n_per_query(); + + for (size_t i = 0; i < triplets.size(); i++) { + sorted_triplets[n_per_query[triplets[i].q - q0]++] = triplets[i]; + } + shift_n_per_query(); + + size_t* lims = n_per_query.data(); + + for (int q = 0; q < nq; q++) { + float one_a = 1 / normalizers[2 * q]; + float b = normalizers[2 * q + 1]; + RangeQueryResult& qres = pres.new_result(q + q0); + for (size_t i = lims[q]; i < lims[q + 1]; i++) { + qres.add( + sorted_triplets[i].dis * one_a + b, + sorted_triplets[i].b); + } + } + } +}; + +#endif + +/******************************************************************************** + * Dynamic dispatching function. The consumer should have a templatized method f + * that will be replaced with the actual SIMDResultHandler that is determined + * dynamically. + */ + +template +void dispatch_SIMDResultHanlder_fixedCW( + SIMDResultHandler& res, + Consumer& consumer, + Types... args) { + if (auto resh = dynamic_cast*>(&res)) { + consumer.template f>(*resh, args...); + } else if (auto resh = dynamic_cast*>(&res)) { + consumer.template f>(*resh, args...); + } else if (auto resh = dynamic_cast*>(&res)) { + consumer.template f>(*resh, args...); + } else { // generic handler -- will not be inlined + FAISS_THROW_IF_NOT_FMT( + simd_result_handlers_accept_virtual, + "Running vitrual handler for %s", + typeid(res).name()); + consumer.template f(res, args...); + } +} + +template +void dispatch_SIMDResultHanlder_fixedC( + SIMDResultHandler& res, + Consumer& consumer, + Types... args) { + if (res.with_fields) { + dispatch_SIMDResultHanlder_fixedCW(res, consumer, args...); + } else { + dispatch_SIMDResultHanlder_fixedCW(res, consumer, args...); + } +} + +template +void dispatch_SIMDResultHanlder( + SIMDResultHandler& res, + Consumer& consumer, + Types... args) { + if (res.sizeof_ids == 0) { + if (auto resh = dynamic_cast(&res)) { + consumer.template f(*resh, args...); + } else if (auto resh = dynamic_cast(&res)) { + consumer.template f(*resh, args...); + } else { // generic path + FAISS_THROW_IF_NOT_FMT( + simd_result_handlers_accept_virtual, + "Running vitrual handler for %s", + typeid(res).name()); + consumer.template f(res, args...); + } + } else if (res.sizeof_ids == sizeof(int)) { + if (res.is_CMax) { + dispatch_SIMDResultHanlder_fixedC>( + res, consumer, args...); + } else { + dispatch_SIMDResultHanlder_fixedC>( + res, consumer, args...); + } + } else if (res.sizeof_ids == sizeof(int64_t)) { + if (res.is_CMax) { + dispatch_SIMDResultHanlder_fixedC>( + res, consumer, args...); + } else { + dispatch_SIMDResultHanlder_fixedC>( + res, consumer, args...); + } + } else { + FAISS_THROW_FMT("Unknown id size %d", res.sizeof_ids); + } +} } // namespace simd_result_handlers } // namespace faiss diff --git a/faiss/python/swigfaiss.swig b/faiss/python/swigfaiss.swig index 3d6f94604a..fb7f50dd2e 100644 --- a/faiss/python/swigfaiss.swig +++ b/faiss/python/swigfaiss.swig @@ -81,6 +81,9 @@ typedef uint64_t size_t; #include #include #include +#include +#include + #include #include #include @@ -490,6 +493,11 @@ void gpu_sync_all_devices() %include %include %include + +// NOTE(matthijs) let's not go into wrapping simdlib +struct faiss::simd16uint16 {}; + +%include %include %include %include diff --git a/faiss/utils/distances.cpp b/faiss/utils/distances.cpp index 5b66158c09..784793c9a9 100644 --- a/faiss/utils/distances.cpp +++ b/faiss/utils/distances.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -131,16 +129,17 @@ void fvec_renorm_L2(size_t d, size_t nx, float* __restrict x) { namespace { /* Find the nearest neighbors for nx queries in a set of ny vectors */ -template +template void exhaustive_inner_product_seq( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res, + BlockResultHandler& res, const IDSelector* sel = nullptr) { - using SingleResultHandler = typename ResultHandler::SingleResultHandler; + using SingleResultHandler = + typename BlockResultHandler::SingleResultHandler; int nt = std::min(int(nx), omp_get_max_threads()); FAISS_ASSERT(use_sel == (sel != nullptr)); @@ -167,16 +166,17 @@ void exhaustive_inner_product_seq( } } -template +template void exhaustive_L2sqr_seq( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res, + BlockResultHandler& res, const IDSelector* sel = nullptr) { - using SingleResultHandler = typename ResultHandler::SingleResultHandler; + using SingleResultHandler = + typename BlockResultHandler::SingleResultHandler; int nt = std::min(int(nx), omp_get_max_threads()); FAISS_ASSERT(use_sel == (sel != nullptr)); @@ -202,14 +202,14 @@ void exhaustive_L2sqr_seq( } /** Find the nearest neighbors for nx queries in a set of ny vectors */ -template +template void exhaustive_inner_product_blas( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res) { + BlockResultHandler& res) { // BLAS does not like empty matrices if (nx == 0 || ny == 0) return; @@ -258,14 +258,14 @@ void exhaustive_inner_product_blas( // distance correction is an operator that can be applied to transform // the distances -template +template void exhaustive_L2sqr_blas_default_impl( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res, + BlockResultHandler& res, const float* y_norms = nullptr) { // BLAS does not like empty matrices if (nx == 0 || ny == 0) @@ -341,14 +341,14 @@ void exhaustive_L2sqr_blas_default_impl( } } -template +template void exhaustive_L2sqr_blas( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res, + BlockResultHandler& res, const float* y_norms = nullptr) { exhaustive_L2sqr_blas_default_impl(x, y, d, nx, ny, res); } @@ -360,7 +360,7 @@ void exhaustive_L2sqr_blas_cmax_avx2( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms) { // BLAS does not like empty matrices if (nx == 0 || ny == 0) @@ -563,13 +563,13 @@ void exhaustive_L2sqr_blas_cmax_avx2( // an override if only a single closest point is needed template <> -void exhaustive_L2sqr_blas>>( +void exhaustive_L2sqr_blas>>( const float* x, const float* y, size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms) { #if defined(__AVX2__) // use a faster fused kernel if available @@ -590,28 +590,29 @@ void exhaustive_L2sqr_blas>>( // run the default implementation exhaustive_L2sqr_blas_default_impl< - SingleBestResultHandler>>( + Top1BlockResultHandler>>( x, y, d, nx, ny, res, y_norms); #else // run the default implementation exhaustive_L2sqr_blas_default_impl< - SingleBestResultHandler>>( + Top1BlockResultHandler>>( x, y, d, nx, ny, res, y_norms); #endif } -template +template void knn_L2sqr_select( const float* x, const float* y, size_t d, size_t nx, size_t ny, - ResultHandler& res, + BlockResultHandler& res, const float* y_norm2, const IDSelector* sel) { if (sel) { - exhaustive_L2sqr_seq(x, y, d, nx, ny, res, sel); + exhaustive_L2sqr_seq( + x, y, d, nx, ny, res, sel); } else if (nx < distance_compute_blas_threshold) { exhaustive_L2sqr_seq(x, y, d, nx, ny, res); } else { @@ -619,6 +620,25 @@ void knn_L2sqr_select( } } +template +void knn_inner_product_select( + const float* x, + const float* y, + size_t d, + size_t nx, + size_t ny, + BlockResultHandler& res, + const IDSelector* sel) { + if (sel) { + exhaustive_inner_product_seq( + x, y, d, nx, ny, res, sel); + } else if (nx < distance_compute_blas_threshold) { + exhaustive_inner_product_seq(x, y, d, nx, ny, res); + } else { + exhaustive_inner_product_blas(x, y, d, nx, ny, res); + } +} + } // anonymous namespace /******************************************************* @@ -637,7 +657,7 @@ void knn_inner_product( size_t nx, size_t ny, size_t k, - float* val, + float* vals, int64_t* ids, const IDSelector* sel) { int64_t imin = 0; @@ -650,30 +670,21 @@ void knn_inner_product( } if (auto sela = dynamic_cast(sel)) { knn_inner_products_by_idx( - x, y, sela->ids, d, nx, sela->n, k, val, ids, 0); + x, y, sela->ids, d, nx, sela->n, k, vals, ids, 0); return; } - if (k < distance_compute_min_k_reservoir) { - using RH = HeapResultHandler>; - RH res(nx, val, ids, k); - if (sel) { - exhaustive_inner_product_seq(x, y, d, nx, ny, res, sel); - } else if (nx < distance_compute_blas_threshold) { - exhaustive_inner_product_seq(x, y, d, nx, ny, res); - } else { - exhaustive_inner_product_blas(x, y, d, nx, ny, res); - } + + if (k == 1) { + Top1BlockResultHandler> res(nx, vals, ids); + knn_inner_product_select(x, y, d, nx, ny, res, sel); + } else if (k < distance_compute_min_k_reservoir) { + HeapBlockResultHandler> res(nx, vals, ids, k); + knn_inner_product_select(x, y, d, nx, ny, res, sel); } else { - using RH = ReservoirResultHandler>; - RH res(nx, val, ids, k); - if (sel) { - exhaustive_inner_product_seq(x, y, d, nx, ny, res, sel); - } else if (nx < distance_compute_blas_threshold) { - exhaustive_inner_product_seq(x, y, d, nx, ny, res, nullptr); - } else { - exhaustive_inner_product_blas(x, y, d, nx, ny, res); - } + ReservoirBlockResultHandler> res(nx, vals, ids, k); + knn_inner_product_select(x, y, d, nx, ny, res, sel); } + if (imin != 0) { for (size_t i = 0; i < nx * k; i++) { if (ids[i] >= 0) { @@ -719,13 +730,13 @@ void knn_L2sqr( return; } if (k == 1) { - SingleBestResultHandler> res(nx, vals, ids); + Top1BlockResultHandler> res(nx, vals, ids); knn_L2sqr_select(x, y, d, nx, ny, res, y_norm2, sel); } else if (k < distance_compute_min_k_reservoir) { - HeapResultHandler> res(nx, vals, ids, k); + HeapBlockResultHandler> res(nx, vals, ids, k); knn_L2sqr_select(x, y, d, nx, ny, res, y_norm2, sel); } else { - ReservoirResultHandler> res(nx, vals, ids, k); + ReservoirBlockResultHandler> res(nx, vals, ids, k); knn_L2sqr_select(x, y, d, nx, ny, res, y_norm2, sel); } if (imin != 0) { @@ -763,7 +774,7 @@ void range_search_L2sqr( float radius, RangeSearchResult* res, const IDSelector* sel) { - using RH = RangeSearchResultHandler>; + using RH = RangeSearchBlockResultHandler>; RH resh(res, radius); if (sel) { exhaustive_L2sqr_seq(x, y, d, nx, ny, resh, sel); @@ -783,7 +794,7 @@ void range_search_inner_product( float radius, RangeSearchResult* res, const IDSelector* sel) { - using RH = RangeSearchResultHandler>; + using RH = RangeSearchBlockResultHandler>; RH resh(res, radius); if (sel) { exhaustive_inner_product_seq(x, y, d, nx, ny, resh, sel); diff --git a/faiss/utils/distances_fused/avx512.cpp b/faiss/utils/distances_fused/avx512.cpp index b5ff70f9e4..d4c442c79b 100644 --- a/faiss/utils/distances_fused/avx512.cpp +++ b/faiss/utils/distances_fused/avx512.cpp @@ -68,7 +68,7 @@ void kernel( const float* const __restrict y, const float* const __restrict y_transposed, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* __restrict y_norms, size_t i) { const size_t ny_p = @@ -231,7 +231,7 @@ void exhaustive_L2sqr_fused_cmax( const float* const __restrict y, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* __restrict y_norms) { // BLAS does not like empty matrices if (nx == 0 || ny == 0) { @@ -275,7 +275,7 @@ void exhaustive_L2sqr_fused_cmax( x, y, y_transposed.data(), ny, res, y_norms, i); } - // Does nothing for SingleBestResultHandler, but + // Does nothing for Top1BlockResultHandler, but // keeping the call for the consistency. res.end_multiple(); InterruptCallback::check(); @@ -289,7 +289,7 @@ bool exhaustive_L2sqr_fused_cmax_AVX512( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms) { // process only cases with certain dimensionalities diff --git a/faiss/utils/distances_fused/avx512.h b/faiss/utils/distances_fused/avx512.h index b6d5fc0556..4cb62771a2 100644 --- a/faiss/utils/distances_fused/avx512.h +++ b/faiss/utils/distances_fused/avx512.h @@ -28,7 +28,7 @@ bool exhaustive_L2sqr_fused_cmax_AVX512( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms); } // namespace faiss diff --git a/faiss/utils/distances_fused/distances_fused.cpp b/faiss/utils/distances_fused/distances_fused.cpp index a0af971c5c..2ba7e29014 100644 --- a/faiss/utils/distances_fused/distances_fused.cpp +++ b/faiss/utils/distances_fused/distances_fused.cpp @@ -20,7 +20,7 @@ bool exhaustive_L2sqr_fused_cmax( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms) { if (nx == 0 || ny == 0) { // nothing to do diff --git a/faiss/utils/distances_fused/distances_fused.h b/faiss/utils/distances_fused/distances_fused.h index e6e35c209e..54b58752b1 100644 --- a/faiss/utils/distances_fused/distances_fused.h +++ b/faiss/utils/distances_fused/distances_fused.h @@ -34,7 +34,7 @@ bool exhaustive_L2sqr_fused_cmax( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms); } // namespace faiss diff --git a/faiss/utils/distances_fused/simdlib_based.cpp b/faiss/utils/distances_fused/simdlib_based.cpp index 97ededd2f0..31239e866b 100644 --- a/faiss/utils/distances_fused/simdlib_based.cpp +++ b/faiss/utils/distances_fused/simdlib_based.cpp @@ -62,7 +62,7 @@ void kernel( const float* const __restrict y, const float* const __restrict y_transposed, const size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* __restrict y_norms, const size_t i) { const size_t ny_p = @@ -226,7 +226,7 @@ void exhaustive_L2sqr_fused_cmax( const float* const __restrict y, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* __restrict y_norms) { // BLAS does not like empty matrices if (nx == 0 || ny == 0) { @@ -270,7 +270,7 @@ void exhaustive_L2sqr_fused_cmax( x, y, y_transposed.data(), ny, res, y_norms, i); } - // Does nothing for SingleBestResultHandler, but + // Does nothing for Top1BlockResultHandler, but // keeping the call for the consistency. res.end_multiple(); InterruptCallback::check(); @@ -284,7 +284,7 @@ bool exhaustive_L2sqr_fused_cmax_simdlib( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms) { // Process only cases with certain dimensionalities. // An acceptable dimensionality value is limited by the number of diff --git a/faiss/utils/distances_fused/simdlib_based.h b/faiss/utils/distances_fused/simdlib_based.h index b60da7b193..6240a8f110 100644 --- a/faiss/utils/distances_fused/simdlib_based.h +++ b/faiss/utils/distances_fused/simdlib_based.h @@ -24,7 +24,7 @@ bool exhaustive_L2sqr_fused_cmax_simdlib( size_t d, size_t nx, size_t ny, - SingleBestResultHandler>& res, + Top1BlockResultHandler>& res, const float* y_norms); } // namespace faiss diff --git a/tests/test_fast_scan_ivf.py b/tests/test_fast_scan_ivf.py index 5a57a39ca9..d6dad8fec3 100644 --- a/tests/test_fast_scan_ivf.py +++ b/tests/test_fast_scan_ivf.py @@ -133,8 +133,6 @@ def test_by_residual_L2_v2(self): self.do_test(LUT, bias, nprobe, alt_3d=True) - - ########################################################## # Tests for various IndexPQFastScan implementations ########################################################## @@ -209,7 +207,6 @@ def test_by_residual_ip(self): self.do_test(True, faiss.METRIC_INNER_PRODUCT) - class TestIVFImplem2(unittest.TestCase): """ Verify implem 2 (search with original invlists with uint8 LUTs) against IndexIVFPQ. Entails some loss in accuracy. """ @@ -259,6 +256,7 @@ def test_qloss_no_residual_ip(self): def test_qloss_by_residual_ip(self): self.eval_quant_loss(True, faiss.METRIC_INNER_PRODUCT) + class TestEquivPQ(unittest.TestCase): def test_equiv_pq(self): @@ -309,6 +307,7 @@ def do_test(self, by_residual, metric=faiss.METRIC_L2, d=32, nq=200): index.add(ds.get_database()) index.nprobe = 4 + # compare against implem = 2, which includes quantized LUTs index2 = faiss.IndexIVFPQFastScan(index) index2.implem = 2 Dref, Iref = index2.search(ds.get_queries(), 4) @@ -370,7 +369,6 @@ def test_by_residual_odd_dim_single_query(self): self.do_test(True, d=30, nq=1) - class TestIVFImplem10(TestIVFImplem12): IMPLEM = 10 @@ -432,7 +430,6 @@ def do_test(self, by_residual=False, metric=faiss.METRIC_L2, d=32, bbs=32): new_code_i = new_code_per_id[the_id] np.testing.assert_array_equal(ref_code_i, new_code_i) - def test_add(self): self.do_test() @@ -812,3 +809,75 @@ def subtest_io(self, factory_str): def test_io(self): self.subtest_io('IVF16,PLSQ2x3x4fsr_Nlsq2x4') self.subtest_io('IVF16,PRQ2x3x4fs_Nrq2x4') + + +class TestSearchParams(unittest.TestCase): + + def test_search_params(self): + ds = datasets.SyntheticDataset(32, 500, 100, 10) + + index = faiss.index_factory(ds.d, "IVF32,PQ16x4fs") + index.train(ds.get_train()) + index.add(ds.get_database()) + + index.nprobe + index.nprobe = 4 + Dref4, Iref4 = index.search(ds.get_queries(), 10) + # index.nprobe = 16 + # Dref16, Iref16 = index.search(ds.get_queries(), 10) + + index.nprobe = 1 + Dnew4, Inew4 = index.search( + ds.get_queries(), 10, params=faiss.IVFSearchParameters(nprobe=4)) + np.testing.assert_array_equal(Dref4, Dnew4) + np.testing.assert_array_equal(Iref4, Inew4) + + +class TestRangeSearchImplem12(unittest.TestCase): + IMPLEM = 12 + + def do_test(self, metric=faiss.METRIC_L2): + ds = datasets.SyntheticDataset(32, 750, 200, 100) + + index = faiss.index_factory(ds.d, "IVF32,PQ16x4np", metric) + index.train(ds.get_train()) + index.add(ds.get_database()) + index.nprobe = 4 + + # find a reasonable radius + D, I = index.search(ds.get_queries(), 10) + radius = np.median(D[:, -1]) + # print("radius=", radius) + lims1, D1, I1 = index.range_search(ds.get_queries(), radius) + + index2 = faiss.IndexIVFPQFastScan(index) + index2.implem = self.IMPLEM + lims2, D2, I2 = index2.range_search(ds.get_queries(), radius) + + nmiss = 0 + nextra = 0 + + for i in range(ds.nq): + ref = set(I1[lims1[i]: lims1[i + 1]]) + new = set(I2[lims2[i]: lims2[i + 1]]) + print(ref, new) + nmiss += len(ref - new) + nextra += len(new - ref) + + # need some tolerance because the look-up tables are quantized + self.assertLess(nmiss, 10) + self.assertLess(nextra, 10) + + def test_L2(self): + self.do_test() + + def test_IP(self): + self.do_test(metric=faiss.METRIC_INNER_PRODUCT) + + +class TestRangeSearchImplem10(TestRangeSearchImplem12): + IMPLEM = 10 + + +class TestRangeSearchImplem110(TestRangeSearchImplem12): + IMPLEM = 110 diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py new file mode 100644 index 0000000000..914fac3ff1 --- /dev/null +++ b/tests/test_graph_based.py @@ -0,0 +1,426 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +""" a few tests for graph-based indices (HNSW and NSG)""" + +import numpy as np +import unittest +import faiss +import tempfile +import os + +from common_faiss_tests import get_dataset_2 + + +class TestHNSW(unittest.TestCase): + + def __init__(self, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + d = 32 + nt = 0 + nb = 1500 + nq = 500 + + (_, self.xb, self.xq) = get_dataset_2(d, nt, nb, nq) + index = faiss.IndexFlatL2(d) + index.add(self.xb) + Dref, Iref = index.search(self.xq, 1) + self.Iref = Iref + + def test_hnsw(self): + d = self.xq.shape[1] + + index = faiss.IndexHNSWFlat(d, 16) + index.add(self.xb) + Dhnsw, Ihnsw = index.search(self.xq, 1) + + self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 460) + + self.io_and_retest(index, Dhnsw, Ihnsw) + + def test_range_search(self): + index_flat = faiss.IndexFlat(self.xb.shape[1]) + index_flat.add(self.xb) + D, _ = index_flat.search(self.xq, 10) + radius = np.median(D[:, -1]) + lims_ref, Dref, Iref = index_flat.range_search(self.xq, radius) + + index = faiss.IndexHNSWFlat(self.xb.shape[1], 16) + index.add(self.xb) + lims, D, I = index.range_search(self.xq, radius) + + nmiss = 0 + # check if returned resutls are a subset of the reference results + for i in range(len(self.xq)): + ref = Iref[lims_ref[i]: lims_ref[i + 1]] + new = I[lims[i]: lims[i + 1]] + self.assertLessEqual(set(new), set(ref)) + nmiss += len(ref) - len(new) + # currenly we miss 405 / 6019 neighbors + self.assertLessEqual(nmiss, lims_ref[-1] * 0.1) + + def test_hnsw_unbounded_queue(self): + d = self.xq.shape[1] + + index = faiss.IndexHNSWFlat(d, 16) + index.add(self.xb) + index.search_bounded_queue = False + Dhnsw, Ihnsw = index.search(self.xq, 1) + + self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 460) + + self.io_and_retest(index, Dhnsw, Ihnsw) + + def io_and_retest(self, index, Dhnsw, Ihnsw): + index2 = faiss.deserialize_index(faiss.serialize_index(index)) + Dhnsw2, Ihnsw2 = index2.search(self.xq, 1) + + self.assertTrue(np.all(Dhnsw2 == Dhnsw)) + self.assertTrue(np.all(Ihnsw2 == Ihnsw)) + + # also test clone + index3 = faiss.clone_index(index) + Dhnsw3, Ihnsw3 = index3.search(self.xq, 1) + + self.assertTrue(np.all(Dhnsw3 == Dhnsw)) + self.assertTrue(np.all(Ihnsw3 == Ihnsw)) + + def test_hnsw_2level(self): + d = self.xq.shape[1] + + quant = faiss.IndexFlatL2(d) + + index = faiss.IndexHNSW2Level(quant, 256, 8, 8) + index.train(self.xb) + index.add(self.xb) + Dhnsw, Ihnsw = index.search(self.xq, 1) + + self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 307) + + self.io_and_retest(index, Dhnsw, Ihnsw) + + def test_add_0_vecs(self): + index = faiss.IndexHNSWFlat(10, 16) + zero_vecs = np.zeros((0, 10), dtype='float32') + # infinite loop + index.add(zero_vecs) + + def test_hnsw_IP(self): + d = self.xq.shape[1] + + index_IP = faiss.IndexFlatIP(d) + index_IP.add(self.xb) + Dref, Iref = index_IP.search(self.xq, 1) + + index = faiss.IndexHNSWFlat(d, 16, faiss.METRIC_INNER_PRODUCT) + index.add(self.xb) + Dhnsw, Ihnsw = index.search(self.xq, 1) + + self.assertGreaterEqual((Iref == Ihnsw).sum(), 470) + + mask = Iref[:, 0] == Ihnsw[:, 0] + assert np.allclose(Dref[mask, 0], Dhnsw[mask, 0]) + + +class TestNSG(unittest.TestCase): + + def __init__(self, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + d = 32 + nt = 0 + nb = 1500 + nq = 500 + self.GK = 32 + + _, self.xb, self.xq = get_dataset_2(d, nt, nb, nq) + + def make_knn_graph(self, metric): + n = self.xb.shape[0] + d = self.xb.shape[1] + index = faiss.IndexFlat(d, metric) + index.add(self.xb) + _, I = index.search(self.xb, self.GK + 1) + knn_graph = np.zeros((n, self.GK), dtype=np.int64) + + # For the inner product distance, the distance between a vector and + # itself may not be the smallest, so it is not guaranteed that I[:, 0] + # is the query itself. + for i in range(n): + cnt = 0 + for j in range(self.GK + 1): + if I[i, j] != i: + knn_graph[i, cnt] = I[i, j] + cnt += 1 + if cnt == self.GK: + break + return knn_graph + + def subtest_io_and_clone(self, index, Dnsg, Insg): + fd, tmpfile = tempfile.mkstemp() + os.close(fd) + try: + faiss.write_index(index, tmpfile) + index2 = faiss.read_index(tmpfile) + finally: + if os.path.exists(tmpfile): + os.unlink(tmpfile) + + Dnsg2, Insg2 = index2.search(self.xq, 1) + np.testing.assert_array_equal(Dnsg2, Dnsg) + np.testing.assert_array_equal(Insg2, Insg) + + # also test clone + index3 = faiss.clone_index(index) + Dnsg3, Insg3 = index3.search(self.xq, 1) + np.testing.assert_array_equal(Dnsg3, Dnsg) + np.testing.assert_array_equal(Insg3, Insg) + + def subtest_connectivity(self, index, nb): + vt = faiss.VisitedTable(nb) + count = index.nsg.dfs(vt, index.nsg.enterpoint, 0) + self.assertEqual(count, nb) + + def subtest_add(self, build_type, thresh, metric=faiss.METRIC_L2): + d = self.xq.shape[1] + metrics = {faiss.METRIC_L2: 'L2', + faiss.METRIC_INNER_PRODUCT: 'IP'} + + flat_index = faiss.IndexFlat(d, metric) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, 1) + + index = faiss.IndexNSGFlat(d, 16, metric) + index.verbose = True + index.build_type = build_type + index.GK = self.GK + index.add(self.xb) + Dnsg, Insg = index.search(self.xq, 1) + + recalls = (Iref == Insg).sum() + print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) + self.assertGreaterEqual(recalls, thresh) + self.subtest_connectivity(index, self.xb.shape[0]) + self.subtest_io_and_clone(index, Dnsg, Insg) + + def subtest_build(self, knn_graph, thresh, metric=faiss.METRIC_L2): + d = self.xq.shape[1] + metrics = {faiss.METRIC_L2: 'L2', + faiss.METRIC_INNER_PRODUCT: 'IP'} + + flat_index = faiss.IndexFlat(d, metric) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, 1) + + index = faiss.IndexNSGFlat(d, 16, metric) + index.verbose = True + + index.build(self.xb, knn_graph) + Dnsg, Insg = index.search(self.xq, 1) + + recalls = (Iref == Insg).sum() + print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) + self.assertGreaterEqual(recalls, thresh) + self.subtest_connectivity(index, self.xb.shape[0]) + + def test_add_bruteforce_L2(self): + self.subtest_add(0, 475, faiss.METRIC_L2) + + def test_add_nndescent_L2(self): + self.subtest_add(1, 475, faiss.METRIC_L2) + + def test_add_bruteforce_IP(self): + self.subtest_add(0, 480, faiss.METRIC_INNER_PRODUCT) + + def test_add_nndescent_IP(self): + self.subtest_add(1, 480, faiss.METRIC_INNER_PRODUCT) + + def test_build_L2(self): + knn_graph = self.make_knn_graph(faiss.METRIC_L2) + self.subtest_build(knn_graph, 475, faiss.METRIC_L2) + + def test_build_IP(self): + knn_graph = self.make_knn_graph(faiss.METRIC_INNER_PRODUCT) + self.subtest_build(knn_graph, 480, faiss.METRIC_INNER_PRODUCT) + + def test_build_invalid_knng(self): + """Make some invalid entries in the input knn graph. + + It would cause a warning but IndexNSG should be able + to handel this. + """ + knn_graph = self.make_knn_graph(faiss.METRIC_L2) + knn_graph[:100, 5] = -111 + self.subtest_build(knn_graph, 475, faiss.METRIC_L2) + + knn_graph = self.make_knn_graph(faiss.METRIC_INNER_PRODUCT) + knn_graph[:100, 5] = -111 + self.subtest_build(knn_graph, 480, faiss.METRIC_INNER_PRODUCT) + + def test_reset(self): + """test IndexNSG.reset()""" + d = self.xq.shape[1] + metrics = {faiss.METRIC_L2: 'L2', + faiss.METRIC_INNER_PRODUCT: 'IP'} + + metric = faiss.METRIC_L2 + flat_index = faiss.IndexFlat(d, metric) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, 1) + + index = faiss.IndexNSGFlat(d, 16) + index.verbose = True + index.GK = 32 + + index.add(self.xb) + Dnsg, Insg = index.search(self.xq, 1) + recalls = (Iref == Insg).sum() + print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) + self.assertGreaterEqual(recalls, 475) + self.subtest_connectivity(index, self.xb.shape[0]) + + index.reset() + index.add(self.xb) + Dnsg, Insg = index.search(self.xq, 1) + recalls = (Iref == Insg).sum() + print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) + self.assertGreaterEqual(recalls, 475) + self.subtest_connectivity(index, self.xb.shape[0]) + + def test_order(self): + """make sure that output results are sorted""" + d = self.xq.shape[1] + index = faiss.IndexNSGFlat(d, 32) + + index.train(self.xb) + index.add(self.xb) + + k = 10 + nq = self.xq.shape[0] + D, _ = index.search(self.xq, k) + + indices = np.argsort(D, axis=1) + gt = np.arange(0, k)[np.newaxis, :] # [1, k] + gt = np.repeat(gt, nq, axis=0) # [nq, k] + np.testing.assert_array_equal(indices, gt) + + def test_nsg_pq(self): + """Test IndexNSGPQ""" + d = self.xq.shape[1] + R, pq_M = 32, 4 + index = faiss.index_factory(d, f"NSG{R}_PQ{pq_M}np") + assert isinstance(index, faiss.IndexNSGPQ) + idxpq = faiss.downcast_index(index.storage) + assert index.nsg.R == R and idxpq.pq.M == pq_M + + flat_index = faiss.IndexFlat(d) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, k=1) + + index.GK = 32 + index.train(self.xb) + index.add(self.xb) + D, I = index.search(self.xq, k=1) + + # test accuracy + recalls = (Iref == I).sum() + print("IndexNSGPQ", recalls) + self.assertGreaterEqual(recalls, 190) # 193 + + # test I/O + self.subtest_io_and_clone(index, D, I) + + def test_nsg_sq(self): + """Test IndexNSGSQ""" + d = self.xq.shape[1] + R = 32 + index = faiss.index_factory(d, f"NSG{R}_SQ8") + assert isinstance(index, faiss.IndexNSGSQ) + idxsq = faiss.downcast_index(index.storage) + assert index.nsg.R == R + assert idxsq.sq.qtype == faiss.ScalarQuantizer.QT_8bit + + flat_index = faiss.IndexFlat(d) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, k=1) + + index.train(self.xb) + index.add(self.xb) + D, I = index.search(self.xq, k=1) + + # test accuracy + recalls = (Iref == I).sum() + print("IndexNSGSQ", recalls) + self.assertGreaterEqual(recalls, 405) # 411 + + # test I/O + self.subtest_io_and_clone(index, D, I) + + +class TestNNDescent(unittest.TestCase): + + def __init__(self, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + d = 32 + nt = 0 + nb = 1500 + nq = 500 + self.GK = 32 + + _, self.xb, self.xq = get_dataset_2(d, nt, nb, nq) + + def test_nndescentflat(self): + d = self.xq.shape[1] + index = faiss.IndexNNDescentFlat(d, 32) + index.nndescent.search_L = 8 + + flat_index = faiss.IndexFlat(d) + flat_index.add(self.xb) + Dref, Iref = flat_index.search(self.xq, k=1) + + index.train(self.xb) + index.add(self.xb) + D, I = index.search(self.xq, k=1) + + # test accuracy + recalls = (Iref == I).sum() + print("IndexNNDescentFlat", recalls) + self.assertGreaterEqual(recalls, 450) # 462 + + # do some IO tests + fd, tmpfile = tempfile.mkstemp() + os.close(fd) + try: + faiss.write_index(index, tmpfile) + index2 = faiss.read_index(tmpfile) + finally: + if os.path.exists(tmpfile): + os.unlink(tmpfile) + + D2, I2 = index2.search(self.xq, 1) + np.testing.assert_array_equal(D2, D) + np.testing.assert_array_equal(I2, I) + + # also test clone + index3 = faiss.clone_index(index) + D3, I3 = index3.search(self.xq, 1) + np.testing.assert_array_equal(D3, D) + np.testing.assert_array_equal(I3, I) + + def test_order(self): + """make sure that output results are sorted""" + d = self.xq.shape[1] + index = faiss.IndexNNDescentFlat(d, 32) + + index.train(self.xb) + index.add(self.xb) + + k = 10 + nq = self.xq.shape[0] + D, _ = index.search(self.xq, k) + + indices = np.argsort(D, axis=1) + gt = np.arange(0, k)[np.newaxis, :] # [1, k] + gt = np.repeat(gt, nq, axis=0) # [nq, k] + np.testing.assert_array_equal(indices, gt) diff --git a/tests/test_index.py b/tests/test_index.py index 0e828e08c1..f46c6a94bf 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -526,406 +526,6 @@ def test_IndexTransform(self): self.run_search_and_reconstruct(index, xb, xq) -class TestHNSW(unittest.TestCase): - - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - d = 32 - nt = 0 - nb = 1500 - nq = 500 - - (_, self.xb, self.xq) = get_dataset_2(d, nt, nb, nq) - index = faiss.IndexFlatL2(d) - index.add(self.xb) - Dref, Iref = index.search(self.xq, 1) - self.Iref = Iref - - def test_hnsw(self): - d = self.xq.shape[1] - - index = faiss.IndexHNSWFlat(d, 16) - index.add(self.xb) - Dhnsw, Ihnsw = index.search(self.xq, 1) - - self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 460) - - self.io_and_retest(index, Dhnsw, Ihnsw) - - def test_hnsw_unbounded_queue(self): - d = self.xq.shape[1] - - index = faiss.IndexHNSWFlat(d, 16) - index.add(self.xb) - index.search_bounded_queue = False - Dhnsw, Ihnsw = index.search(self.xq, 1) - - self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 460) - - self.io_and_retest(index, Dhnsw, Ihnsw) - - def io_and_retest(self, index, Dhnsw, Ihnsw): - fd, tmpfile = tempfile.mkstemp() - os.close(fd) - try: - faiss.write_index(index, tmpfile) - index2 = faiss.read_index(tmpfile) - finally: - if os.path.exists(tmpfile): - os.unlink(tmpfile) - - Dhnsw2, Ihnsw2 = index2.search(self.xq, 1) - - self.assertTrue(np.all(Dhnsw2 == Dhnsw)) - self.assertTrue(np.all(Ihnsw2 == Ihnsw)) - - # also test clone - index3 = faiss.clone_index(index) - Dhnsw3, Ihnsw3 = index3.search(self.xq, 1) - - self.assertTrue(np.all(Dhnsw3 == Dhnsw)) - self.assertTrue(np.all(Ihnsw3 == Ihnsw)) - - - def test_hnsw_2level(self): - d = self.xq.shape[1] - - quant = faiss.IndexFlatL2(d) - - index = faiss.IndexHNSW2Level(quant, 256, 8, 8) - index.train(self.xb) - index.add(self.xb) - Dhnsw, Ihnsw = index.search(self.xq, 1) - - self.assertGreaterEqual((self.Iref == Ihnsw).sum(), 307) - - self.io_and_retest(index, Dhnsw, Ihnsw) - - def test_add_0_vecs(self): - index = faiss.IndexHNSWFlat(10, 16) - zero_vecs = np.zeros((0, 10), dtype='float32') - # infinite loop - index.add(zero_vecs) - - def test_hnsw_IP(self): - d = self.xq.shape[1] - - index_IP = faiss.IndexFlatIP(d) - index_IP.add(self.xb) - Dref, Iref = index_IP.search(self.xq, 1) - - index = faiss.IndexHNSWFlat(d, 16, faiss.METRIC_INNER_PRODUCT) - index.add(self.xb) - Dhnsw, Ihnsw = index.search(self.xq, 1) - - print('nb equal: ', (Iref == Ihnsw).sum()) - - self.assertGreaterEqual((Iref == Ihnsw).sum(), 470) - - mask = Iref[:, 0] == Ihnsw[:, 0] - assert np.allclose(Dref[mask, 0], Dhnsw[mask, 0]) - - -class TestNSG(unittest.TestCase): - - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - d = 32 - nt = 0 - nb = 1500 - nq = 500 - self.GK = 32 - - _, self.xb, self.xq = get_dataset_2(d, nt, nb, nq) - - def make_knn_graph(self, metric): - n = self.xb.shape[0] - d = self.xb.shape[1] - index = faiss.IndexFlat(d, metric) - index.add(self.xb) - _, I = index.search(self.xb, self.GK + 1) - knn_graph = np.zeros((n, self.GK), dtype=np.int64) - - # For the inner product distance, the distance between a vector and itself - # may not be the smallest, so it is not guaranteed that I[:, 0] is the query itself. - for i in range(n): - cnt = 0 - for j in range(self.GK + 1): - if I[i, j] != i: - knn_graph[i, cnt] = I[i, j] - cnt += 1 - if cnt == self.GK: - break - return knn_graph - - def subtest_io_and_clone(self, index, Dnsg, Insg): - fd, tmpfile = tempfile.mkstemp() - os.close(fd) - try: - faiss.write_index(index, tmpfile) - index2 = faiss.read_index(tmpfile) - finally: - if os.path.exists(tmpfile): - os.unlink(tmpfile) - - Dnsg2, Insg2 = index2.search(self.xq, 1) - np.testing.assert_array_equal(Dnsg2, Dnsg) - np.testing.assert_array_equal(Insg2, Insg) - - # also test clone - index3 = faiss.clone_index(index) - Dnsg3, Insg3 = index3.search(self.xq, 1) - np.testing.assert_array_equal(Dnsg3, Dnsg) - np.testing.assert_array_equal(Insg3, Insg) - - def subtest_connectivity(self, index, nb): - vt = faiss.VisitedTable(nb) - count = index.nsg.dfs(vt, index.nsg.enterpoint, 0) - self.assertEqual(count, nb) - - def subtest_add(self, build_type, thresh, metric=faiss.METRIC_L2): - d = self.xq.shape[1] - metrics = {faiss.METRIC_L2: 'L2', - faiss.METRIC_INNER_PRODUCT: 'IP'} - - flat_index = faiss.IndexFlat(d, metric) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, 1) - - index = faiss.IndexNSGFlat(d, 16, metric) - index.verbose = True - index.build_type = build_type - index.GK = self.GK - index.add(self.xb) - Dnsg, Insg = index.search(self.xq, 1) - - recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) - self.assertGreaterEqual(recalls, thresh) - self.subtest_connectivity(index, self.xb.shape[0]) - self.subtest_io_and_clone(index, Dnsg, Insg) - - def subtest_build(self, knn_graph, thresh, metric=faiss.METRIC_L2): - d = self.xq.shape[1] - metrics = {faiss.METRIC_L2: 'L2', - faiss.METRIC_INNER_PRODUCT: 'IP'} - - flat_index = faiss.IndexFlat(d, metric) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, 1) - - index = faiss.IndexNSGFlat(d, 16, metric) - index.verbose = True - - index.build(self.xb, knn_graph) - Dnsg, Insg = index.search(self.xq, 1) - - recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) - self.assertGreaterEqual(recalls, thresh) - self.subtest_connectivity(index, self.xb.shape[0]) - - def test_add_bruteforce_L2(self): - self.subtest_add(0, 475, faiss.METRIC_L2) - - def test_add_nndescent_L2(self): - self.subtest_add(1, 475, faiss.METRIC_L2) - - def test_add_bruteforce_IP(self): - self.subtest_add(0, 480, faiss.METRIC_INNER_PRODUCT) - - def test_add_nndescent_IP(self): - self.subtest_add(1, 480, faiss.METRIC_INNER_PRODUCT) - - def test_build_L2(self): - knn_graph = self.make_knn_graph(faiss.METRIC_L2) - self.subtest_build(knn_graph, 475, faiss.METRIC_L2) - - def test_build_IP(self): - knn_graph = self.make_knn_graph(faiss.METRIC_INNER_PRODUCT) - self.subtest_build(knn_graph, 480, faiss.METRIC_INNER_PRODUCT) - - def test_build_invalid_knng(self): - """Make some invalid entries in the input knn graph. - - It would cause a warning but IndexNSG should be able - to handel this. - """ - knn_graph = self.make_knn_graph(faiss.METRIC_L2) - knn_graph[:100, 5] = -111 - self.subtest_build(knn_graph, 475, faiss.METRIC_L2) - - knn_graph = self.make_knn_graph(faiss.METRIC_INNER_PRODUCT) - knn_graph[:100, 5] = -111 - self.subtest_build(knn_graph, 480, faiss.METRIC_INNER_PRODUCT) - - def test_reset(self): - """test IndexNSG.reset()""" - d = self.xq.shape[1] - metrics = {faiss.METRIC_L2: 'L2', - faiss.METRIC_INNER_PRODUCT: 'IP'} - - metric = faiss.METRIC_L2 - flat_index = faiss.IndexFlat(d, metric) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, 1) - - index = faiss.IndexNSGFlat(d, 16) - index.verbose = True - index.GK = 32 - - index.add(self.xb) - Dnsg, Insg = index.search(self.xq, 1) - recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) - self.assertGreaterEqual(recalls, 475) - self.subtest_connectivity(index, self.xb.shape[0]) - - index.reset() - index.add(self.xb) - Dnsg, Insg = index.search(self.xq, 1) - recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) - self.assertGreaterEqual(recalls, 475) - self.subtest_connectivity(index, self.xb.shape[0]) - - def test_order(self): - """make sure that output results are sorted""" - d = self.xq.shape[1] - index = faiss.IndexNSGFlat(d, 32) - - index.train(self.xb) - index.add(self.xb) - - k = 10 - nq = self.xq.shape[0] - D, _ = index.search(self.xq, k) - - indices = np.argsort(D, axis=1) - gt = np.arange(0, k)[np.newaxis, :] # [1, k] - gt = np.repeat(gt, nq, axis=0) # [nq, k] - np.testing.assert_array_equal(indices, gt) - - def test_nsg_pq(self): - """Test IndexNSGPQ""" - d = self.xq.shape[1] - R, pq_M = 32, 4 - index = faiss.index_factory(d, f"NSG{R}_PQ{pq_M}np") - assert isinstance(index, faiss.IndexNSGPQ) - idxpq = faiss.downcast_index(index.storage) - assert index.nsg.R == R and idxpq.pq.M == pq_M - - flat_index = faiss.IndexFlat(d) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, k=1) - - index.GK = 32 - index.train(self.xb) - index.add(self.xb) - D, I = index.search(self.xq, k=1) - - # test accuracy - recalls = (Iref == I).sum() - print("IndexNSGPQ", recalls) - self.assertGreaterEqual(recalls, 190) # 193 - - # test I/O - self.subtest_io_and_clone(index, D, I) - - def test_nsg_sq(self): - """Test IndexNSGSQ""" - d = self.xq.shape[1] - R = 32 - index = faiss.index_factory(d, f"NSG{R}_SQ8") - assert isinstance(index, faiss.IndexNSGSQ) - idxsq = faiss.downcast_index(index.storage) - assert index.nsg.R == R - assert idxsq.sq.qtype == faiss.ScalarQuantizer.QT_8bit - - flat_index = faiss.IndexFlat(d) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, k=1) - - index.train(self.xb) - index.add(self.xb) - D, I = index.search(self.xq, k=1) - - # test accuracy - recalls = (Iref == I).sum() - print("IndexNSGSQ", recalls) - self.assertGreaterEqual(recalls, 405) # 411 - - # test I/O - self.subtest_io_and_clone(index, D, I) - - -class TestNNDescent(unittest.TestCase): - - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - d = 32 - nt = 0 - nb = 1500 - nq = 500 - self.GK = 32 - - _, self.xb, self.xq = get_dataset_2(d, nt, nb, nq) - - def test_nndescentflat(self): - d = self.xq.shape[1] - index = faiss.IndexNNDescentFlat(d, 32) - index.nndescent.search_L = 8 - - flat_index = faiss.IndexFlat(d) - flat_index.add(self.xb) - Dref, Iref = flat_index.search(self.xq, k=1) - - index.train(self.xb) - index.add(self.xb) - D, I = index.search(self.xq, k=1) - - # test accuracy - recalls = (Iref == I).sum() - print("IndexNNDescentFlat", recalls) - self.assertGreaterEqual(recalls, 450) # 462 - - # do some IO tests - fd, tmpfile = tempfile.mkstemp() - os.close(fd) - try: - faiss.write_index(index, tmpfile) - index2 = faiss.read_index(tmpfile) - finally: - if os.path.exists(tmpfile): - os.unlink(tmpfile) - - D2, I2 = index2.search(self.xq, 1) - np.testing.assert_array_equal(D2, D) - np.testing.assert_array_equal(I2, I) - - # also test clone - index3 = faiss.clone_index(index) - D3, I3 = index3.search(self.xq, 1) - np.testing.assert_array_equal(D3, D) - np.testing.assert_array_equal(I3, I) - - def test_order(self): - """make sure that output results are sorted""" - d = self.xq.shape[1] - index = faiss.IndexNNDescentFlat(d, 32) - - index.train(self.xb) - index.add(self.xb) - - k = 10 - nq = self.xq.shape[0] - D, _ = index.search(self.xq, k) - - indices = np.argsort(D, axis=1) - gt = np.arange(0, k)[np.newaxis, :] # [1, k] - gt = np.repeat(gt, nq, axis=0) # [nq, k] - np.testing.assert_array_equal(indices, gt) - class TestDistancesPositive(unittest.TestCase): From c3aa526ec7410d7ad2c8b243439ecbbc8c8c76c5 Mon Sep 17 00:00:00 2001 From: Naveen Tatikonda Date: Thu, 11 Jan 2024 13:53:27 -0800 Subject: [PATCH 018/206] Add SIMD NEON Optimization for QT_FP16 in Scalar Quantizer (#3166) Summary: ### Description We have SIMD support for x86 architecture using AVX2 optimization. But, we don't have a similar optimization for ARM architecture in Scalar Quantizer for the Quantization Type `QT_FP16`. This PR adds SIMD support for ARM using NEON optimization. ### Issues resolved https://github.com/facebookresearch/faiss/issues/3014 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3166 Reviewed By: algoriddle, pemazare Differential Revision: D52510486 Pulled By: mdouze fbshipit-source-id: 2bb360475a0d9e0816c8e05b44d7da7f2e6b28c5 --- faiss/CMakeLists.txt | 1 + faiss/impl/ScalarQuantizer.cpp | 333 ++++++++++++++++++++++++++++++++- faiss/utils/fp16-arm.h | 29 +++ faiss/utils/fp16.h | 2 + 4 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 faiss/utils/fp16-arm.h diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index db5133d68b..22dac7cb2c 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -189,6 +189,7 @@ set(FAISS_HEADERS utils/extra_distances.h utils/fp16-fp16c.h utils/fp16-inl.h + utils/fp16-arm.h utils/fp16.h utils/hamming-inl.h utils/hamming.h diff --git a/faiss/impl/ScalarQuantizer.cpp b/faiss/impl/ScalarQuantizer.cpp index fc7b28eff4..07d77d5622 100644 --- a/faiss/impl/ScalarQuantizer.cpp +++ b/faiss/impl/ScalarQuantizer.cpp @@ -91,6 +91,20 @@ struct Codec8bit { return _mm256_fmadd_ps(f8, one_255, half_one_255); } #endif + +#ifdef __aarch64__ + static FAISS_ALWAYS_INLINE float32x4x2_t + decode_8_components(const uint8_t* code, int i) { + float32_t result[8] = {}; + for (size_t j = 0; j < 8; j++) { + result[j] = decode_component(code, i + j); + } + float32x4_t res1 = vld1q_f32(result); + float32x4_t res2 = vld1q_f32(result + 4); + float32x4x2_t res = vzipq_f32(res1, res2); + return vuzpq_f32(res.val[0], res.val[1]); + } +#endif }; struct Codec4bit { @@ -129,6 +143,20 @@ struct Codec4bit { return _mm256_mul_ps(f8, one_255); } #endif + +#ifdef __aarch64__ + static FAISS_ALWAYS_INLINE float32x4x2_t + decode_8_components(const uint8_t* code, int i) { + float32_t result[8] = {}; + for (size_t j = 0; j < 8; j++) { + result[j] = decode_component(code, i + j); + } + float32x4_t res1 = vld1q_f32(result); + float32x4_t res2 = vld1q_f32(result + 4); + float32x4x2_t res = vzipq_f32(res1, res2); + return vuzpq_f32(res.val[0], res.val[1]); + } +#endif }; struct Codec6bit { @@ -228,6 +256,20 @@ struct Codec6bit { } #endif + +#ifdef __aarch64__ + static FAISS_ALWAYS_INLINE float32x4x2_t + decode_8_components(const uint8_t* code, int i) { + float32_t result[8] = {}; + for (size_t j = 0; j < 8; j++) { + result[j] = decode_component(code, i + j); + } + float32x4_t res1 = vld1q_f32(result); + float32x4_t res2 = vld1q_f32(result + 4); + float32x4x2_t res = vzipq_f32(res1, res2); + return vuzpq_f32(res.val[0], res.val[1]); + } +#endif }; /******************************************************************* @@ -293,6 +335,31 @@ struct QuantizerTemplate : QuantizerTemplate { #endif +#ifdef __aarch64__ + +template +struct QuantizerTemplate : QuantizerTemplate { + QuantizerTemplate(size_t d, const std::vector& trained) + : QuantizerTemplate(d, trained) {} + + FAISS_ALWAYS_INLINE float32x4x2_t + reconstruct_8_components(const uint8_t* code, int i) const { + float32x4x2_t xi = Codec::decode_8_components(code, i); + float32x4x2_t res = vzipq_f32( + vfmaq_f32( + vdupq_n_f32(this->vmin), + xi.val[0], + vdupq_n_f32(this->vdiff)), + vfmaq_f32( + vdupq_n_f32(this->vmin), + xi.val[1], + vdupq_n_f32(this->vdiff))); + return vuzpq_f32(res.val[0], res.val[1]); + } +}; + +#endif + template struct QuantizerTemplate : ScalarQuantizer::SQuantizer { const size_t d; @@ -350,6 +417,29 @@ struct QuantizerTemplate : QuantizerTemplate { #endif +#ifdef __aarch64__ + +template +struct QuantizerTemplate : QuantizerTemplate { + QuantizerTemplate(size_t d, const std::vector& trained) + : QuantizerTemplate(d, trained) {} + + FAISS_ALWAYS_INLINE float32x4x2_t + reconstruct_8_components(const uint8_t* code, int i) const { + float32x4x2_t xi = Codec::decode_8_components(code, i); + + float32x4x2_t vmin_8 = vld1q_f32_x2(this->vmin + i); + float32x4x2_t vdiff_8 = vld1q_f32_x2(this->vdiff + i); + + float32x4x2_t res = vzipq_f32( + vfmaq_f32(vmin_8.val[0], xi.val[0], vdiff_8.val[0]), + vfmaq_f32(vmin_8.val[1], xi.val[1], vdiff_8.val[1])); + return vuzpq_f32(res.val[0], res.val[1]); + } +}; + +#endif + /******************************************************************* * FP16 quantizer *******************************************************************/ @@ -397,6 +487,23 @@ struct QuantizerFP16<8> : QuantizerFP16<1> { #endif +#ifdef __aarch64__ + +template <> +struct QuantizerFP16<8> : QuantizerFP16<1> { + QuantizerFP16(size_t d, const std::vector& trained) + : QuantizerFP16<1>(d, trained) {} + + FAISS_ALWAYS_INLINE float32x4x2_t + reconstruct_8_components(const uint8_t* code, int i) const { + uint16x4x2_t codei = vld2_u16((const uint16_t*)(code + 2 * i)); + return vzipq_f32( + vcvt_f32_f16(vreinterpret_f16_u16(codei.val[0])), + vcvt_f32_f16(vreinterpret_f16_u16(codei.val[1]))); + } +}; +#endif + /******************************************************************* * 8bit_direct quantizer *******************************************************************/ @@ -446,6 +553,28 @@ struct Quantizer8bitDirect<8> : Quantizer8bitDirect<1> { #endif +#ifdef __aarch64__ + +template <> +struct Quantizer8bitDirect<8> : Quantizer8bitDirect<1> { + Quantizer8bitDirect(size_t d, const std::vector& trained) + : Quantizer8bitDirect<1>(d, trained) {} + + FAISS_ALWAYS_INLINE float32x4x2_t + reconstruct_8_components(const uint8_t* code, int i) const { + float32_t result[8] = {}; + for (size_t j = 0; j < 8; j++) { + result[j] = code[i + j]; + } + float32x4_t res1 = vld1q_f32(result); + float32x4_t res2 = vld1q_f32(result + 4); + float32x4x2_t res = vzipq_f32(res1, res2); + return vuzpq_f32(res.val[0], res.val[1]); + } +}; + +#endif + template ScalarQuantizer::SQuantizer* select_quantizer_1( QuantizerType qtype, @@ -728,6 +857,59 @@ struct SimilarityL2<8> { #endif +#ifdef __aarch64__ +template <> +struct SimilarityL2<8> { + static constexpr int simdwidth = 8; + static constexpr MetricType metric_type = METRIC_L2; + + const float *y, *yi; + explicit SimilarityL2(const float* y) : y(y) {} + float32x4x2_t accu8; + + FAISS_ALWAYS_INLINE void begin_8() { + accu8 = vzipq_f32(vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)); + yi = y; + } + + FAISS_ALWAYS_INLINE void add_8_components(float32x4x2_t x) { + float32x4x2_t yiv = vld1q_f32_x2(yi); + yi += 8; + + float32x4_t sub0 = vsubq_f32(yiv.val[0], x.val[0]); + float32x4_t sub1 = vsubq_f32(yiv.val[1], x.val[1]); + + float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], sub0, sub0); + float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], sub1, sub1); + + float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); + accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + } + + FAISS_ALWAYS_INLINE void add_8_components_2( + float32x4x2_t x, + float32x4x2_t y) { + float32x4_t sub0 = vsubq_f32(y.val[0], x.val[0]); + float32x4_t sub1 = vsubq_f32(y.val[1], x.val[1]); + + float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], sub0, sub0); + float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], sub1, sub1); + + float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); + accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + } + + FAISS_ALWAYS_INLINE float result_8() { + float32x4_t sum_0 = vpaddq_f32(accu8.val[0], accu8.val[0]); + float32x4_t sum_1 = vpaddq_f32(accu8.val[1], accu8.val[1]); + + float32x4_t sum2_0 = vpaddq_f32(sum_0, sum_0); + float32x4_t sum2_1 = vpaddq_f32(sum_1, sum_1); + return vgetq_lane_f32(sum2_0, 0) + vgetq_lane_f32(sum2_1, 0); + } +}; +#endif + template struct SimilarityIP {}; @@ -801,6 +983,56 @@ struct SimilarityIP<8> { }; #endif +#ifdef __aarch64__ + +template <> +struct SimilarityIP<8> { + static constexpr int simdwidth = 8; + static constexpr MetricType metric_type = METRIC_INNER_PRODUCT; + + const float *y, *yi; + + explicit SimilarityIP(const float* y) : y(y) {} + float32x4x2_t accu8; + + FAISS_ALWAYS_INLINE void begin_8() { + accu8 = vzipq_f32(vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)); + yi = y; + } + + FAISS_ALWAYS_INLINE void add_8_components(float32x4x2_t x) { + float32x4x2_t yiv = vld1q_f32_x2(yi); + yi += 8; + + float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], yiv.val[0], x.val[0]); + float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], yiv.val[1], x.val[1]); + float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); + accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + } + + FAISS_ALWAYS_INLINE void add_8_components_2( + float32x4x2_t x1, + float32x4x2_t x2) { + float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], x1.val[0], x2.val[0]); + float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], x1.val[1], x2.val[1]); + float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); + accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + } + + FAISS_ALWAYS_INLINE float result_8() { + float32x4x2_t sum_tmp = vzipq_f32( + vpaddq_f32(accu8.val[0], accu8.val[0]), + vpaddq_f32(accu8.val[1], accu8.val[1])); + float32x4x2_t sum = vuzpq_f32(sum_tmp.val[0], sum_tmp.val[1]); + float32x4x2_t sum2_tmp = vzipq_f32( + vpaddq_f32(sum.val[0], sum.val[0]), + vpaddq_f32(sum.val[1], sum.val[1])); + float32x4x2_t sum2 = vuzpq_f32(sum2_tmp.val[0], sum2_tmp.val[1]); + return vgetq_lane_f32(sum2.val[0], 0) + vgetq_lane_f32(sum2.val[1], 0); + } +}; +#endif + /******************************************************************* * DistanceComputer: combines a similarity and a quantizer to do * code-to-vector or code-to-code comparisons @@ -903,6 +1135,53 @@ struct DCTemplate : SQDistanceComputer { #endif +#ifdef __aarch64__ + +template +struct DCTemplate : SQDistanceComputer { + using Sim = Similarity; + + Quantizer quant; + + DCTemplate(size_t d, const std::vector& trained) + : quant(d, trained) {} + float compute_distance(const float* x, const uint8_t* code) const { + Similarity sim(x); + sim.begin_8(); + for (size_t i = 0; i < quant.d; i += 8) { + float32x4x2_t xi = quant.reconstruct_8_components(code, i); + sim.add_8_components(xi); + } + return sim.result_8(); + } + + float compute_code_distance(const uint8_t* code1, const uint8_t* code2) + const { + Similarity sim(nullptr); + sim.begin_8(); + for (size_t i = 0; i < quant.d; i += 8) { + float32x4x2_t x1 = quant.reconstruct_8_components(code1, i); + float32x4x2_t x2 = quant.reconstruct_8_components(code2, i); + sim.add_8_components_2(x1, x2); + } + return sim.result_8(); + } + + void set_query(const float* x) final { + q = x; + } + + float symmetric_dis(idx_t i, idx_t j) override { + return compute_code_distance( + codes + i * code_size, codes + j * code_size); + } + + float query_to_code(const uint8_t* code) const final { + return compute_distance(q, code); + } +}; +#endif + /******************************************************************* * DistanceComputerByte: computes distances in the integer domain *******************************************************************/ @@ -1019,6 +1298,54 @@ struct DistanceComputerByte : SQDistanceComputer { #endif +#ifdef __aarch64__ + +template +struct DistanceComputerByte : SQDistanceComputer { + using Sim = Similarity; + + int d; + std::vector tmp; + + DistanceComputerByte(int d, const std::vector&) : d(d), tmp(d) {} + + int compute_code_distance(const uint8_t* code1, const uint8_t* code2) + const { + int accu = 0; + for (int i = 0; i < d; i++) { + if (Sim::metric_type == METRIC_INNER_PRODUCT) { + accu += int(code1[i]) * code2[i]; + } else { + int diff = int(code1[i]) - code2[i]; + accu += diff * diff; + } + } + return accu; + } + + void set_query(const float* x) final { + for (int i = 0; i < d; i++) { + tmp[i] = int(x[i]); + } + } + + int compute_distance(const float* x, const uint8_t* code) { + set_query(x); + return compute_code_distance(tmp.data(), code); + } + + float symmetric_dis(idx_t i, idx_t j) override { + return compute_code_distance( + codes + i * code_size, codes + j * code_size); + } + + float query_to_code(const uint8_t* code) const final { + return compute_code_distance(tmp.data(), code); + } +}; + +#endif + /******************************************************************* * select_distance_computer: runtime selection of template * specialization @@ -1155,7 +1482,7 @@ void ScalarQuantizer::train(size_t n, const float* x) { } ScalarQuantizer::SQuantizer* ScalarQuantizer::select_quantizer() const { -#ifdef USE_F16C +#if defined(USE_F16C) || defined(__aarch64__) if (d % 8 == 0) { return select_quantizer_1<8>(qtype, d, trained); } else @@ -1186,7 +1513,7 @@ void ScalarQuantizer::decode(const uint8_t* codes, float* x, size_t n) const { SQDistanceComputer* ScalarQuantizer::get_distance_computer( MetricType metric) const { FAISS_THROW_IF_NOT(metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT); -#ifdef USE_F16C +#if defined(USE_F16C) || defined(__aarch64__) if (d % 8 == 0) { if (metric == METRIC_L2) { return select_distance_computer>(qtype, d, trained); @@ -1522,7 +1849,7 @@ InvertedListScanner* ScalarQuantizer::select_InvertedListScanner( bool store_pairs, const IDSelector* sel, bool by_residual) const { -#ifdef USE_F16C +#if defined(USE_F16C) || defined(__aarch64__) if (d % 8 == 0) { return sel0_InvertedListScanner<8>( mt, this, quantizer, store_pairs, sel, by_residual); diff --git a/faiss/utils/fp16-arm.h b/faiss/utils/fp16-arm.h new file mode 100644 index 0000000000..79c885b058 --- /dev/null +++ b/faiss/utils/fp16-arm.h @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace faiss { + +inline uint16_t encode_fp16(float x) { + float32x4_t fx4 = vdupq_n_f32(x); + float16x4_t f16x4 = vcvt_f16_f32(fx4); + uint16x4_t ui16x4 = vreinterpret_u16_f16(f16x4); + return vduph_lane_u16(ui16x4, 3); +} + +inline float decode_fp16(uint16_t x) { + uint16x4_t ui16x4 = vdup_n_u16(x); + float16x4_t f16x4 = vreinterpret_f16_u16(ui16x4); + float32x4_t fx4 = vcvt_f32_f16(f16x4); + return vdups_laneq_f32(fx4, 3); +} + +} // namespace faiss diff --git a/faiss/utils/fp16.h b/faiss/utils/fp16.h index 90691d8ffe..43e05dc3d3 100644 --- a/faiss/utils/fp16.h +++ b/faiss/utils/fp16.h @@ -13,6 +13,8 @@ #if defined(__F16C__) #include +#elif defined(__aarch64__) +#include #else #include #endif From b7efd3add75f58abc79f629587ab38c1f6538d67 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Sat, 13 Jan 2024 10:05:35 -0800 Subject: [PATCH 019/206] bump libraft version to fix nightly Summary: Diff summary courtesy of Metamate: This diff bumps the version of libraft to fix nightly issues in the faiss-gpu-raft package. The code changes include updating the libraft version in the meta.yaml file to 24.02. This change is necessary to ensure that the package is compatible with the latest version of libraft. Reviewed By: mlomeli1 Differential Revision: D52736355 fbshipit-source-id: 7ac2427210c06eb2d1c3ab4a3d37d48494fb039e --- conda/faiss-gpu-raft/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 387f8b4ac0..84aa826c6c 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -48,12 +48,12 @@ outputs: - mkl =2023 # [x86_64] - openblas # [not x86_64] - cuda-version {{ cudatoolkit }} - - libraft =23.12 + - libraft =24.02 run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - {{ pin_compatible('cuda-version', max_pin='x') }} - - libraft =23.12 + - libraft =24.02 test: requires: - conda-build From f884ba240ea7ce948ce850c31f82bb2e9eac21b0 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 14 Jan 2024 15:22:31 -0800 Subject: [PATCH 020/206] Remove unused variables in faiss/IndexHNSW.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52734573 fbshipit-source-id: edf315a4e2e7ddfaf8b879b7f4a3fc3a6c2e607f --- faiss/IndexHNSW.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index c40136749b..9a67332d67 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -733,7 +733,6 @@ int search_from_candidates_2( int level, int nres_in = 0) { int nres = nres_in; - int ndis = 0; for (int i = 0; i < candidates.size(); i++) { idx_t v1 = candidates.ids[i]; FAISS_ASSERT(v1 >= 0); @@ -756,7 +755,6 @@ int search_from_candidates_2( if (vt.visited[v1] == vt.visno + 1) { // nothing to do } else { - ndis++; float d = qdis(v1); candidates.push(v1, d); From cfcefc05952372faf973b68246de40f3f691e4bf Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 14 Jan 2024 15:23:28 -0800 Subject: [PATCH 021/206] Remove unused variables in faiss/utils/sorting.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52734585 fbshipit-source-id: be5da3411d2965f6cd2516376598576049c03f09 --- faiss/utils/sorting.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/faiss/utils/sorting.cpp b/faiss/utils/sorting.cpp index 76fa5e6201..3c69f705a9 100644 --- a/faiss/utils/sorting.cpp +++ b/faiss/utils/sorting.cpp @@ -544,7 +544,6 @@ void bucket_sort_inplace_parallel( // in this loop, we write elements collected in the previous round // and collect the elements that are overwritten for the next round - size_t tot_written = 0; int round = 0; for (;;) { #pragma omp barrier @@ -554,9 +553,6 @@ void bucket_sort_inplace_parallel( n_to_write += to_write_2.lims.back(); } - tot_written += n_to_write; - // assert(tot_written <= nval); - #pragma omp master { if (verbose >= 1) { From 7442a54d019c4b8a4a949f859274b065478e458c Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 14 Jan 2024 15:39:59 -0800 Subject: [PATCH 022/206] Fix shadowed variable in faiss/impl/index_write.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582916 fbshipit-source-id: 367ea85b569063efa50c82702c3ba5efa2fb92f9 --- faiss/impl/index_write.cpp | 79 ++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/faiss/impl/index_write.cpp b/faiss/impl/index_write.cpp index 84484e799c..7bb302700d 100644 --- a/faiss/impl/index_write.cpp +++ b/faiss/impl/index_write.cpp @@ -433,13 +433,14 @@ void write_index(const Index* idx, IOWriter* f) { WRITE1(idxr->code_size); WRITEVECTOR(idxr->codes); } else if ( - auto* idxr = dynamic_cast(idx)) { + auto* idxr_2 = + dynamic_cast(idx)) { uint32_t h = fourcc("IxLS"); WRITE1(h); write_index_header(idx, f); - write_LocalSearchQuantizer(&idxr->lsq, f); - WRITE1(idxr->code_size); - WRITEVECTOR(idxr->codes); + write_LocalSearchQuantizer(&idxr_2->lsq, f); + WRITE1(idxr_2->code_size); + WRITEVECTOR(idxr_2->codes); } else if ( const IndexProductResidualQuantizer* idxpr = dynamic_cast(idx)) { @@ -572,26 +573,26 @@ void write_index(const Index* idx, IOWriter* f) { write_InvertedLists(ivaqfs->invlists, f); } else if ( - const ResidualCoarseQuantizer* idxr = + const ResidualCoarseQuantizer* idxr_2 = dynamic_cast(idx)) { uint32_t h = fourcc("ImRQ"); WRITE1(h); write_index_header(idx, f); - write_ResidualQuantizer(&idxr->rq, f); - WRITE1(idxr->beam_factor); + write_ResidualQuantizer(&idxr_2->rq, f); + WRITE1(idxr_2->beam_factor); } else if ( - const Index2Layer* idxp = dynamic_cast(idx)) { + const Index2Layer* idxp_2 = dynamic_cast(idx)) { uint32_t h = fourcc("Ix2L"); WRITE1(h); write_index_header(idx, f); - write_index(idxp->q1.quantizer, f); - WRITE1(idxp->q1.nlist); - WRITE1(idxp->q1.quantizer_trains_alone); - write_ProductQuantizer(&idxp->pq, f); - WRITE1(idxp->code_size_1); - WRITE1(idxp->code_size_2); - WRITE1(idxp->code_size); - WRITEVECTOR(idxp->codes); + write_index(idxp_2->q1.quantizer, f); + WRITE1(idxp_2->q1.nlist); + WRITE1(idxp_2->q1.quantizer_trains_alone); + write_ProductQuantizer(&idxp_2->pq, f); + WRITE1(idxp_2->code_size_1); + WRITE1(idxp_2->code_size_2); + WRITE1(idxp_2->code_size); + WRITEVECTOR(idxp_2->codes); } else if ( const IndexScalarQuantizer* idxs = dynamic_cast(idx)) { @@ -601,15 +602,16 @@ void write_index(const Index* idx, IOWriter* f) { write_ScalarQuantizer(&idxs->sq, f); WRITEVECTOR(idxs->codes); } else if ( - const IndexLattice* idxl = dynamic_cast(idx)) { + const IndexLattice* idxl_2 = + dynamic_cast(idx)) { uint32_t h = fourcc("IxLa"); WRITE1(h); - WRITE1(idxl->d); - WRITE1(idxl->nsq); - WRITE1(idxl->scale_nbit); - WRITE1(idxl->zn_sphere_codec.r2); + WRITE1(idxl_2->d); + WRITE1(idxl_2->nsq); + WRITE1(idxl_2->scale_nbit); + WRITE1(idxl_2->zn_sphere_codec.r2); write_index_header(idx, f); - WRITEVECTOR(idxl->trained); + WRITEVECTOR(idxl_2->trained); } else if ( const IndexIVFFlatDedup* ivfl = dynamic_cast(idx)) { @@ -628,11 +630,12 @@ void write_index(const Index* idx, IOWriter* f) { } write_InvertedLists(ivfl->invlists, f); } else if ( - const IndexIVFFlat* ivfl = dynamic_cast(idx)) { + const IndexIVFFlat* ivfl_2 = + dynamic_cast(idx)) { uint32_t h = fourcc("IwFl"); WRITE1(h); - write_ivf_header(ivfl, f); - write_InvertedLists(ivfl->invlists, f); + write_ivf_header(ivfl_2, f); + write_InvertedLists(ivfl_2->invlists, f); } else if ( const IndexIVFScalarQuantizer* ivsc = dynamic_cast(idx)) { @@ -806,19 +809,19 @@ void write_index(const Index* idx, IOWriter* f) { WRITE1(idxpqfs->M2); WRITEVECTOR(idxpqfs->codes); } else if ( - const IndexIVFPQFastScan* ivpq = + const IndexIVFPQFastScan* ivpq_2 = dynamic_cast(idx)) { uint32_t h = fourcc("IwPf"); WRITE1(h); - write_ivf_header(ivpq, f); - WRITE1(ivpq->by_residual); - WRITE1(ivpq->code_size); - WRITE1(ivpq->bbs); - WRITE1(ivpq->M2); - WRITE1(ivpq->implem); - WRITE1(ivpq->qbs2); - write_ProductQuantizer(&ivpq->pq, f); - write_InvertedLists(ivpq->invlists, f); + write_ivf_header(ivpq_2, f); + WRITE1(ivpq_2->by_residual); + WRITE1(ivpq_2->code_size); + WRITE1(ivpq_2->bbs); + WRITE1(ivpq_2->M2); + WRITE1(ivpq_2->implem); + WRITE1(ivpq_2->qbs2); + write_ProductQuantizer(&ivpq_2->pq, f); + write_InvertedLists(ivpq_2->invlists, f); } else if ( const IndexRowwiseMinMax* imm = dynamic_cast(idx)) { @@ -828,13 +831,13 @@ void write_index(const Index* idx, IOWriter* f) { write_index_header(imm, f); write_index(imm->index, f); } else if ( - const IndexRowwiseMinMaxFP16* imm = + const IndexRowwiseMinMaxFP16* imm_2 = dynamic_cast(idx)) { // IndexRowwiseMinmaxHalf uint32_t h = fourcc("IRMh"); WRITE1(h); - write_index_header(imm, f); - write_index(imm->index, f); + write_index_header(imm_2, f); + write_index(imm_2->index, f); } else { FAISS_THROW_MSG("don't know how to serialize this type of index"); } From 1be1d3233ad16f2bc673f426fed57435ac36cdee Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 14 Jan 2024 15:42:08 -0800 Subject: [PATCH 023/206] Fix shadowed variable in faiss/impl/io.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582928 fbshipit-source-id: 57bd901e87cbb8ddfd423c8ae6baefe1048c206f --- faiss/impl/io.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/faiss/impl/io.cpp b/faiss/impl/io.cpp index 3837525138..5d24e58591 100644 --- a/faiss/impl/io.cpp +++ b/faiss/impl/io.cpp @@ -196,13 +196,13 @@ size_t BufferedIOWriter::operator()( while (size > 0) { assert(b0 == bsz); // now we need to flush to add more bytes - size_t ofs = 0; + size_t ofs_2 = 0; do { - assert(ofs < 10000000); - size_t written = (*writer)(buffer.data() + ofs, 1, bsz - ofs); + assert(ofs_2 < 10000000); + size_t written = (*writer)(buffer.data() + ofs_2, 1, bsz - ofs_2); FAISS_THROW_IF_NOT(written > 0); - ofs += written; - } while (ofs != bsz); + ofs_2 += written; + } while (ofs_2 != bsz); // copy src to buffer size_t nb1 = std::min(bsz, size); @@ -217,12 +217,12 @@ size_t BufferedIOWriter::operator()( } BufferedIOWriter::~BufferedIOWriter() { - size_t ofs = 0; - while (ofs != b0) { - // printf("Destructor write %zd \n", b0 - ofs); - size_t written = (*writer)(buffer.data() + ofs, 1, b0 - ofs); + size_t ofs_2 = 0; + while (ofs_2 != b0) { + // printf("Destructor write %zd \n", b0 - ofs_2); + size_t written = (*writer)(buffer.data() + ofs_2, 1, b0 - ofs_2); FAISS_THROW_IF_NOT(written > 0); - ofs += written; + ofs_2 += written; } } From 46320e0e7a2e6899b65a58eb989039ec466eb28b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 14 Jan 2024 15:44:03 -0800 Subject: [PATCH 024/206] Fix shadowed variable in faiss/utils/hamming_distance/avx2-inl.h Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582813 fbshipit-source-id: 02a742df17614c546e10446bc530835e876942f0 --- faiss/utils/hamming_distance/avx2-inl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/utils/hamming_distance/avx2-inl.h b/faiss/utils/hamming_distance/avx2-inl.h index fdc746c019..5cdc6a2b46 100644 --- a/faiss/utils/hamming_distance/avx2-inl.h +++ b/faiss/utils/hamming_distance/avx2-inl.h @@ -259,8 +259,8 @@ struct HammingComputerDefault { set(a8, code_size); } - void set(const uint8_t* a8, int code_size) { - this->a8 = a8; + void set(const uint8_t* a8_2, int code_size) { + this->a8 = a8_2; quotient8 = code_size / 8; remainder8 = code_size % 8; } From 3973017742620b38d7d9007ef804f44275be62b3 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 15 Jan 2024 19:29:08 -0800 Subject: [PATCH 025/206] Fix shadowed variable in faiss/IndexBinaryIVF.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D52582927 fbshipit-source-id: be03fb1354898d0637d287f285ea99d096c39008 --- faiss/IndexBinaryIVF.cpp | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/faiss/IndexBinaryIVF.cpp b/faiss/IndexBinaryIVF.cpp index f49127f6b2..1937b1f87d 100644 --- a/faiss/IndexBinaryIVF.cpp +++ b/faiss/IndexBinaryIVF.cpp @@ -119,16 +119,16 @@ void IndexBinaryIVF::search( FAISS_THROW_IF_NOT(k > 0); FAISS_THROW_IF_NOT(nprobe > 0); - const size_t nprobe = std::min(nlist, this->nprobe); - std::unique_ptr idx(new idx_t[n * nprobe]); - std::unique_ptr coarse_dis(new int32_t[n * nprobe]); + const size_t nprobe_2 = std::min(nlist, this->nprobe); + std::unique_ptr idx(new idx_t[n * nprobe_2]); + std::unique_ptr coarse_dis(new int32_t[n * nprobe_2]); double t0 = getmillisecs(); - quantizer->search(n, x, nprobe, coarse_dis.get(), idx.get()); + quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get()); indexIVF_stats.quantization_time += getmillisecs() - t0; t0 = getmillisecs(); - invlists->prefetch_lists(idx.get(), n * nprobe); + invlists->prefetch_lists(idx.get(), n * nprobe_2); search_preassigned( n, x, k, idx.get(), coarse_dis.get(), distances, labels, false); @@ -169,16 +169,16 @@ void IndexBinaryIVF::search_and_reconstruct( const SearchParameters* params) const { FAISS_THROW_IF_NOT_MSG( !params, "search params not supported for this index"); - const size_t nprobe = std::min(nlist, this->nprobe); + const size_t nprobe_2 = std::min(nlist, this->nprobe); FAISS_THROW_IF_NOT(k > 0); - FAISS_THROW_IF_NOT(nprobe > 0); + FAISS_THROW_IF_NOT(nprobe_2 > 0); - std::unique_ptr idx(new idx_t[n * nprobe]); - std::unique_ptr coarse_dis(new int32_t[n * nprobe]); + std::unique_ptr idx(new idx_t[n * nprobe_2]); + std::unique_ptr coarse_dis(new int32_t[n * nprobe_2]); - quantizer->search(n, x, nprobe, coarse_dis.get(), idx.get()); + quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get()); - invlists->prefetch_lists(idx.get(), n * nprobe); + invlists->prefetch_lists(idx.get(), n * nprobe_2); // search_preassigned() with `store_pairs` enabled to obtain the list_no // and offset into `codes` for reconstruction @@ -321,8 +321,8 @@ struct IVFBinaryScannerL2 : BinaryInvertedListScanner { } idx_t list_no; - void set_list(idx_t list_no, uint8_t /* coarse_dis */) override { - this->list_no = list_no; + void set_list(idx_t list_no_2, uint8_t /* coarse_dis */) override { + this->list_no = list_no_2; } uint32_t distance_to_code(const uint8_t* code) const override { @@ -812,16 +812,16 @@ void IndexBinaryIVF::range_search( const SearchParameters* params) const { FAISS_THROW_IF_NOT_MSG( !params, "search params not supported for this index"); - const size_t nprobe = std::min(nlist, this->nprobe); - std::unique_ptr idx(new idx_t[n * nprobe]); - std::unique_ptr coarse_dis(new int32_t[n * nprobe]); + const size_t nprobe_2 = std::min(nlist, this->nprobe); + std::unique_ptr idx(new idx_t[n * nprobe_2]); + std::unique_ptr coarse_dis(new int32_t[n * nprobe_2]); double t0 = getmillisecs(); - quantizer->search(n, x, nprobe, coarse_dis.get(), idx.get()); + quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get()); indexIVF_stats.quantization_time += getmillisecs() - t0; t0 = getmillisecs(); - invlists->prefetch_lists(idx.get(), n * nprobe); + invlists->prefetch_lists(idx.get(), n * nprobe_2); range_search_preassigned(n, x, radius, idx.get(), coarse_dis.get(), res); @@ -835,7 +835,7 @@ void IndexBinaryIVF::range_search_preassigned( const idx_t* __restrict assign, const int32_t* __restrict centroid_dis, RangeSearchResult* __restrict res) const { - const size_t nprobe = std::min(nlist, this->nprobe); + const size_t nprobe_2 = std::min(nlist, this->nprobe); bool store_pairs = false; size_t nlistv = 0, ndis = 0; @@ -851,7 +851,7 @@ void IndexBinaryIVF::range_search_preassigned( all_pres[omp_get_thread_num()] = &pres; auto scan_list_func = [&](size_t i, size_t ik, RangeQueryResult& qres) { - idx_t key = assign[i * nprobe + ik]; /* select the list */ + idx_t key = assign[i * nprobe_2 + ik]; /* select the list */ if (key < 0) return; FAISS_THROW_IF_NOT_FMT( @@ -868,7 +868,7 @@ void IndexBinaryIVF::range_search_preassigned( InvertedLists::ScopedCodes scodes(invlists, key); InvertedLists::ScopedIds ids(invlists, key); - scanner->set_list(key, assign[i * nprobe + ik]); + scanner->set_list(key, assign[i * nprobe_2 + ik]); nlistv++; ndis += list_size; scanner->scan_codes_range( @@ -881,7 +881,7 @@ void IndexBinaryIVF::range_search_preassigned( RangeQueryResult& qres = pres.new_result(i); - for (size_t ik = 0; ik < nprobe; ik++) { + for (size_t ik = 0; ik < nprobe_2; ik++) { scan_list_func(i, ik, qres); } } From 4150fb1827dc4b720c2814b6e983530fee155d59 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 15 Jan 2024 20:53:34 -0800 Subject: [PATCH 026/206] Fix shadowed variable in faiss/impl/PolysemousTraining.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582870 fbshipit-source-id: 4c81218e109ff97052036645ab33bc9b17802e91 --- faiss/impl/PolysemousTraining.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/faiss/impl/PolysemousTraining.cpp b/faiss/impl/PolysemousTraining.cpp index 1f01fc9dcf..a3bd400fb6 100644 --- a/faiss/impl/PolysemousTraining.cpp +++ b/faiss/impl/PolysemousTraining.cpp @@ -683,18 +683,21 @@ struct RankingScore2 : Score3Computer { double accum_gt_weight_diff( const std::vector& a, const std::vector& b) { - int nb = b.size(), na = a.size(); + const auto nb_2 = b.size(); + const auto na = a.size(); double accu = 0; - int j = 0; - for (int i = 0; i < na; i++) { - int ai = a[i]; - while (j < nb && ai >= b[j]) + size_t j = 0; + for (size_t i = 0; i < na; i++) { + const auto ai = a[i]; + while (j < nb_2 && ai >= b[j]) { j++; + } double accu_i = 0; - for (int k = j; k < b.size(); k++) + for (auto k = j; k < b.size(); k++) { accu_i += rank_weight(b[k] - ai); + } accu += rank_weight(ai) * accu_i; } From 0fc8456e1db0846759bd8d76a03ebe497c511a9f Mon Sep 17 00:00:00 2001 From: Maria Lomeli Date: Tue, 16 Jan 2024 05:05:15 -0800 Subject: [PATCH 027/206] Offline IVF powered by faiss big batch search (#3202) Summary: This PR introduces the offline IVF (OIVF) framework which contains some tooling to run search using IVFPQ indexes (plus OPQ pretransforms) for large batches of queries using [big_batch_search](https://github.com/mlomeli1/faiss/blob/main/contrib/big_batch_search.py) and GPU faiss. See the [README](https://github.com/facebookresearch/faiss/blob/36226f5fe8412162863d7d5d4cab97809f4d211d/demos/offline_ivf/README.md) for details about using this framework. This PR includes the following unit tests, which can be run with the unittest library as so: ```` ~/faiss/demos/offline_ivf$ python3 -m unittest tests/test_iterate_input.py -k test_iterate_back ```` In test_offline_ivf: ```` test_consistency_check test_train_index test_index_shard_equal_file_sizes test_index_shard_unequal_file_sizes test_search test_evaluate_without_margin test_evaluate_without_margin_OPQ ```` In test_iterate_input: ```` test_iterate_input_file_larger_than_batch test_get_vs_iterate test_iterate_back ```` Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3202 Reviewed By: algoriddle Differential Revision: D52734222 Pulled By: mlomeli1 fbshipit-source-id: 61fd0084277c1b14bdae1189db8ae43340611e16 --- demos/offline_ivf/README.md | 52 + demos/offline_ivf/__init__.py | 0 demos/offline_ivf/config_ssnpp.yaml | 109 ++ .../offline_ivf/create_sharded_ssnpp_files.py | 63 ++ demos/offline_ivf/dataset.py | 173 ++++ demos/offline_ivf/generate_config.py | 45 + demos/offline_ivf/offline_ivf.py | 938 ++++++++++++++++++ demos/offline_ivf/run.py | 218 ++++ demos/offline_ivf/tests/test_iterate_input.py | 132 +++ demos/offline_ivf/tests/test_offline_ivf.py | 288 ++++++ demos/offline_ivf/tests/testing_utils.py | 180 ++++ demos/offline_ivf/utils.py | 94 ++ 12 files changed, 2292 insertions(+) create mode 100644 demos/offline_ivf/README.md create mode 100644 demos/offline_ivf/__init__.py create mode 100644 demos/offline_ivf/config_ssnpp.yaml create mode 100644 demos/offline_ivf/create_sharded_ssnpp_files.py create mode 100644 demos/offline_ivf/dataset.py create mode 100644 demos/offline_ivf/generate_config.py create mode 100644 demos/offline_ivf/offline_ivf.py create mode 100644 demos/offline_ivf/run.py create mode 100644 demos/offline_ivf/tests/test_iterate_input.py create mode 100644 demos/offline_ivf/tests/test_offline_ivf.py create mode 100644 demos/offline_ivf/tests/testing_utils.py create mode 100644 demos/offline_ivf/utils.py diff --git a/demos/offline_ivf/README.md b/demos/offline_ivf/README.md new file mode 100644 index 0000000000..df848ba0ab --- /dev/null +++ b/demos/offline_ivf/README.md @@ -0,0 +1,52 @@ + +# Offline IVF + +This folder contains the code for the offline ivf algorithm powered by faiss big batch search. + +Create a conda env: + +`conda create --name oivf python=3.10` + +`conda activate oivf` + +`conda install -c pytorch/label/nightly -c nvidia faiss-gpu=1.7.4` + +`conda install tqdm` + +`conda install pyyaml` + +`conda install -c conda-forge submitit` + + +## Run book + +1. Optionally shard your dataset (see create_sharded_dataset.py) and create the corresponding yaml file `config_ssnpp.yaml`. You can use `generate_config.py` by specifying the root directory of your dataset and the files with the data shards + +`python generate_config` + +2. Run the train index command + +`python run.py --command train_index --config config_ssnpp.yaml --xb ssnpp_1B` + + +3. Run the index-shard command so it produces sharded indexes, required for the search step + +`python run.py --command index_shard --config config_ssnpp.yaml --xb ssnpp_1B` + + +6. Send jobs to the cluster to run search + +`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --cluster_run --partition ` + + +Remarks about the `search` command: it is assumed that the database vectors are the query vectors when performing the search step. +a. If the query vectors are different than the database vectors, it should be passed in the xq argument +b. A new dataset needs to be prepared (step 1) before passing it to the query vectors argument `–xq` + +`python run.py --command search --config config_ssnpp.yaml --xb ssnpp_1B --xq ` + + +6. We can always run the consistency-check for sanity checks! + +`python run.py --command consistency_check--config config_ssnpp.yaml --xb ssnpp_1B` + diff --git a/demos/offline_ivf/__init__.py b/demos/offline_ivf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/offline_ivf/config_ssnpp.yaml b/demos/offline_ivf/config_ssnpp.yaml new file mode 100644 index 0000000000..690f0de156 --- /dev/null +++ b/demos/offline_ivf/config_ssnpp.yaml @@ -0,0 +1,109 @@ +d: 256 +output: /checkpoint/marialomeli/offline_faiss/ssnpp +index: + prod: + - 'IVF8192,PQ128' + non-prod: + - 'IVF16384,PQ128' + - 'IVF32768,PQ128' +nprobe: + prod: + - 512 + non-prod: + - 256 + - 128 + - 1024 + - 2048 + - 4096 + - 8192 + +k: 50 +index_shard_size: 50000000 +query_batch_size: 50000000 +evaluation_sample: 10000 +training_sample: 1572864 +datasets: + ssnpp_1B: + root: /checkpoint/marialomeli/ssnpp_data + size: 1000000000 + files: + - dtype: uint8 + format: npy + name: ssnpp_0000000000.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000001.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000002.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000003.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000004.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000005.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000006.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000007.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000008.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000009.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000010.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000011.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000012.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000013.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000014.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000015.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000016.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000017.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000018.npy + size: 50000000 + - dtype: uint8 + format: npy + name: ssnpp_0000000019.npy + size: 50000000 diff --git a/demos/offline_ivf/create_sharded_ssnpp_files.py b/demos/offline_ivf/create_sharded_ssnpp_files.py new file mode 100644 index 0000000000..1dd22d2be8 --- /dev/null +++ b/demos/offline_ivf/create_sharded_ssnpp_files.py @@ -0,0 +1,63 @@ +# 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 numpy as np +import argparse +import os + + +def xbin_mmap(fname, dtype, maxn=-1): + """ + Code from + https://github.com/harsha-simhadri/big-ann-benchmarks/blob/main/benchmark/dataset_io.py#L94 + mmap the competition file format for a given type of items + """ + n, d = map(int, np.fromfile(fname, dtype="uint32", count=2)) + assert os.stat(fname).st_size == 8 + n * d * np.dtype(dtype).itemsize + if maxn > 0: + n = min(n, maxn) + return np.memmap(fname, dtype=dtype, mode="r", offset=8, shape=(n, d)) + + +def main(args: argparse.Namespace): + ssnpp_data = xbin_mmap(fname=args.filepath, dtype="uint8") + num_batches = ssnpp_data.shape[0] // args.data_batch + assert ( + ssnpp_data.shape[0] % args.data_batch == 0 + ), "num of embeddings per file should divide total num of embeddings" + for i in range(num_batches): + xb_batch = ssnpp_data[ + i * args.data_batch:(i + 1) * args.data_batch, : + ] + filename = args.output_dir + f"/ssnpp_{(i):010}.npy" + np.save(filename, xb_batch) + print(f"File {filename} is saved!") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--data_batch", + dest="data_batch", + type=int, + default=50000000, + help="Number of embeddings per file, should be a divisor of 1B", + ) + parser.add_argument( + "--filepath", + dest="filepath", + type=str, + default="/datasets01/big-ann-challenge-data/FB_ssnpp/FB_ssnpp_database.u8bin", + help="path of 1B ssnpp database vectors' original file", + ) + parser.add_argument( + "--filepath", + dest="output_dir", + type=str, + default="/checkpoint/marialomeli/ssnpp_data", + help="path to put sharded files", + ) + + args = parser.parse_args() + main(args) diff --git a/demos/offline_ivf/dataset.py b/demos/offline_ivf/dataset.py new file mode 100644 index 0000000000..f9e30009c5 --- /dev/null +++ b/demos/offline_ivf/dataset.py @@ -0,0 +1,173 @@ +# 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 os +import numpy as np +import faiss +from typing import List +import random +import logging +from functools import lru_cache + + +def create_dataset_from_oivf_config(cfg, ds_name): + normalise = cfg["normalise"] if "normalise" in cfg else False + return MultiFileVectorDataset( + cfg["datasets"][ds_name]["root"], + [ + FileDescriptor( + f["name"], f["format"], np.dtype(f["dtype"]), f["size"] + ) + for f in cfg["datasets"][ds_name]["files"] + ], + cfg["d"], + normalise, + cfg["datasets"][ds_name]["size"], + ) + + +@lru_cache(maxsize=100) +def _memmap_vecs( + file_name: str, format: str, dtype: np.dtype, size: int, d: int +) -> np.array: + """ + If the file is in raw format, the file size will + be divisible by the dimensionality and by the size + of the data type. + Otherwise,the file contains a header and we assume + it is of .npy type. It the returns the memmapped file. + """ + + assert os.path.exists(file_name), f"file does not exist {file_name}" + if format == "raw": + fl = os.path.getsize(file_name) + nb = fl // d // dtype.itemsize + assert nb == size, f"{nb} is different than config's {size}" + assert fl == d * dtype.itemsize * nb # no header + return np.memmap(file_name, shape=(nb, d), dtype=dtype, mode="r") + elif format == "npy": + vecs = np.load(file_name, mmap_mode="r") + assert vecs.shape[0] == size, f"size:{size},shape {vecs.shape[0]}" + assert vecs.shape[1] == d + assert vecs.dtype == dtype + return vecs + else: + ValueError("The file cannot be loaded in the current format.") + + +class FileDescriptor: + def __init__(self, name: str, format: str, dtype: np.dtype, size: int): + self.name = name + self.format = format + self.dtype = dtype + self.size = size + + +class MultiFileVectorDataset: + def __init__( + self, + root: str, + file_descriptors: List[FileDescriptor], + d: int, + normalize: bool, + size: int, + ): + assert os.path.exists(root) + self.root = root + self.file_descriptors = file_descriptors + self.d = d + self.normalize = normalize + self.size = size + self.file_offsets = [0] + t = 0 + for f in self.file_descriptors: + xb = _memmap_vecs( + f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d + ) + t += xb.shape[0] + self.file_offsets.append(t) + assert ( + t == self.size + ), "the sum of num of embeddings per file!=total num of embeddings" + + def iterate(self, start: int, batch_size: int, dt: np.dtype): + buffer = np.empty(shape=(batch_size, self.d), dtype=dt) + rem = 0 + for f in self.file_descriptors: + if start >= f.size: + start -= f.size + continue + logging.info(f"processing: {f.name}...") + xb = _memmap_vecs( + f"{self.root}/{f.name}", + f.format, + f.dtype, + f.size, + self.d, + ) + if start > 0: + xb = xb[start:] + start = 0 + req = min(batch_size - rem, xb.shape[0]) + buffer[rem:rem + req] = xb[:req] + rem += req + if rem == batch_size: + if self.normalize: + faiss.normalize_L2(buffer) + yield buffer.copy() + rem = 0 + for i in range(req, xb.shape[0], batch_size): + j = i + batch_size + if j <= xb.shape[0]: + tmp = xb[i:j].astype(dt) + if self.normalize: + faiss.normalize_L2(tmp) + yield tmp + else: + rem = xb.shape[0] - i + buffer[:rem] = xb[i:j] + if rem > 0: + tmp = buffer[:rem] + if self.normalize: + faiss.normalize_L2(tmp) + yield tmp + + def get(self, idx: List[int]): + n = len(idx) + fidx = np.searchsorted(self.file_offsets, idx, "right") + res = np.empty(shape=(len(idx), self.d), dtype=np.float32) + for r, id, fid in zip(range(n), idx, fidx): + assert fid > 0 and fid <= len(self.file_descriptors), f"{fid}" + f = self.file_descriptors[fid - 1] + # deferring normalization until after reading the vec + vecs = _memmap_vecs( + f"{self.root}/{f.name}", f.format, f.dtype, f.size, self.d + ) + i = id - self.file_offsets[fid - 1] + assert i >= 0 and i < vecs.shape[0] + res[r, :] = vecs[i] # TODO: find a faster way + if self.normalize: + faiss.normalize_L2(res) + return res + + def sample(self, n, idx_fn, vecs_fn): + if vecs_fn and os.path.exists(vecs_fn): + vecs = np.load(vecs_fn) + assert vecs.shape == (n, self.d) + return vecs + if idx_fn and os.path.exists(idx_fn): + idx = np.load(idx_fn) + assert idx.size == n + else: + idx = np.array(sorted(random.sample(range(self.size), n))) + if idx_fn: + np.save(idx_fn, idx) + vecs = self.get(idx) + if vecs_fn: + np.save(vecs_fn, vecs) + return vecs + + def get_first_n(self, n, dt): + assert n <= self.size + return next(self.iterate(0, n, dt)) diff --git a/demos/offline_ivf/generate_config.py b/demos/offline_ivf/generate_config.py new file mode 100644 index 0000000000..b5a12645ab --- /dev/null +++ b/demos/offline_ivf/generate_config.py @@ -0,0 +1,45 @@ +# 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 numpy as np +import os +import yaml + +# with ssnpp sharded data +root = "/checkpoint/marialomeli/ssnpp_data" +file_names = [f"ssnpp_{i:010}.npy" for i in range(20)] +d = 256 +dt = np.dtype(np.uint8) + + +def read_embeddings(fp): + fl = os.path.getsize(fp) + nb = fl // d // dt.itemsize + print(nb) + if fl == d * dt.itemsize * nb: # no header + return ("raw", np.memmap(fp, shape=(nb, d), dtype=dt, mode="r")) + else: # assume npy + vecs = np.load(fp, mmap_mode="r") + assert vecs.shape[1] == d + assert vecs.dtype == dt + return ("npy", vecs) + + +cfg = {} +files = [] +size = 0 +for fn in file_names: + fp = f"{root}/{fn}" + assert os.path.exists(fp), f"{fp} is missing" + ft, xb = read_embeddings(fp) + files.append( + {"name": fn, "size": xb.shape[0], "dtype": dt.name, "format": ft} + ) + size += xb.shape[0] + +cfg["size"] = size +cfg["root"] = root +cfg["d"] = d +cfg["files"] = files +print(yaml.dump(cfg)) diff --git a/demos/offline_ivf/offline_ivf.py b/demos/offline_ivf/offline_ivf.py new file mode 100644 index 0000000000..5c316178cb --- /dev/null +++ b/demos/offline_ivf/offline_ivf.py @@ -0,0 +1,938 @@ +# 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 faiss +import numpy as np +import os +from tqdm import tqdm, trange +import sys +import logging +from faiss.contrib.ondisk import merge_ondisk +from faiss.contrib.big_batch_search import big_batch_search +from faiss.contrib.exhaustive_search import knn_ground_truth +from faiss.contrib.evaluation import knn_intersection_measure +from utils import ( + get_intersection_cardinality_frequencies, + margin, + is_pretransform_index, +) +from dataset import create_dataset_from_oivf_config + +logging.basicConfig( + format=( + "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)-12s %(message)s" + ), + level=logging.INFO, + datefmt="%Y-%m-%d %H:%M:%S", + force=True, +) + +EMBEDDINGS_BATCH_SIZE: int = 100_000 +NUM_SUBSAMPLES: int = 100 +SMALL_DATA_SAMPLE: int = 10000 + + +class OfflineIVF: + def __init__(self, cfg, args, nprobe, index_factory_str): + self.input_d = cfg["d"] + self.dt = cfg["datasets"][args.xb]["files"][0]["dtype"] + assert self.input_d > 0 + output_dir = cfg["output"] + assert os.path.exists(output_dir) + self.index_factory = index_factory_str + assert self.index_factory is not None + self.index_factory_fn = self.index_factory.replace(",", "_") + self.index_template_file = ( + f"{output_dir}/{args.xb}/{self.index_factory_fn}.empty.faissindex" + ) + logging.info(f"index template: {self.index_template_file}") + + if not args.xq: + args.xq = args.xb + + self.by_residual = True + if args.no_residuals: + self.by_residual = False + + xb_output_dir = f"{output_dir}/{args.xb}" + if not os.path.exists(xb_output_dir): + os.makedirs(xb_output_dir) + xq_output_dir = f"{output_dir}/{args.xq}" + if not os.path.exists(xq_output_dir): + os.makedirs(xq_output_dir) + search_output_dir = f"{output_dir}/{args.xq}_in_{args.xb}" + if not os.path.exists(search_output_dir): + os.makedirs(search_output_dir) + self.knn_dir = f"{search_output_dir}/knn" + if not os.path.exists(self.knn_dir): + os.makedirs(self.knn_dir) + self.eval_dir = f"{search_output_dir}/eval" + if not os.path.exists(self.eval_dir): + os.makedirs(self.eval_dir) + self.index = {} # to keep a reference to opened indices, + self.ivls = {} # hstack inverted lists, + self.index_shards = {} # and index shards + self.index_shard_prefix = ( + f"{xb_output_dir}/{self.index_factory_fn}.shard_" + ) + self.xq_index_shard_prefix = ( + f"{xq_output_dir}/{self.index_factory_fn}.shard_" + ) + self.index_file = ( # TODO: added back temporarily for evaluate, handle name of non-sharded index file and remove. + f"{xb_output_dir}/{self.index_factory_fn}.faissindex" + ) + self.xq_index_file = ( + f"{xq_output_dir}/{self.index_factory_fn}.faissindex" + ) + self.training_sample = cfg["training_sample"] + self.evaluation_sample = cfg["evaluation_sample"] + self.xq_ds = create_dataset_from_oivf_config(cfg, args.xq) + self.xb_ds = create_dataset_from_oivf_config(cfg, args.xb) + file_descriptors = self.xq_ds.file_descriptors + self.file_sizes = [fd.size for fd in file_descriptors] + self.shard_size = cfg["index_shard_size"] # ~100GB + self.nshards = self.xb_ds.size // self.shard_size + if self.xb_ds.size % self.shard_size != 0: + self.nshards += 1 + self.xq_nshards = self.xq_ds.size // self.shard_size + if self.xq_ds.size % self.shard_size != 0: + self.xq_nshards += 1 + self.nprobe = nprobe + assert self.nprobe > 0, "Invalid nprobe parameter." + if "deduper" in cfg: + self.deduper = cfg["deduper"] + self.deduper_codec_fn = [ + f"{xb_output_dir}/deduper_codec_{codec.replace(',', '_')}" + for codec in self.deduper + ] + self.deduper_idx_fn = [ + f"{xb_output_dir}/deduper_idx_{codec.replace(',', '_')}" + for codec in self.deduper + ] + else: + self.deduper = None + self.k = cfg["k"] + assert self.k > 0, "Invalid number of neighbours parameter." + self.knn_output_file_suffix = ( + f"{self.index_factory_fn}_np{self.nprobe}.npy" + ) + + fp = 32 + if self.dt == "float16": + fp = 16 + + self.xq_bs = cfg["query_batch_size"] + if "metric" in cfg: + self.metric = eval(f'faiss.{cfg["metric"]}') + else: + self.metric = faiss.METRIC_L2 + + if "evaluate_by_margin" in cfg: + self.evaluate_by_margin = cfg["evaluate_by_margin"] + else: + self.evaluate_by_margin = False + + os.system("grep -m1 'model name' < /proc/cpuinfo") + os.system("grep -E 'MemTotal|MemFree' /proc/meminfo") + os.system("nvidia-smi") + os.system("nvcc --version") + + self.knn_queries_memory_limit = 4 * 1024 * 1024 * 1024 # 4 GB + self.knn_vectors_memory_limit = 8 * 1024 * 1024 * 1024 # 8 GB + + def input_stats(self): + """ + Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). + """ + xb_sample = self.xb_ds.get_first_n(self.training_sample, np.float32) + logging.info(f"input shape: {xb_sample.shape}") + logging.info("running MatrixStats on training sample...") + logging.info(faiss.MatrixStats(xb_sample).comments) + logging.info("done") + + def dedupe(self): + logging.info(self.deduper) + if self.deduper is None: + logging.info("No deduper configured") + return + codecs = [] + codesets = [] + idxs = [] + for factory, filename in zip(self.deduper, self.deduper_codec_fn): + if os.path.exists(filename): + logging.info(f"loading trained dedupe codec: {filename}") + codec = faiss.read_index(filename) + else: + logging.info(f"training dedupe codec: {factory}") + codec = faiss.index_factory(self.input_d, factory) + xb_sample = np.unique( + self.xb_ds.get_first_n(100_000, np.float32), axis=0 + ) + faiss.ParameterSpace().set_index_parameter(codec, "verbose", 1) + codec.train(xb_sample) + logging.info(f"writing trained dedupe codec: {filename}") + faiss.write_index(codec, filename) + codecs.append(codec) + codesets.append(faiss.CodeSet(codec.sa_code_size())) + idxs.append(np.empty((0,), dtype=np.uint32)) + bs = 1_000_000 + i = 0 + for buffer in tqdm(self.xb_ds.iterate(0, bs, np.float32)): + for j in range(len(codecs)): + codec, codeset, idx = codecs[j], codesets[j], idxs[j] + uniq = codeset.insert(codec.sa_encode(buffer)) + idxs[j] = np.append( + idx, + np.arange(i, i + buffer.shape[0], dtype=np.uint32)[uniq], + ) + i += buffer.shape[0] + for idx, filename in zip(idxs, self.deduper_idx_fn): + logging.info(f"writing {filename}, shape: {idx.shape}") + np.save(filename, idx) + logging.info("done") + + def train_index(self): + """ + Trains the index using a subsample of the first chunk of data in the database and saves it in the template file (with no vectors added). + """ + assert not os.path.exists(self.index_template_file), ( + "The train command has been ran, the index template file already" + " exists." + ) + xb_sample = np.unique( + self.xb_ds.get_first_n(self.training_sample, np.float32), axis=0 + ) + logging.info(f"input shape: {xb_sample.shape}") + index = faiss.index_factory( + self.input_d, self.index_factory, self.metric + ) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.by_residual = True + faiss.ParameterSpace().set_index_parameter(index, "verbose", 1) + logging.info("running training...") + index.train(xb_sample) + logging.info(f"writing trained index {self.index_template_file}...") + faiss.write_index(index, self.index_template_file) + logging.info("done") + + def _iterate_transformed(self, ds, start, batch_size, dt): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + if is_pretransform_index(index): + vt = index.chain.at(0) # fetch pretransform + for buffer in ds.iterate(start, batch_size, dt): + yield vt.apply(buffer) + else: + for buffer in ds.iterate(start, batch_size, dt): + yield buffer + + def index_shard_and_quantize(self): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + assert self.nprobe <= index_ivf.quantizer.ntotal, ( + f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" + f" to retrieve {self.nprobe} neighbours, check." + ) + + if is_pretransform_index(index): + d = index.chain.at(0).d_out + else: + d = self.input_d + for i in range(0, self.nshards): + sfn = f"{self.index_shard_prefix}{i}" + cqfn = f"{self.coarse_quantization_prefix}{i}" # fixme + if os.path.exists(sfn) or os.path.exists(cqfn): + logging.info(f"skipping shard: {i}") + continue + try: + with open(cqfn, "xb") as cqf: + index.reset() + start = i * self.shard_size + j = 0 + quantizer = faiss.index_cpu_to_all_gpus( + index_ivf.quantizer + ) + for xb_j in tqdm( + self._iterate_transformed( + self.xb_ds, + start, + EMBEDDINGS_BATCH_SIZE, + np.float32, + ), + file=sys.stdout, + ): + assert xb_j.shape[1] == d + _, I = quantizer.search(xb_j, self.nprobe) + assert np.amin(I) >= 0, f"{I}" + assert np.amax(I) < index_ivf.nlist + cqf.write(I) + self._index_add_core_wrapper( # fixme + index_ivf, + xb_j, + np.arange(start + j, start + j + xb_j.shape[0]), + I[:, 0], + ) + j += xb_j.shape[0] + assert j <= self.shard_size + if j == self.shard_size: + break + logging.info(f"writing {sfn}...") + faiss.write_index(index, sfn) + except FileExistsError: + logging.info(f"skipping shard: {i}") + continue + logging.info("done") + + def index_shard(self): + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + assert self.nprobe <= index_ivf.quantizer.ntotal, ( + f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" + f" to retrieve {self.nprobe} neighbours, check." + ) + cpu_quantizer = index_ivf.quantizer + gpu_quantizer = faiss.index_cpu_to_all_gpus(cpu_quantizer) + + for i in range(0, self.nshards): + sfn = f"{self.index_shard_prefix}{i}" + try: + index.reset() + index_ivf.quantizer = gpu_quantizer + with open(sfn, "xb"): + start = i * self.shard_size + jj = 0 + embeddings_batch_size = min( + EMBEDDINGS_BATCH_SIZE, self.shard_size + ) + assert ( + self.shard_size % embeddings_batch_size == 0 + or EMBEDDINGS_BATCH_SIZE % embeddings_batch_size == 0 + ), ( + f"the shard size {self.shard_size} and embeddings" + f" shard size {EMBEDDINGS_BATCH_SIZE} are not" + " divisible" + ) + + for xb_j in tqdm( + self._iterate_transformed( + self.xb_ds, + start, + embeddings_batch_size, + np.float32, + ), + file=sys.stdout, + ): + assert xb_j.shape[1] == index.d + index.add_with_ids( + xb_j, + np.arange(start + jj, start + jj + xb_j.shape[0]), + ) + jj += xb_j.shape[0] + logging.info(jj) + assert ( + jj <= self.shard_size + ), f"jj {jj} and shard_zide {self.shard_size}" + if jj == self.shard_size: + break + logging.info(f"writing {sfn}...") + index_ivf.quantizer = cpu_quantizer + faiss.write_index(index, sfn) + except FileExistsError: + logging.info(f"skipping shard: {i}") + continue + logging.info("done") + + def merge_index(self): + ivf_file = f"{self.index_file}.ivfdata" + + assert os.path.exists(self.index_template_file) + assert not os.path.exists( + ivf_file + ), f"file with embeddings data {ivf_file} not found, check." + assert not os.path.exists(self.index_file) + index = faiss.read_index(self.index_template_file) + block_fnames = [ + f"{self.index_shard_prefix}{i}" for i in range(self.nshards) + ] + for fn in block_fnames: + assert os.path.exists(fn) + logging.info(block_fnames) + logging.info("merging...") + merge_ondisk(index, block_fnames, ivf_file) + logging.info("writing index...") + faiss.write_index(index, self.index_file) + logging.info("done") + + def _cached_search( + self, + sample, + xq_ds, + xb_ds, + idx_file, + vecs_file, + I_file, + D_file, + index_file=None, + nprobe=None, + ): + if not os.path.exists(I_file): + assert not os.path.exists(I_file), f"file {I_file} does not exist " + assert not os.path.exists(D_file), f"file {D_file} does not exist " + xq = xq_ds.sample(sample, idx_file, vecs_file) + + if index_file: + D, I = self._index_nonsharded_search(index_file, xq, nprobe) + else: + logging.info("ground truth computations") + db_iterator = xb_ds.iterate(0, 100_000, np.float32) + D, I = knn_ground_truth( + xq, db_iterator, self.k, metric_type=self.metric + ) + assert np.amin(I) >= 0 + + np.save(I_file, I) + np.save(D_file, D) + else: + assert os.path.exists(idx_file), f"file {idx_file} does not exist " + assert os.path.exists( + vecs_file + ), f"file {vecs_file} does not exist " + assert os.path.exists(I_file), f"file {I_file} does not exist " + assert os.path.exists(D_file), f"file {D_file} does not exist " + I = np.load(I_file) + D = np.load(D_file) + assert I.shape == (sample, self.k), f"{I_file} shape mismatch" + assert D.shape == (sample, self.k), f"{D_file} shape mismatch" + return (D, I) + + def _index_search(self, index_shard_prefix, xq, nprobe): + assert nprobe is not None + logging.info( + f"open sharded index: {index_shard_prefix}, {self.nshards}" + ) + index = self._open_sharded_index(index_shard_prefix) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {nprobe}") + index_ivf.nprobe = nprobe + return index.search(xq, self.k) + + def _index_nonsharded_search(self, index_file, xq, nprobe): + assert nprobe is not None + logging.info(f"index {index_file}") + assert os.path.exists(index_file), f"file {index_file} does not exist " + index = faiss.read_index(index_file, faiss.IO_FLAG_ONDISK_SAME_DIR) + logging.info(f"index size {index.ntotal} ") + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {nprobe}") + index_ivf.nprobe = nprobe + return index.search(xq, self.k) + + def _refine_distances(self, xq_ds, idx, xb_ds, I): + xq = xq_ds.get(idx).repeat(self.k, axis=0) + xb = xb_ds.get(I.reshape(-1)) + if self.metric == faiss.METRIC_INNER_PRODUCT: + return (xq * xb).sum(axis=1).reshape(I.shape) + elif self.metric == faiss.METRIC_L2: + return ((xq - xb) ** 2).sum(axis=1).reshape(I.shape) + else: + raise ValueError(f"metric not supported {self.metric}") + + def evaluate(self): + self._evaluate( + self.index_factory_fn, + self.index_file, + self.xq_index_file, + self.nprobe, + ) + + def _evaluate(self, index_factory_fn, index_file, xq_index_file, nprobe): + idx_a_file = f"{self.eval_dir}/idx_a.npy" + idx_b_gt_file = f"{self.eval_dir}/idx_b_gt.npy" + idx_b_ann_file = ( + f"{self.eval_dir}/idx_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + vecs_a_file = f"{self.eval_dir}/vecs_a.npy" + vecs_b_gt_file = f"{self.eval_dir}/vecs_b_gt.npy" + vecs_b_ann_file = ( + f"{self.eval_dir}/vecs_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_a_gt_file = f"{self.eval_dir}/D_a_gt.npy" + D_a_ann_file = ( + f"{self.eval_dir}/D_a_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_a_ann_refined_file = f"{self.eval_dir}/D_a_ann_refined_{index_factory_fn}_np{nprobe}.npy" + D_b_gt_file = f"{self.eval_dir}/D_b_gt.npy" + D_b_ann_file = ( + f"{self.eval_dir}/D_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + D_b_ann_gt_file = ( + f"{self.eval_dir}/D_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" + ) + I_a_gt_file = f"{self.eval_dir}/I_a_gt.npy" + I_a_ann_file = ( + f"{self.eval_dir}/I_a_ann_{index_factory_fn}_np{nprobe}.npy" + ) + I_b_gt_file = f"{self.eval_dir}/I_b_gt.npy" + I_b_ann_file = ( + f"{self.eval_dir}/I_b_ann_{index_factory_fn}_np{nprobe}.npy" + ) + I_b_ann_gt_file = ( + f"{self.eval_dir}/I_b_ann_gt_{index_factory_fn}_np{nprobe}.npy" + ) + margin_gt_file = f"{self.eval_dir}/margin_gt.npy" + margin_refined_file = ( + f"{self.eval_dir}/margin_refined_{index_factory_fn}_np{nprobe}.npy" + ) + margin_ann_file = ( + f"{self.eval_dir}/margin_ann_{index_factory_fn}_np{nprobe}.npy" + ) + + logging.info("exact search forward") + # xq -> xb AKA a -> b + D_a_gt, I_a_gt = self._cached_search( + self.evaluation_sample, + self.xq_ds, + self.xb_ds, + idx_a_file, + vecs_a_file, + I_a_gt_file, + D_a_gt_file, + ) + idx_a = np.load(idx_a_file) + + logging.info("approximate search forward") + D_a_ann, I_a_ann = self._cached_search( + self.evaluation_sample, + self.xq_ds, + self.xb_ds, + idx_a_file, + vecs_a_file, + I_a_ann_file, + D_a_ann_file, + index_file, + nprobe, + ) + + logging.info( + "calculate refined distances on approximate search forward" + ) + if os.path.exists(D_a_ann_refined_file): + D_a_ann_refined = np.load(D_a_ann_refined_file) + assert D_a_ann.shape == D_a_ann_refined.shape + else: + D_a_ann_refined = self._refine_distances( + self.xq_ds, idx_a, self.xb_ds, I_a_ann + ) + np.save(D_a_ann_refined_file, D_a_ann_refined) + + if self.evaluate_by_margin: + k_extract = self.k + margin_threshold = 1.05 + logging.info( + "exact search backward from the k_extract NN results of" + " forward search" + ) + # xb -> xq AKA b -> a + D_a_b_gt = D_a_gt[:, :k_extract].ravel() + idx_b_gt = I_a_gt[:, :k_extract].ravel() + assert len(idx_b_gt) == self.evaluation_sample * k_extract + np.save(idx_b_gt_file, idx_b_gt) + # exact search + D_b_gt, _ = self._cached_search( + len(idx_b_gt), + self.xb_ds, + self.xq_ds, + idx_b_gt_file, + vecs_b_gt_file, + I_b_gt_file, + D_b_gt_file, + ) # xb and xq ^^^ are inverted + + logging.info("margin on exact search") + margin_gt = margin( + self.evaluation_sample, + idx_a, + idx_b_gt, + D_a_b_gt, + D_a_gt, + D_b_gt, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_gt_file, margin_gt) + + logging.info( + "exact search backward from the k_extract NN results of" + " approximate forward search" + ) + D_a_b_refined = D_a_ann_refined[:, :k_extract].ravel() + idx_b_ann = I_a_ann[:, :k_extract].ravel() + assert len(idx_b_ann) == self.evaluation_sample * k_extract + np.save(idx_b_ann_file, idx_b_ann) + # exact search + D_b_ann_gt, _ = self._cached_search( + len(idx_b_ann), + self.xb_ds, + self.xq_ds, + idx_b_ann_file, + vecs_b_ann_file, + I_b_ann_gt_file, + D_b_ann_gt_file, + ) # xb and xq ^^^ are inverted + + logging.info("refined margin on approximate search") + margin_refined = margin( + self.evaluation_sample, + idx_a, + idx_b_ann, + D_a_b_refined, + D_a_gt, # not D_a_ann_refined(!) + D_b_ann_gt, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_refined_file, margin_refined) + + D_b_ann, I_b_ann = self._cached_search( + len(idx_b_ann), + self.xb_ds, + self.xq_ds, + idx_b_ann_file, + vecs_b_ann_file, + I_b_ann_file, + D_b_ann_file, + xq_index_file, + nprobe, + ) + + D_a_b_ann = D_a_ann[:, :k_extract].ravel() + + logging.info("approximate search margin") + + margin_ann = margin( + self.evaluation_sample, + idx_a, + idx_b_ann, + D_a_b_ann, + D_a_ann, + D_b_ann, + self.k, + k_extract, + margin_threshold, + ) + np.save(margin_ann_file, margin_ann) + + logging.info("intersection") + logging.info(I_a_gt) + logging.info(I_a_ann) + + for i in range(1, self.k + 1): + logging.info( + f"{i}: {knn_intersection_measure(I_a_gt[:,:i], I_a_ann[:,:i])}" + ) + + logging.info(f"mean of gt distances: {D_a_gt.mean()}") + logging.info(f"mean of approx distances: {D_a_ann.mean()}") + logging.info(f"mean of refined distances: {D_a_ann_refined.mean()}") + + logging.info("intersection cardinality frequencies") + logging.info(get_intersection_cardinality_frequencies(I_a_ann, I_a_gt)) + + logging.info("done") + pass + + def _knn_function(self, xq, xb, k, metric, thread_id=None): + try: + return faiss.knn_gpu( + self.all_gpu_resources[thread_id], + xq, + xb, + k, + metric=metric, + device=thread_id, + vectorsMemoryLimit=self.knn_vectors_memory_limit, + queriesMemoryLimit=self.knn_queries_memory_limit, + ) + except Exception: + logging.info(f"knn_function failed: {xq.shape}, {xb.shape}") + raise + + def _coarse_quantize(self, index_ivf, xq, nprobe): + assert nprobe <= index_ivf.quantizer.ntotal + quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) + bs = 100_000 + nq = len(xq) + q_assign = np.empty((nq, nprobe), dtype="int32") + for i0 in trange(0, nq, bs): + i1 = min(nq, i0 + bs) + _, q_assign_i = quantizer.search(xq[i0:i1], nprobe) + q_assign[i0:i1] = q_assign_i + return q_assign + + def search(self): + logging.info(f"search: {self.knn_dir}") + slurm_job_id = os.environ.get("SLURM_JOB_ID") + + ngpu = faiss.get_num_gpus() + logging.info(f"number of gpus: {ngpu}") + self.all_gpu_resources = [ + faiss.StandardGpuResources() for _ in range(ngpu) + ] + self._knn_function( + np.zeros((10, 10), dtype=np.float16), + np.zeros((10, 10), dtype=np.float16), + self.k, + metric=self.metric, + thread_id=0, + ) + + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + logging.info(f"setting nprobe to {self.nprobe}") + index_ivf.nprobe = self.nprobe + # quantizer = faiss.index_cpu_to_all_gpus(index_ivf.quantizer) + for i in range(0, self.xq_ds.size, self.xq_bs): + Ifn = f"{self.knn_dir}/I{(i):010}_{self.knn_output_file_suffix}" + Dfn = f"{self.knn_dir}/D_approx{(i):010}_{self.knn_output_file_suffix}" + CPfn = f"{self.knn_dir}/CP{(i):010}_{self.knn_output_file_suffix}" + + if slurm_job_id: + worker_record = ( + self.knn_dir + + f"/record_{(i):010}_{self.knn_output_file_suffix}.txt" + ) + if not os.path.exists(worker_record): + logging.info( + f"creating record file {worker_record} and saving job" + f" id: {slurm_job_id}" + ) + with open(worker_record, "w") as h: + h.write(slurm_job_id) + else: + old_slurm_id = open(worker_record, "r").read() + logging.info( + f"old job slurm id {old_slurm_id} and current job id:" + f" {slurm_job_id}" + ) + if old_slurm_id == slurm_job_id: + if os.path.getsize(Ifn) == 0: + logging.info( + f"cleaning up zero length files {Ifn} and" + f" {Dfn}" + ) + os.remove(Ifn) + os.remove(Dfn) + + try: # TODO: modify shape for pretransform case + with open(Ifn, "xb") as f, open(Dfn, "xb") as g: + xq_i = np.empty( + shape=(self.xq_bs, self.input_d), dtype=np.float16 + ) + q_assign = np.empty( + (self.xq_bs, self.nprobe), dtype=np.int32 + ) + j = 0 + quantizer = faiss.index_cpu_to_all_gpus( + index_ivf.quantizer + ) + for xq_i_j in tqdm( + self._iterate_transformed( + self.xq_ds, i, min(100_000, self.xq_bs), np.float16 + ), + file=sys.stdout, + ): + xq_i[j:j + xq_i_j.shape[0]] = xq_i_j + ( + _, + q_assign[j:j + xq_i_j.shape[0]], + ) = quantizer.search(xq_i_j, self.nprobe) + j += xq_i_j.shape[0] + assert j <= xq_i.shape[0] + if j == xq_i.shape[0]: + break + xq_i = xq_i[:j] + q_assign = q_assign[:j] + + assert q_assign.shape == (xq_i.shape[0], index_ivf.nprobe) + del quantizer + logging.info(f"computing: {Ifn}") + logging.info(f"computing: {Dfn}") + prefetch_threads = faiss.get_num_gpus() + D_ann, I = big_batch_search( + index_ivf, + xq_i, + self.k, + verbose=10, + method="knn_function", + knn=self._knn_function, + threaded=faiss.get_num_gpus() * 8, + use_float16=True, + prefetch_threads=prefetch_threads, + computation_threads=faiss.get_num_gpus(), + q_assign=q_assign, + checkpoint=CPfn, + checkpoint_freq=7200, # in seconds + ) + assert ( + np.amin(I) >= 0 + ), f"{I}, there exists negative indices, check" + logging.info(f"saving: {Ifn}") + np.save(f, I) + logging.info(f"saving: {Dfn}") + np.save(g, D_ann) + + if os.path.exists(CPfn): + logging.info(f"removing: {CPfn}") + os.remove(CPfn) + + except FileExistsError: + logging.info(f"skipping {Ifn}, already exists") + logging.info(f"skipping {Dfn}, already exists") + continue + + def _open_index_shard(self, fn): + if fn in self.index_shards: + index_shard = self.index_shards[fn] + else: + logging.info(f"open index shard: {fn}") + index_shard = faiss.read_index( + fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY + ) + self.index_shards[fn] = index_shard + return index_shard + + def _open_sharded_index(self, index_shard_prefix=None): + if index_shard_prefix is None: + index_shard_prefix = self.index_shard_prefix + if index_shard_prefix in self.index: + return self.index[index_shard_prefix] + assert os.path.exists( + self.index_template_file + ), f"file {self.index_template_file} does not exist " + logging.info(f"open index template: {self.index_template_file}") + index = faiss.read_index(self.index_template_file) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + ilv = faiss.InvertedListsPtrVector() + for i in range(self.nshards): + fn = f"{index_shard_prefix}{i}" + assert os.path.exists(fn), f"file {fn} does not exist " + logging.info(fn) + index_shard = self._open_index_shard(fn) + il = faiss.downcast_index( + faiss.extract_index_ivf(index_shard) + ).invlists + ilv.push_back(il) + hsil = faiss.HStackInvertedLists(ilv.size(), ilv.data()) + index_ivf.replace_invlists(hsil, False) + self.ivls[index_shard_prefix] = hsil + self.index[index_shard_prefix] = index + return index + + def index_shard_stats(self): + for i in range(self.nshards): + fn = f"{self.index_shard_prefix}{i}" + assert os.path.exists(fn) + index = faiss.read_index( + fn, faiss.IO_FLAG_MMAP | faiss.IO_FLAG_READ_ONLY + ) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + il = index_ivf.invlists + il.print_stats() + + def index_stats(self): + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + il = index_ivf.invlists + list_sizes = [il.list_size(i) for i in range(il.nlist)] + logging.info(np.max(list_sizes)) + logging.info(np.mean(list_sizes)) + logging.info(np.argmax(list_sizes)) + logging.info("index_stats:") + il.print_stats() + + def consistency_check(self): + logging.info("consistency-check") + + logging.info("index template...") + + assert os.path.exists(self.index_template_file) + index = faiss.read_index(self.index_template_file) + + offset = 0 # 2**24 + assert self.shard_size > offset + SMALL_DATA_SAMPLE + + logging.info("index shards...") + for i in range(self.nshards): + r = i * self.shard_size + offset + xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) + fn = f"{self.index_shard_prefix}{i}" + assert os.path.exists(fn), f"There is no index shard file {fn}" + index = self._open_index_shard(fn) + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.nprobe = 1 + _, I = index.search(xb, 100) + for j in range(SMALL_DATA_SAMPLE): + assert np.where(I[j] == j + r)[0].size > 0, ( + f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" + f" {self.shard_size}" + ) + + logging.info("merged index...") + index = self._open_sharded_index() + index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) + index_ivf.nprobe = 1 + for i in range(self.nshards): + r = i * self.shard_size + offset + xb = next(self.xb_ds.iterate(r, SMALL_DATA_SAMPLE, np.float32)) + _, I = index.search(xb, 100) + for j in range(SMALL_DATA_SAMPLE): + assert np.where(I[j] == j + r)[0].size > 0, ( + f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" + f" {self.shard_size}" + ) + + logging.info("search results...") + index_ivf.nprobe = self.nprobe + for i in range(0, self.xq_ds.size, self.xq_bs): + Ifn = f"{self.knn_dir}/I{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" + assert os.path.exists(Ifn) + assert os.path.getsize(Ifn) > 0, f"The file {Ifn} is empty." + logging.info(Ifn) + I = np.load(Ifn, mmap_mode="r") + + assert I.shape[1] == self.k + assert I.shape[0] == min(self.xq_bs, self.xq_ds.size - i) + assert np.all(I[:, 1] >= 0) + + Dfn = f"{self.knn_dir}/D_approx{i:010}_{self.index_factory_fn}_np{self.nprobe}.npy" + assert os.path.exists(Dfn) + assert os.path.getsize(Dfn) > 0, f"The file {Dfn} is empty." + logging.info(Dfn) + D = np.load(Dfn, mmap_mode="r") + assert D.shape == I.shape + + xq = next(self.xq_ds.iterate(i, SMALL_DATA_SAMPLE, np.float32)) + D_online, I_online = index.search(xq, self.k) + assert ( + np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size + / (self.k * SMALL_DATA_SAMPLE) + > 0.95 + ), ( + "the ratio is" + f" {np.where(I[:SMALL_DATA_SAMPLE] == I_online)[0].size / (self.k * SMALL_DATA_SAMPLE)}" + ) + assert np.allclose( + D[:SMALL_DATA_SAMPLE].sum(axis=1), + D_online.sum(axis=1), + rtol=0.01, + ), ( + "the difference is" + f" {D[:SMALL_DATA_SAMPLE].sum(axis=1), D_online.sum(axis=1)}" + ) + + logging.info("done") diff --git a/demos/offline_ivf/run.py b/demos/offline_ivf/run.py new file mode 100644 index 0000000000..dfa831d6f0 --- /dev/null +++ b/demos/offline_ivf/run.py @@ -0,0 +1,218 @@ +# 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 +from utils import ( + load_config, + add_group_args, +) +from offline_ivf import OfflineIVF +import faiss +from typing import List, Callable, Dict +import submitit + + +def join_lists_in_dict(poss: List[str]) -> List[str]: + """ + Joins two lists of prod and non-prod values, checking if the prod value is already included. + If there is no non-prod list, it returns the prod list. + """ + if "non-prod" in poss.keys(): + all_poss = poss["non-prod"] + if poss["prod"][-1] not in poss["non-prod"]: + all_poss += poss["prod"] + return all_poss + else: + return poss["prod"] + + +def main( + args: argparse.Namespace, + cfg: Dict[str, str], + nprobe: int, + index_factory_str: str, +) -> None: + oivf = OfflineIVF(cfg, args, nprobe, index_factory_str) + eval(f"oivf.{args.command}()") + + +def process_options_and_run_jobs(args: argparse.Namespace) -> None: + """ + If "--cluster_run", it launches an array of jobs to the cluster using the submitit library for all the index strings. In + the case of evaluate, it launches a job for each index string and nprobe pair. Otherwise, it launches a single job + that is ran locally with the prod values for index string and nprobe. + """ + + cfg = load_config(args.config) + index_strings = cfg["index"] + nprobes = cfg["nprobe"] + if args.command == "evaluate": + if args.cluster_run: + all_nprobes = join_lists_in_dict(nprobes) + all_index_strings = join_lists_in_dict(index_strings) + for index_factory_str in all_index_strings: + for nprobe in all_nprobes: + launch_job(main, args, cfg, nprobe, index_factory_str) + else: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] + ) + else: + if args.cluster_run: + all_index_strings = join_lists_in_dict(index_strings) + for index_factory_str in all_index_strings: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_factory_str + ) + else: + launch_job( + main, args, cfg, nprobes["prod"][-1], index_strings["prod"][-1] + ) + + +def launch_job( + func: Callable, + args: argparse.Namespace, + cfg: Dict[str, str], + n_probe: int, + index_str: str, +) -> None: + """ + Launches an array of slurm jobs to the cluster using the submitit library. + """ + + if args.cluster_run: + assert args.num_nodes >= 1 + executor = submitit.AutoExecutor(folder=args.logs_dir) + + executor.update_parameters( + nodes=args.num_nodes, + gpus_per_node=args.gpus_per_node, + cpus_per_task=args.cpus_per_task, + tasks_per_node=args.tasks_per_node, + name=args.job_name, + slurm_partition=args.partition, + slurm_time=70 * 60, + ) + if args.slurm_constraint: + executor.update_parameters(slurm_constraint=args.slurm_constrain) + + job = executor.submit(func, args, cfg, n_probe, index_str) + print(f"Job id: {job.job_id}") + else: + func(args, cfg, n_probe, index_str) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + group = parser.add_argument_group("general") + + add_group_args(group, "--command", required=True, help="command to run") + add_group_args( + group, + "--config", + required=True, + help="config yaml with the dataset specs", + ) + add_group_args( + group, "--nt", type=int, default=96, help="nb search threads" + ) + add_group_args( + group, + "--no_residuals", + action="store_false", + help="set index.by_residual to False during train index.", + ) + + group = parser.add_argument_group("slurm_job") + + add_group_args( + group, + "--cluster_run", + action="store_true", + help=" if True, runs in cluster", + ) + add_group_args( + group, + "--job_name", + type=str, + default="oivf", + help="cluster job name", + ) + add_group_args( + group, + "--num_nodes", + type=str, + default=1, + help="num of nodes per job", + ) + add_group_args( + group, + "--tasks_per_node", + type=int, + default=1, + help="tasks per job", + ) + + add_group_args( + group, + "--gpus_per_node", + type=int, + default=8, + help="cluster job name", + ) + add_group_args( + group, + "--cpus_per_task", + type=int, + default=80, + help="cluster job name", + ) + + add_group_args( + group, + "--logs_dir", + type=str, + default="/checkpoint/marialomeli/offline_faiss/logs", + help="cluster job name", + ) + + add_group_args( + group, + "--slurm_constraint", + type=str, + default=None, + help="can be volta32gb for the fair cluster", + ) + + add_group_args( + group, + "--partition", + type=str, + default="learnlab", + help="specify which partition to use if ran on cluster with job arrays", + choices=[ + "learnfair", + "devlab", + "scavenge", + "learnlab", + "nllb", + "seamless", + "seamless_medium", + "learnaccel", + "onellm_low", + "learn", + "scavenge", + ], + ) + + group = parser.add_argument_group("dataset") + + add_group_args(group, "--xb", required=True, help="database vectors") + add_group_args(group, "--xq", help="query vectors") + + args = parser.parse_args() + print("args:", args) + faiss.omp_set_num_threads(args.nt) + process_options_and_run_jobs(args=args) diff --git a/demos/offline_ivf/tests/test_iterate_input.py b/demos/offline_ivf/tests/test_iterate_input.py new file mode 100644 index 0000000000..3f59071102 --- /dev/null +++ b/demos/offline_ivf/tests/test_iterate_input.py @@ -0,0 +1,132 @@ +# 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 numpy as np +import unittest +from typing import List +from utils import load_config +from tests.testing_utils import TestDataCreator +import tempfile +from dataset import create_dataset_from_oivf_config + +DIMENSION: int = 768 +SMALL_FILE_SIZES: List[int] = [100, 210, 450] +LARGE_FILE_SIZES: List[int] = [1253, 3459, 890] +TEST_BATCH_SIZE: int = 500 +SMALL_SAMPLE_SIZE: int = 1000 +NUM_FILES: int = 3 + + +class TestUtilsMethods(unittest.TestCase): + """ + Unit tests for iterate and decreasing_matrix methods. + """ + + def test_iterate_input_file_smaller_than_batch(self): + """ + Tests when batch size is larger than the file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_sizes=SMALL_FILE_SIZES, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + db_iterator = create_dataset_from_oivf_config( + cfg, args.xb + ).iterate(0, TEST_BATCH_SIZE, np.float32) + + for i in range(len(SMALL_FILE_SIZES) - 1): + vecs = next(db_iterator) + if i != 1: + self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) + else: + self.assertEqual( + vecs.shape[0], sum(SMALL_FILE_SIZES) - TEST_BATCH_SIZE + ) + + def test_iterate_input_file_larger_than_batch(self): + """ + Tests when batch size is smaller than the file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_sizes=LARGE_FILE_SIZES, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + db_iterator = create_dataset_from_oivf_config( + cfg, args.xb + ).iterate(0, TEST_BATCH_SIZE, np.float32) + + for i in range(len(LARGE_FILE_SIZES) - 1): + vecs = next(db_iterator) + if i != 9: + self.assertEqual(vecs.shape[0], TEST_BATCH_SIZE) + else: + self.assertEqual( + vecs.shape[0], + sum(LARGE_FILE_SIZES) - TEST_BATCH_SIZE * 9, + ) + + def test_get_vs_iterate(self) -> None: + """ + Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_size=SMALL_SAMPLE_SIZE, + num_files=NUM_FILES, + normalise=True, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + ds = create_dataset_from_oivf_config(cfg, args.xb) + vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) + self.assertEqual( + vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES + ) + vecs_by_get = ds.get(list(range(vecs_by_iterator.shape[0]))) + self.assertTrue(np.all(vecs_by_iterator == vecs_by_get)) + + def test_iterate_back(self) -> None: + """ + Loads vectors with iterator and get, and checks that they match, non-aligned by file size case. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=DIMENSION, + data_type=np.float16, + file_size=SMALL_SAMPLE_SIZE, + num_files=NUM_FILES, + normalise=True, + ) + data_creator.create_test_data() + args = data_creator.setup_cli() + cfg = load_config(args.config) + ds = create_dataset_from_oivf_config(cfg, args.xb) + vecs_by_iterator = np.vstack(list(ds.iterate(0, 317, np.float32))) + self.assertEqual( + vecs_by_iterator.shape[0], SMALL_SAMPLE_SIZE * NUM_FILES + ) + vecs_chunk = np.vstack( + [ + next(ds.iterate(i, 543, np.float32)) + for i in range(0, SMALL_SAMPLE_SIZE * NUM_FILES, 543) + ] + ) + self.assertTrue(np.all(vecs_by_iterator == vecs_chunk)) diff --git a/demos/offline_ivf/tests/test_offline_ivf.py b/demos/offline_ivf/tests/test_offline_ivf.py new file mode 100644 index 0000000000..557a0b37dd --- /dev/null +++ b/demos/offline_ivf/tests/test_offline_ivf.py @@ -0,0 +1,288 @@ +# 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 numpy as np +import unittest +from utils import load_config +import pathlib as pl +import tempfile +from typing import List +from tests.testing_utils import TestDataCreator +from run import process_options_and_run_jobs + +KNN_RESULTS_FILE: str = ( + "/my_test_data_in_my_test_data/knn/I0000000000_IVF256_PQ4_np2.npy" +) + +A_INDEX_FILES: List[str] = [ + "I_a_gt.npy", + "D_a_gt.npy", + "vecs_a.npy", + "D_a_ann_IVF256_PQ4_np2.npy", + "I_a_ann_IVF256_PQ4_np2.npy", + "D_a_ann_refined_IVF256_PQ4_np2.npy", +] + +A_INDEX_OPQ_FILES: List[str] = [ + "I_a_gt.npy", + "D_a_gt.npy", + "vecs_a.npy", + "D_a_ann_OPQ4_IVF256_PQ4_np200.npy", + "I_a_ann_OPQ4_IVF256_PQ4_np200.npy", + "D_a_ann_refined_OPQ4_IVF256_PQ4_np200.npy", +] + + +class TestOIVF(unittest.TestCase): + """ + Unit tests for OIVF. Some of these unit tests first copy the required test data objects and puts them in the tempdir created by the context manager. + """ + + def assert_file_exists(self, filepath: str) -> None: + path = pl.Path(filepath) + self.assertEqual((str(path), path.is_file()), (str(path), True)) + + def test_consistency_check(self) -> None: + """ + Test the OIVF consistency check step, that it throws if no other steps have been ran. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("consistency_check") + self.assertRaises( + AssertionError, process_options_and_run_jobs, test_args + ) + + def test_train_index(self) -> None: + """ + Test the OIVF train index step, that it correctly produces the empty.faissindex template file. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + empty_index = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + ".empty.faissindex" + ) + self.assert_file_exists(empty_index) + + def test_index_shard_equal_file_sizes(self) -> None: + """ + Test the case where the shard size is a divisor of the database size and it is equal to the first file size. + """ + + with tempfile.TemporaryDirectory() as tmpdirname: + index_shard_size = 10000 + num_files = 3 + file_size = 10000 + xb_ds_size = num_files * file_size + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=num_files, + file_size=file_size, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=index_shard_size, + query_batch_size=1000, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + num_shards = xb_ds_size // index_shard_size + if xb_ds_size % index_shard_size != 0: + num_shards += 1 + print(f"number of shards:{num_shards}") + for i in range(num_shards): + index_shard_file = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + f".shard_{i}" + ) + self.assert_file_exists(index_shard_file) + + def test_index_shard_unequal_file_sizes(self) -> None: + """ + Test the case where the shard size is not a divisor of the database size and is greater than the first file size. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + file_sizes = [20000, 15001, 13990] + xb_ds_size = sum(file_sizes) + index_shard_size = 30000 + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float16, + index_factory=["IVF256,PQ4"], + training_sample=9984, + file_sizes=file_sizes, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=index_shard_size, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + num_shards = xb_ds_size // index_shard_size + if xb_ds_size % index_shard_size != 0: + num_shards += 1 + print(f"number of shards:{num_shards}") + for i in range(num_shards): + index_shard_file = ( + cfg["output"] + + "/my_test_data/" + + cfg["index"]["prod"][-1].replace(",", "_") + + f".shard_{i}" + ) + self.assert_file_exists(index_shard_file) + + def test_search(self) -> None: + """ + Test search step using test data objects to bypass dependencies on previous steps. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + num_files = 3 + file_size = 10000 + query_batch_size = 10000 + total_batches = num_files * file_size // query_batch_size + if num_files * file_size % query_batch_size != 0: + total_batches += 1 + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=query_batch_size, + evaluation_sample=100, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("search") + cfg = load_config(test_args.config) + process_options_and_run_jobs(test_args) + # TODO: add check that there are number of batches total of files + knn_file = cfg["output"] + KNN_RESULTS_FILE + self.assert_file_exists(knn_file) + + def test_evaluate_without_margin(self) -> None: + """ + Test evaluate step using test data objects, no margin evaluation, single index. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=2, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=10000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("merge_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("evaluate") + process_options_and_run_jobs(test_args) + common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" + for filename in A_INDEX_FILES: + file_to_check = common_path + "/" + filename + self.assert_file_exists(file_to_check) + + def test_evaluate_without_margin_OPQ(self) -> None: + """ + Test evaluate step using test data objects, no margin evaluation, single index. + """ + with tempfile.TemporaryDirectory() as tmpdirname: + data_creator = TestDataCreator( + tempdir=tmpdirname, + dimension=8, + data_type=np.float32, + index_factory=["OPQ4,IVF256,PQ4"], + training_sample=9984, + num_files=3, + file_size=10000, + nprobe=200, + k=2, + metric="METRIC_L2", + index_shard_size=10000, + query_batch_size=10000, + evaluation_sample=100, + with_queries_ds=True, + ) + data_creator.create_test_data() + test_args = data_creator.setup_cli("train_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("index_shard") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("merge_index") + process_options_and_run_jobs(test_args) + test_args = data_creator.setup_cli("evaluate") + process_options_and_run_jobs(test_args) + common_path = tmpdirname + "/my_queries_data_in_my_test_data/eval/" + for filename in A_INDEX_OPQ_FILES: + file_to_check = common_path + filename + self.assert_file_exists(file_to_check) diff --git a/demos/offline_ivf/tests/testing_utils.py b/demos/offline_ivf/tests/testing_utils.py new file mode 100644 index 0000000000..34751f278a --- /dev/null +++ b/demos/offline_ivf/tests/testing_utils.py @@ -0,0 +1,180 @@ +# 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 yaml +import numpy as np +from typing import Dict, List, Optional + +OIVF_TEST_ARGS: List[str] = [ + "--config", + "--xb", + "--xq", + "--command", + "--cluster_run", + "--no_residuals", +] + + +def get_test_parser(args) -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + for arg in args: + parser.add_argument(arg) + return parser + + +class TestDataCreator: + def __init__( + self, + tempdir: str, + dimension: int, + data_type: np.dtype, + index_factory: Optional[List] = ["OPQ4,IVF256,PQ4"], + training_sample: Optional[int] = 9984, + index_shard_size: Optional[int] = 1000, + query_batch_size: Optional[int] = 1000, + evaluation_sample: Optional[int] = 100, + num_files: Optional[int] = None, + file_size: Optional[int] = None, + file_sizes: Optional[List] = None, + nprobe: Optional[int] = 64, + k: Optional[int] = 10, + metric: Optional[str] = "METRIC_L2", + normalise: Optional[bool] = False, + with_queries_ds: Optional[bool] = False, + evaluate_by_margin: Optional[bool] = False, + ) -> None: + self.tempdir = tempdir + self.dimension = dimension + self.data_type = np.dtype(data_type).name + self.index_factory = {"prod": index_factory} + if file_size and num_files: + self.file_sizes = [file_size for _ in range(num_files)] + elif file_sizes: + self.file_sizes = file_sizes + else: + raise ValueError("no file sizes provided") + self.num_files = len(self.file_sizes) + self.training_sample = training_sample + self.index_shard_size = index_shard_size + self.query_batch_size = query_batch_size + self.evaluation_sample = evaluation_sample + self.nprobe = {"prod": [nprobe]} + self.k = k + self.metric = metric + self.normalise = normalise + self.config_file = self.tempdir + "/config_test.yaml" + self.ds_name = "my_test_data" + self.qs_name = "my_queries_data" + self.evaluate_by_margin = evaluate_by_margin + self.with_queries_ds = with_queries_ds + + def create_test_data(self) -> None: + datafiles = self._create_data_files() + files_info = [] + + for i, file in enumerate(datafiles): + files_info.append( + { + "dtype": self.data_type, + "format": "npy", + "name": file, + "size": self.file_sizes[i], + } + ) + + config_for_yaml = { + "d": self.dimension, + "output": self.tempdir, + "index": self.index_factory, + "nprobe": self.nprobe, + "k": self.k, + "normalise": self.normalise, + "metric": self.metric, + "training_sample": self.training_sample, + "evaluation_sample": self.evaluation_sample, + "index_shard_size": self.index_shard_size, + "query_batch_size": self.query_batch_size, + "datasets": { + self.ds_name: { + "root": self.tempdir, + "size": sum(self.file_sizes), + "files": files_info, + } + }, + } + if self.evaluate_by_margin: + config_for_yaml["evaluate_by_margin"] = self.evaluate_by_margin + q_datafiles = self._create_data_files("my_q_data") + q_files_info = [] + + for i, file in enumerate(q_datafiles): + q_files_info.append( + { + "dtype": self.data_type, + "format": "npy", + "name": file, + "size": self.file_sizes[i], + } + ) + if self.with_queries_ds: + config_for_yaml["datasets"][self.qs_name] = { + "root": self.tempdir, + "size": sum(self.file_sizes), + "files": q_files_info, + } + + self._create_config_yaml(config_for_yaml) + + def setup_cli(self, command="consistency_check") -> argparse.Namespace: + parser = get_test_parser(OIVF_TEST_ARGS) + + if self.with_queries_ds: + return parser.parse_args( + [ + "--xb", + self.ds_name, + "--config", + self.config_file, + "--command", + command, + "--xq", + self.qs_name, + ] + ) + return parser.parse_args( + [ + "--xb", + self.ds_name, + "--config", + self.config_file, + "--command", + command, + ] + ) + + def _create_data_files(self, name_of_file="my_data") -> List[str]: + """ + Creates a dataset "my_test_data" with number of files (num_files), using padding in the files + name. If self.with_queries is True, it adds an extra dataset "my_queries_data" with the same number of files + as the "my_test_data". The default name for embeddings files is "my_data" + .npy. + """ + filenames = [] + for i, file_size in enumerate(self.file_sizes): + # np.random.seed(i) + db_vectors = np.random.random((file_size, self.dimension)).astype( + self.data_type + ) + filename = name_of_file + f"{i:02}" + ".npy" + filenames.append(filename) + np.save(self.tempdir + "/" + filename, db_vectors) + return filenames + + def _create_config_yaml(self, dict_file: Dict[str, str]) -> None: + """ + Creates a yaml file in dir (can be a temporary dir for tests). + """ + filename = self.tempdir + "/config_test.yaml" + with open(filename, "w") as file: + yaml.dump(dict_file, file, default_flow_style=False) diff --git a/demos/offline_ivf/utils.py b/demos/offline_ivf/utils.py new file mode 100644 index 0000000000..378af00c30 --- /dev/null +++ b/demos/offline_ivf/utils.py @@ -0,0 +1,94 @@ +# 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 numpy as np +import os +from typing import Dict +import yaml +import faiss +from faiss.contrib.datasets import SyntheticDataset + + +def load_config(config): + assert os.path.exists(config) + with open(config, "r") as f: + return yaml.safe_load(f) + + +def faiss_sanity_check(): + ds = SyntheticDataset(256, 0, 100, 100) + xq = ds.get_queries() + xb = ds.get_database() + index_cpu = faiss.IndexFlat(ds.d) + index_gpu = faiss.index_cpu_to_all_gpus(index_cpu) + index_cpu.add(xb) + index_gpu.add(xb) + D_cpu, I_cpu = index_cpu.search(xq, 10) + D_gpu, I_gpu = index_gpu.search(xq, 10) + assert np.all(I_cpu == I_gpu), "faiss sanity check failed" + assert np.all(np.isclose(D_cpu, D_gpu)), "faiss sanity check failed" + + +def margin(sample, idx_a, idx_b, D_a_b, D_a, D_b, k, k_extract, threshold): + """ + two datasets: xa, xb; n = number of pairs + idx_a - (np,) - query vector ids in xa + idx_b - (np,) - query vector ids in xb + D_a_b - (np,) - pairwise distances between xa[idx_a] and xb[idx_b] + D_a - (np, k) - distances between vectors xa[idx_a] and corresponding nearest neighbours in xb + D_b - (np, k) - distances between vectors xb[idx_b] and corresponding nearest neighbours in xa + k - k nearest neighbours used for margin + k_extract - number of nearest neighbours of each query in xb we consider for margin calculation and filtering + threshold - margin threshold + """ + + n = sample + nk = n * k_extract + assert idx_a.shape == (n,) + idx_a_k = idx_a.repeat(k_extract) + assert idx_a_k.shape == (nk,) + assert idx_b.shape == (nk,) + assert D_a_b.shape == (nk,) + assert D_a.shape == (n, k) + assert D_b.shape == (nk, k) + mean_a = np.mean(D_a, axis=1) + assert mean_a.shape == (n,) + mean_a_k = mean_a.repeat(k_extract) + assert mean_a_k.shape == (nk,) + mean_b = np.mean(D_b, axis=1) + assert mean_b.shape == (nk,) + margin = 2 * D_a_b / (mean_a_k + mean_b) + above_threshold = margin > threshold + print(np.count_nonzero(above_threshold)) + print(idx_a_k[above_threshold]) + print(idx_b[above_threshold]) + print(margin[above_threshold]) + return margin + + +def add_group_args(group, *args, **kwargs): + return group.add_argument(*args, **kwargs) + + +def get_intersection_cardinality_frequencies( + I: np.ndarray, I_gt: np.ndarray +) -> Dict[int, int]: + """ + Computes the frequencies for the cardinalities of the intersection of neighbour indices. + """ + nq = I.shape[0] + res = [] + for ell in range(nq): + res.append(len(np.intersect1d(I[ell, :], I_gt[ell, :]))) + values, counts = np.unique(res, return_counts=True) + return dict(zip(values, counts)) + + +def is_pretransform_index(index): + if index.__class__ == faiss.IndexPreTransform: + assert hasattr(index, "chain") + return True + else: + assert not hasattr(index, "chain") + return False From 7dd06dd188643523d1a0faab511ee8fc0c5b0e3b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 16 Jan 2024 07:18:20 -0800 Subject: [PATCH 028/206] Fix shadowed variable in faiss/impl/NNDescent.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582837 fbshipit-source-id: 275d20f940102030989f9bcfb4884891457b149c --- faiss/impl/NNDescent.cpp | 42 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/faiss/impl/NNDescent.cpp b/faiss/impl/NNDescent.cpp index 8878349ff6..b609aba390 100644 --- a/faiss/impl/NNDescent.cpp +++ b/faiss/impl/NNDescent.cpp @@ -195,8 +195,9 @@ void NNDescent::update() { int l = 0; while ((l < maxl) && (c < S)) { - if (nn.pool[l].flag) + if (nn.pool[l].flag) { ++c; + } ++l; } nn.M = l; @@ -305,8 +306,9 @@ void NNDescent::generate_eval_set( for (int i = 0; i < c.size(); i++) { std::vector tmp; for (int j = 0; j < N; j++) { - if (c[i] == j) + if (c[i] == j) { continue; // skip itself + } float dist = qdis.symmetric_dis(c[i], j); tmp.push_back(Neighbor(j, dist, true)); } @@ -360,8 +362,9 @@ void NNDescent::init_graph(DistanceComputer& qdis) { for (int j = 0; j < S; j++) { int id = tmp[j]; - if (id == i) + if (id == i) { continue; + } float dist = qdis.symmetric_dis(i, id); graph[i].pool.push_back(Neighbor(id, dist, true)); @@ -418,30 +421,30 @@ void NNDescent::search( float* dists, VisitedTable& vt) const { FAISS_THROW_IF_NOT_MSG(has_built, "The index is not build yet."); - int L = std::max(search_L, topk); + int L_2 = std::max(search_L, topk); // candidate pool, the K best items is the result. - std::vector retset(L + 1); + std::vector retset(L_2 + 1); - // Randomly choose L points to initialize the candidate pool - std::vector init_ids(L); + // Randomly choose L_2 points to initialize the candidate pool + std::vector init_ids(L_2); std::mt19937 rng(random_seed); - gen_random(rng, init_ids.data(), L, ntotal); - for (int i = 0; i < L; i++) { + gen_random(rng, init_ids.data(), L_2, ntotal); + for (int i = 0; i < L_2; i++) { int id = init_ids[i]; float dist = qdis(id); retset[i] = Neighbor(id, dist, true); } // Maintain the candidate pool in ascending order - std::sort(retset.begin(), retset.begin() + L); + std::sort(retset.begin(), retset.begin() + L_2); int k = 0; - // Stop until the smallest position updated is >= L - while (k < L) { - int nk = L; + // Stop until the smallest position updated is >= L_2 + while (k < L_2) { + int nk = L_2; if (retset[k].flag) { retset[k].flag = false; @@ -449,25 +452,28 @@ void NNDescent::search( for (int m = 0; m < K; ++m) { int id = final_graph[n * K + m]; - if (vt.get(id)) + if (vt.get(id)) { continue; + } vt.set(id); float dist = qdis(id); - if (dist >= retset[L - 1].distance) + if (dist >= retset[L_2 - 1].distance) { continue; + } Neighbor nn(id, dist, true); - int r = insert_into_pool(retset.data(), L, nn); + int r = insert_into_pool(retset.data(), L_2, nn); if (r < nk) nk = r; } } - if (nk <= k) + if (nk <= k) { k = nk; - else + } else { ++k; + } } for (size_t i = 0; i < topk; i++) { indices[i] = retset[i].id; From 9a63a3c28da16e7559356c1ee7dde0f1e7cd146d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 16 Jan 2024 07:45:48 -0800 Subject: [PATCH 029/206] Fix shadowed variable in faiss/IndexFastScan.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: meyering Differential Revision: D52582914 fbshipit-source-id: edb3983635de4343c4a0b20096e81852cfa058c6 --- faiss/IndexFastScan.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/faiss/IndexFastScan.cpp b/faiss/IndexFastScan.cpp index ca02af4168..2dfb2f55fd 100644 --- a/faiss/IndexFastScan.cpp +++ b/faiss/IndexFastScan.cpp @@ -37,22 +37,22 @@ inline size_t roundup(size_t a, size_t b) { void IndexFastScan::init_fastscan( int d, - size_t M, - size_t nbits, + size_t M_2, + size_t nbits_2, MetricType metric, int bbs) { - FAISS_THROW_IF_NOT(nbits == 4); + FAISS_THROW_IF_NOT(nbits_2 == 4); FAISS_THROW_IF_NOT(bbs % 32 == 0); this->d = d; - this->M = M; - this->nbits = nbits; + this->M = M_2; + this->nbits = nbits_2; this->metric_type = metric; this->bbs = bbs; - ksub = (1 << nbits); + ksub = (1 << nbits_2); - code_size = (M * nbits + 7) / 8; + code_size = (M_2 * nbits_2 + 7) / 8; ntotal = ntotal2 = 0; - M2 = roundup(M, 2); + M2 = roundup(M_2, 2); is_trained = false; } From 739ce139e9f4812020e9de4db1ddc2f3ff048039 Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Wed, 17 Jan 2024 01:47:46 -0800 Subject: [PATCH 030/206] doc update to mention the paper Summary: reference the new Faiss paper in the docs. Also added Gergely as a co-author of Faiss. Some minor updates. Reviewed By: mlomeli1 Differential Revision: D52829321 fbshipit-source-id: 0f1845beace6cd88f809ba50b87a8d446475d30b --- CONTRIBUTING.md | 2 +- INSTALL.md | 4 ++-- README.md | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5ef204b946..10fc8152f6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ outlined on that page and do not file a public issue. ## Coding Style -* 4 or 2 spaces for indentation in C++ (no tabs) +* 4 spaces for indentation in C++ (no tabs) * 80 character line length (both for C++ and Python) * C++ language level: C++17 diff --git a/INSTALL.md b/INSTALL.md index dd04511bd2..ee08d8d2cf 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,6 @@ # Installing Faiss via conda -The recommended way to install Faiss is through [conda](https://docs.conda.io). +The supported way to install Faiss is through [conda](https://docs.conda.io). Stable releases are pushed regularly to the pytorch conda channel, as well as pre-release nightly builds. @@ -77,7 +77,7 @@ found to run on other platforms as well, see The basic requirements are: - a C++17 compiler (with support for OpenMP support version 2 or higher), -- a BLAS implementation (we strongly recommend using Intel MKL for best +- a BLAS implementation (on Intel machines we strongly recommend using Intel MKL for best performance). The optional requirements are: diff --git a/README.md b/README.md index 0db380b807..bd1cf33a68 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,22 @@ The main authors of Faiss are: - [Lucas Hosseini](https://github.com/beauby) implemented the binary indexes and the build system - [Chengqi Deng](https://github.com/KinglittleQ) implemented NSG, NNdescent and much of the additive quantization code. - [Alexandr Guzhva](https://github.com/alexanderguzhva) many optimizations: SIMD, memory allocation and layout, fast decoding kernels for vector codecs, etc. +- [Gergely Szilvasy](https://github.com/algoriddle) build system, benchmarking framework. ## Reference -Reference to cite when you use Faiss in a research paper: - +References to cite when you use Faiss in a research paper: +``` +@article{douze2024faiss, + title={The Faiss library}, + author={Matthijs Douze and Alexandr Guzhva and Chengqi Deng and Jeff Johnson and Gergely Szilvasy and Pierre-Emmanuel Mazaré and Maria Lomeli and Lucas Hosseini and Hervé Jégou}, + year={2024}, + eprint={2401.08281}, + archivePrefix={arXiv}, + primaryClass={cs.LG} +} +``` +For the GPU version of Faiss, please cite: ``` @article{johnson2019billion, title={Billion-scale similarity search with {GPUs}}, From 5e3eae4fccb20723dbc674b3ffa005ce09afcd8d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 17 Jan 2024 16:48:14 -0800 Subject: [PATCH 031/206] Remove unused variables in faiss/utils/hamming.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: danzimm Differential Revision: D52847958 fbshipit-source-id: b3f98d8e0e4fd0e13191f0c0d907edd7c0e78db0 --- faiss/utils/hamming.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/utils/hamming.cpp b/faiss/utils/hamming.cpp index 79e10a4f01..93acaaf5b4 100644 --- a/faiss/utils/hamming.cpp +++ b/faiss/utils/hamming.cpp @@ -35,8 +35,6 @@ #include #include -static const size_t BLOCKSIZE_QUERY = 8192; - namespace faiss { size_t hamming_batch_size = 65536; From 091f344a34224dd3e207e044ec0b464fc09f5723 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 18 Jan 2024 11:11:58 -0800 Subject: [PATCH 032/206] add gpu to avx512 (#3210) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3210 Adds support for GPUs to the AVX512 binaries Reviewed By: mlomeli1 Differential Revision: D52874274 fbshipit-source-id: 6b10311f03007c47fe0d7690193591a393942bad --- faiss/gpu/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/faiss/gpu/CMakeLists.txt b/faiss/gpu/CMakeLists.txt index 0ab6ff3cea..24bafe4917 100644 --- a/faiss/gpu/CMakeLists.txt +++ b/faiss/gpu/CMakeLists.txt @@ -242,10 +242,11 @@ if(FAISS_ENABLE_RAFT) impl/RaftFlatIndex.cuh) list(APPEND FAISS_GPU_SRC impl/RaftFlatIndex.cu - impl/RaftIVFFlat.cu) + impl/RaftIVFFlat.cu) target_compile_definitions(faiss PUBLIC USE_NVIDIA_RAFT=1) target_compile_definitions(faiss_avx2 PUBLIC USE_NVIDIA_RAFT=1) + target_compile_definitions(faiss_avx512 PUBLIC USE_NVIDIA_RAFT=1) endif() # Export FAISS_GPU_HEADERS variable to parent scope. @@ -253,6 +254,7 @@ set(FAISS_GPU_HEADERS ${FAISS_GPU_HEADERS} PARENT_SCOPE) target_sources(faiss PRIVATE ${FAISS_GPU_SRC}) target_sources(faiss_avx2 PRIVATE ${FAISS_GPU_SRC}) +target_sources(faiss_avx512 PRIVATE ${FAISS_GPU_SRC}) foreach(header ${FAISS_GPU_HEADERS}) get_filename_component(dir ${header} DIRECTORY ) @@ -276,9 +278,12 @@ __nv_relfatbin : { *(__nv_relfatbin) } ) target_link_options(faiss PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") target_link_options(faiss_avx2 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") +target_link_options(faiss_avx512 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") find_package(CUDAToolkit REQUIRED) target_link_libraries(faiss PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) target_link_libraries(faiss_avx2 PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) +target_link_libraries(faiss_avx512 PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) target_compile_options(faiss PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) target_compile_options(faiss_avx2 PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) +target_compile_options(faiss_avx512 PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) From c540e762ca0ecf8f43da0bfc215da148c5cf420e Mon Sep 17 00:00:00 2001 From: Kota Yamaguchi Date: Thu, 18 Jan 2024 11:15:03 -0800 Subject: [PATCH 033/206] Use packaging instead of deprecated distutils for version handling (#3191) Summary: This PR replaces deprecated `distutils.version.LooseVersion` with [`packaging.version.Version`](https://packaging.pypa.io/en/stable/index.html). This change is needed to support CPython 3.12+. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3191 Reviewed By: algoriddle Differential Revision: D52872218 Pulled By: mlomeli1 fbshipit-source-id: 336b2a618fde0a65d70b53c7d8a27aef3b62ece1 --- conda/faiss-gpu-raft/meta.yaml | 1 + conda/faiss-gpu/meta.yaml | 1 + conda/faiss/meta.yaml | 1 + faiss/python/loader.py | 4 ++-- faiss/python/setup.py | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 84aa826c6c..b01fb6d695 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -84,6 +84,7 @@ outputs: run: - python {{ python }} - numpy >=1.19,<2 + - packaging - {{ pin_subpackage('libfaiss', exact=True) }} test: requires: diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index e7b839975f..7cc6e4ff3d 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -82,6 +82,7 @@ outputs: run: - python {{ python }} - numpy >=1.19,<2 + - packaging - {{ pin_subpackage('libfaiss', exact=True) }} test: requires: diff --git a/conda/faiss/meta.yaml b/conda/faiss/meta.yaml index a0431a4041..c4d66ca0d3 100644 --- a/conda/faiss/meta.yaml +++ b/conda/faiss/meta.yaml @@ -78,6 +78,7 @@ outputs: run: - python {{ python }} - numpy >=1.19,<2 + - packaging - {{ pin_subpackage('libfaiss', exact=True) }} test: requires: diff --git a/faiss/python/loader.py b/faiss/python/loader.py index eb60bf6800..8cc97f2f44 100644 --- a/faiss/python/loader.py +++ b/faiss/python/loader.py @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from distutils.version import LooseVersion +from packaging.version import Version import platform import subprocess import logging @@ -25,7 +25,7 @@ def supported_instruction_sets(): {"NEON", "ASIMD", ...} """ import numpy - if LooseVersion(numpy.__version__) >= "1.19": + if Version(numpy.__version__) >= Version("1.19"): # use private API as next-best thing until numpy/numpy#18058 is solved from numpy.core._multiarray_umath import __cpu_features__ # __cpu_features__ is a dictionary with CPU features diff --git a/faiss/python/setup.py b/faiss/python/setup.py index 1c9101290d..3b4f2e9c83 100644 --- a/faiss/python/setup.py +++ b/faiss/python/setup.py @@ -69,7 +69,7 @@ license='MIT', keywords='search nearest neighbors', - install_requires=['numpy'], + install_requires=['numpy', 'packaging'], packages=['faiss', 'faiss.contrib'], package_data={ 'faiss': ['*.so', '*.pyd'], From aff812ed4cfb1902577dbb9d3a14ec97230ae978 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 19 Jan 2024 03:54:36 -0800 Subject: [PATCH 034/206] Fix shadowed variable in faiss/clone_index.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: dmm-fb Differential Revision: D52582793 fbshipit-source-id: 2941630671d99de39c19cfc5d24b2e27e495c171 --- faiss/clone_index.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/faiss/clone_index.cpp b/faiss/clone_index.cpp index 44ab1f7cc3..39de1a8208 100644 --- a/faiss/clone_index.cpp +++ b/faiss/clone_index.cpp @@ -63,9 +63,10 @@ Index* clone_index(const Index* index) { // assumes there is a copy constructor ready. Always try from most // specific to most general. Most indexes don't have complicated // structs, the default copy constructor often just works. -#define TRYCLONE(classname, obj) \ - if (const classname* clo = dynamic_cast(obj)) { \ - return new classname(*clo); \ +#define TRYCLONE(classname, obj) \ + if (const classname* clo##classname = \ + dynamic_cast(obj)) { \ + return new classname(*clo##classname); \ } else VectorTransform* Cloner::clone_VectorTransform(const VectorTransform* vt) { From 7f3e0a349f6ff5752ff3e36ec0b2e03bea9007a0 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sun, 21 Jan 2024 12:14:46 -0800 Subject: [PATCH 035/206] Mismatch tags take 2 (#3211) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3211 X-link: https://github.com/facebookincubator/velox/pull/8461 Reviewed By: luciang Differential Revision: D52931746 fbshipit-source-id: 0aa40ff310ec48ace13927faaa47e0ebfa8b921e --- faiss/IndexReplicas.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/IndexReplicas.cpp b/faiss/IndexReplicas.cpp index 8295f34a60..85f3fda746 100644 --- a/faiss/IndexReplicas.cpp +++ b/faiss/IndexReplicas.cpp @@ -201,7 +201,7 @@ void IndexReplicasTemplate::syncWithSubIndexes() { } // explicit instantiations -template struct IndexReplicasTemplate; -template struct IndexReplicasTemplate; +template class IndexReplicasTemplate; +template class IndexReplicasTemplate; } // namespace faiss From 7e01b47a1c26bf97a5cf3f34dcce38f4c95126a6 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Mon, 22 Jan 2024 09:51:35 -0800 Subject: [PATCH 036/206] fix raft build Summary: Raft conda packages are built with conda-forge, which ships a newer version of swig, which broke the build. I'm pinning the version as a zero-effort attempt to fix this. ``` [ 80%] Building CXX object CMakeFiles/swigfaiss.dir/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx.o /home/circleci/miniconda/conda-bld/faiss-pkg_1705881814815/work/_build_python_3.9/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx: In function 'PyObject* swig_ptr(PyObject*)': /home/circleci/miniconda/conda-bld/faiss-pkg_1705881814815/work/_build_python_3.9/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx:6573:41: error: 'SWIGTYPE_p_unsigned_long_long' was not declared in this scope; did you mean 'SWIGTYPE_p_unsigned_long'? 6573 | return SWIG_NewPointerObj(data, SWIGTYPE_p_unsigned_long_long, 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/circleci/miniconda/conda-bld/faiss-pkg_1705881814815/work/_build_python_3.9/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx:1136:94: note: in definition of macro 'SWIG_NewPointerObj' 1136 | #define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) | ^~~~ /home/circleci/miniconda/conda-bld/faiss-pkg_1705881814815/work/_build_python_3.9/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx:6580:41: error: 'SWIGTYPE_p_long_long' was not declared in this scope; did you mean 'SWIGTYPE_p_MapLong2Long'? 6580 | return SWIG_NewPointerObj(data, SWIGTYPE_p_long_long, 0); | ^~~~~~~~~~~~~~~~~~~~ /home/circleci/miniconda/conda-bld/faiss-pkg_1705881814815/work/_build_python_3.9/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx:1136:94: note: in definition of macro 'SWIG_NewPointerObj' 1136 | #define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) | ^~~~ make[3]: *** [CMakeFiles/swigfaiss.dir/build.make:76: CMakeFiles/swigfaiss.dir/CMakeFiles/swigfaiss.dir/swigfaissPYTHON_wrap.cxx.o] Error 1 ``` Reviewed By: mlomeli1 Differential Revision: D52962236 fbshipit-source-id: e1a6b4c6ba03c9a0a320b5dbb54a8d618b8f8e74 --- conda/faiss-gpu-raft/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index b01fb6d695..b59c2d19b3 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -74,7 +74,7 @@ outputs: build: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - - swig + - swig =4.0.2 - cmake >=3.23.1 - make # [not win] host: From 3e666aea8becfd3970a2c2401214b0ac0424f392 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 22 Jan 2024 19:01:12 -0800 Subject: [PATCH 037/206] Remove extra semi colon from faiss/invlists/InvertedLists.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969085 fbshipit-source-id: f532f9000abd580e53159f660f6703dacb02796f --- faiss/invlists/InvertedLists.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/invlists/InvertedLists.cpp b/faiss/invlists/InvertedLists.cpp index 46f31e6286..ca87ae00ea 100644 --- a/faiss/invlists/InvertedLists.cpp +++ b/faiss/invlists/InvertedLists.cpp @@ -437,7 +437,7 @@ idx_t translate_list_no(const SliceInvertedLists* sil, idx_t list_no) { return list_no + sil->i0; } -}; // namespace +} // namespace SliceInvertedLists::SliceInvertedLists( const InvertedLists* il, @@ -522,7 +522,7 @@ idx_t sum_il_sizes(int nil, const InvertedLists** ils_in) { return tot; } -}; // namespace +} // namespace VStackInvertedLists::VStackInvertedLists(int nil, const InvertedLists** ils_in) : ReadOnlyInvertedLists( From 522452f7d35ce80c0f9396afe91e612c02a872e6 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 22 Jan 2024 19:06:17 -0800 Subject: [PATCH 038/206] Remove extra semi colon from faiss/python/python_callbacks.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969076 fbshipit-source-id: 97692db6dd7a2d6ffef12ebcdaadd99abf089ca1 --- faiss/python/python_callbacks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/python/python_callbacks.cpp b/faiss/python/python_callbacks.cpp index c99c1a3f77..bfcf883aec 100644 --- a/faiss/python/python_callbacks.cpp +++ b/faiss/python/python_callbacks.cpp @@ -22,7 +22,7 @@ struct PyThreadLock { } }; -}; // namespace +} // namespace /*********************************************************** * Callbacks for IO reader and writer From 683eadf1a036429265807baac41c1048d8b47da1 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 22 Jan 2024 19:43:11 -0800 Subject: [PATCH 039/206] Remove extra semi colon from faiss/utils/distances_simd.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52965948 fbshipit-source-id: e24e38ecbb7e0c957b024a1ae7b2ec94d2fa0adf --- faiss/utils/distances_simd.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/utils/distances_simd.cpp b/faiss/utils/distances_simd.cpp index 953e5b7763..b5cbb3c7e6 100644 --- a/faiss/utils/distances_simd.cpp +++ b/faiss/utils/distances_simd.cpp @@ -969,7 +969,6 @@ void fvec_L2sqr_ny_y_transposed_D( // squared length of x float x_sqlen = 0; - ; for (size_t j = 0; j < DIM; j++) { x_sqlen += x[j] * x[j]; } From b10eb35569f23ff3236cb807780419e20e59e0b2 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 22 Jan 2024 20:15:40 -0800 Subject: [PATCH 040/206] Remove extra semi colon from faiss/Clustering.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969138 fbshipit-source-id: bdde568b9bc6f4cc650e131a471a41f6bc2f3f95 --- faiss/Clustering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/Clustering.cpp b/faiss/Clustering.cpp index 1fd33bb2e7..31955bd531 100644 --- a/faiss/Clustering.cpp +++ b/faiss/Clustering.cpp @@ -250,7 +250,7 @@ int split_clusters( return nsplit; } -}; // namespace +} // namespace void Clustering::train_encoded( idx_t nx, @@ -617,7 +617,7 @@ void copy_columns(idx_t n, idx_t d1, const float* src, idx_t d2, float* dest) { } } -}; // namespace +} // namespace void ProgressiveDimClustering::train( idx_t n, From e19de27d72b47bb8782bc173725c45c46c9782eb Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 22 Jan 2024 20:32:04 -0800 Subject: [PATCH 041/206] Remove extra semi colon from faiss/IndexIVFFastScan.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969081 fbshipit-source-id: d728a4887ac1415ae88dae643055380a183c6990 --- faiss/IndexIVFFastScan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 45dae01f27..286e7ff0ef 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -450,7 +450,7 @@ int compute_search_nslice( return nslice; } -}; // namespace +} // namespace void IndexIVFFastScan::search_dispatch_implem( idx_t n, From a651069a37297c6651915f68c7a5b4515ed34e67 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 04:40:47 -0800 Subject: [PATCH 042/206] Remove unused variables in faiss/impl/index_read.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52981028 fbshipit-source-id: dbdf5c56e1d594e534183483c236ed2f08f98857 --- faiss/impl/index_read.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/faiss/impl/index_read.cpp b/faiss/impl/index_read.cpp index 3253100369..ac62e0269e 100644 --- a/faiss/impl/index_read.cpp +++ b/faiss/impl/index_read.cpp @@ -398,15 +398,12 @@ static void read_NSG(NSG* nsg, IOReader* f) { graph = std::make_shared>(N, R); std::fill_n(graph->data, N * R, EMPTY_ID); - int size = 0; - for (int i = 0; i < N; i++) { for (int j = 0; j < R + 1; j++) { int id; READ1(id); if (id != EMPTY_ID) { graph->at(i, j) = id; - size += 1; } else { break; } From e55a0ac5b579851daf8cea16ff3002ab739af214 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 04:40:52 -0800 Subject: [PATCH 043/206] Remove unused variables in faiss/impl/index_write.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52981052 fbshipit-source-id: 203e7ead56c69ffd77ee4a61eed1d0a502a14866 --- faiss/impl/index_write.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/impl/index_write.cpp b/faiss/impl/index_write.cpp index 7bb302700d..b2808d7170 100644 --- a/faiss/impl/index_write.cpp +++ b/faiss/impl/index_write.cpp @@ -338,13 +338,11 @@ static void write_NSG(const NSG* nsg, IOWriter* f) { FAISS_THROW_IF_NOT(K == nsg->R); FAISS_THROW_IF_NOT(true == graph->own_fields); - int size = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < K; j++) { int id = graph->at(i, j); if (id != EMPTY_ID) { WRITE1(id); - size += 1; } else { break; } From b274cb4f4fa823be274b0be1e2b3661fc739e902 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 06:15:33 -0800 Subject: [PATCH 044/206] Remove unused variables in faiss/IndexIVFFastScan.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52981034 fbshipit-source-id: 0315bb594a2dfaa059132b5f4e41855a4e15034b --- faiss/IndexIVFFastScan.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 286e7ff0ef..855665c617 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -858,7 +858,7 @@ void IndexIVFFastScan::search_implem_10( bool single_LUT = !lookup_table_is_3d(); - size_t ndis = 0, nlist_visited = 0; + size_t ndis = 0; int qmap1[1]; handler.q_map = qmap1; @@ -906,7 +906,6 @@ void IndexIVFFastScan::search_implem_10( handler, scaler); - nlist_visited++; ndis++; } } From a70a8a5e1d673cb7daa65ad064fbbfdd534695a5 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 06:26:35 -0800 Subject: [PATCH 045/206] Remove unused variables in faiss/impl/HNSW.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52981042 fbshipit-source-id: 6748dc957a26a6b5dec3922505c18a1996e3a002 --- faiss/impl/HNSW.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index 8c4c5be87f..fb4de67899 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -851,13 +851,11 @@ HNSWStats HNSW::search( top_candidates.pop(); } - int nres = 0; while (!top_candidates.empty()) { float d; storage_idx_t label; std::tie(d, label) = top_candidates.top(); res.add_result(d, label); - nres++; top_candidates.pop(); } } From bffedda90397251e7245e634a21214446f78eb00 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 08:38:30 -0800 Subject: [PATCH 046/206] Fix shadowed variable in faiss/IndexIDMap.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: dmm-fb Differential Revision: D52959009 fbshipit-source-id: 4842fdae7c20105746660304b3c04d20066c70ae --- faiss/IndexIDMap.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/faiss/IndexIDMap.cpp b/faiss/IndexIDMap.cpp index 02bfbc0553..e093bbda83 100644 --- a/faiss/IndexIDMap.cpp +++ b/faiss/IndexIDMap.cpp @@ -90,10 +90,10 @@ struct ScopedSelChange { SearchParameters* params = nullptr; IDSelector* old_sel = nullptr; - void set(SearchParameters* params, IDSelector* new_sel) { - this->params = params; - old_sel = params->sel; - params->sel = new_sel; + void set(SearchParameters* params_2, IDSelector* new_sel) { + this->params = params_2; + old_sel = params_2->sel; + params_2->sel = new_sel; } ~ScopedSelChange() { if (params) { From 0716bde2500edb2e18509bf05f5dfa37bd698082 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 08:40:54 -0800 Subject: [PATCH 047/206] Fix shadowed variable in faiss/IndexNSG.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: dmm-fb Differential Revision: D52959118 fbshipit-source-id: f3b44eb294ae534ebebfcb7d2da4cd70e259eaa3 --- faiss/IndexNSG.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/faiss/IndexNSG.cpp b/faiss/IndexNSG.cpp index 2d1c3d820f..45a547b93b 100644 --- a/faiss/IndexNSG.cpp +++ b/faiss/IndexNSG.cpp @@ -104,7 +104,7 @@ void IndexNSG::search( } } -void IndexNSG::build(idx_t n, const float* x, idx_t* knn_graph, int GK) { +void IndexNSG::build(idx_t n, const float* x, idx_t* knn_graph, int GK_2) { FAISS_THROW_IF_NOT_MSG( storage, "Please use IndexNSGFlat (or variants) instead of IndexNSG directly"); @@ -115,9 +115,9 @@ void IndexNSG::build(idx_t n, const float* x, idx_t* knn_graph, int GK) { ntotal = storage->ntotal; // check the knn graph - check_knn_graph(knn_graph, n, GK); + check_knn_graph(knn_graph, n, GK_2); - const nsg::Graph knng(knn_graph, n, GK); + const nsg::Graph knng(knn_graph, n, GK_2); nsg.build(storage, n, knng, verbose); is_built = true; } From bbb6ec7e1deb0fc997f19be51985a7fd54f9e83b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 23 Jan 2024 13:06:41 -0800 Subject: [PATCH 048/206] Remove unused variables in faiss/IndexShardsIVF.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: bunnypak, dmm-fb Differential Revision: D53011658 fbshipit-source-id: a8ba9102751def7a584167c3f50e4d02e9e6442c --- faiss/IndexShardsIVF.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/IndexShardsIVF.cpp b/faiss/IndexShardsIVF.cpp index fa6272d297..33c8f0e3e6 100644 --- a/faiss/IndexShardsIVF.cpp +++ b/faiss/IndexShardsIVF.cpp @@ -137,7 +137,6 @@ void IndexShardsIVF::add_with_ids( auto fn = [n, ids, x, nshard, d, Iq](int no, Index* index) { idx_t i0 = (idx_t)no * n / nshard; idx_t i1 = ((idx_t)no + 1) * n / nshard; - const float* x0 = x + i0 * d; auto index_ivf = dynamic_cast(index); if (index->verbose) { From e8494f62d984f58d232465a21c4e58ab7be7cfea Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 08:50:57 -0800 Subject: [PATCH 049/206] Remove unused variables in faiss/IndexBinaryHash.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: bunnypak, dmm-fb Differential Revision: D53011679 fbshipit-source-id: 90cdfb645d66e155b3de853dfab7586a8c720465 --- faiss/IndexBinaryHash.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/IndexBinaryHash.cpp b/faiss/IndexBinaryHash.cpp index 86a6d52ded..aca332d8d8 100644 --- a/faiss/IndexBinaryHash.cpp +++ b/faiss/IndexBinaryHash.cpp @@ -342,7 +342,6 @@ static void verify_shortlist( const std::unordered_set& shortlist, SearchResults& res) { size_t code_size = index->code_size; - size_t nlist = 0, ndis = 0, n0 = 0; HammingComputer hc(q, code_size); const uint8_t* codes = index->xb.data(); From 99c0e2bd59f10d5a978aabe8f773c337fe119fe0 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 09:00:55 -0800 Subject: [PATCH 050/206] Remove unused variables in faiss/utils/sorting.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: bunnypak, dmm-fb Differential Revision: D53011673 fbshipit-source-id: 011204944fdc48627a34e1358833fc525dcc2c28 --- faiss/utils/sorting.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/utils/sorting.cpp b/faiss/utils/sorting.cpp index 3c69f705a9..f8ed250ddb 100644 --- a/faiss/utils/sorting.cpp +++ b/faiss/utils/sorting.cpp @@ -791,7 +791,6 @@ void hashtable_int64_to_int64_lookup( std::vector hk(n), bucket_no(n); int64_t mask = capacity - 1; int log2_nbucket = log2_capacity_to_log2_nbucket(log2_capacity); - size_t nbucket = (size_t)1 << log2_nbucket; #pragma omp parallel for for (int64_t i = 0; i < n; i++) { From 63edc324356675b6c8b4722723eb18a77ec2198f Mon Sep 17 00:00:00 2001 From: Kota Yamaguchi Date: Wed, 24 Jan 2024 09:36:53 -0800 Subject: [PATCH 051/206] Fix AVX512 build targets in CMakeLists.txt (#3214) Summary: When `FAISS_OPT_LEVEL=avx512`, the current default target omits the `avx2` build, which conflicts with the install targets that specify both `avx2` and `avx512` builds. This PR fixes the default build targets for AVX512. Install targets: https://github.com/facebookresearch/faiss/blob/e19de27d72b47bb8782bc173725c45c46c9782eb/faiss/CMakeLists.txt#L332 With this PR, cmake can build and install without any error. ```bash cmake -B build -DFAISS_OPT_LEVEL=avx512 . cmake --build build --config Release -j cmake --install build ``` Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3214 Reviewed By: mlomeli1 Differential Revision: D52996716 Pulled By: algoriddle fbshipit-source-id: b8a46eee6cc15c2043a1a74c5e15d7a606e94acc --- faiss/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index 22dac7cb2c..72bf6d9e61 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -230,7 +230,7 @@ set(FAISS_HEADERS ${FAISS_HEADERS} PARENT_SCOPE) add_library(faiss ${FAISS_SRC}) add_library(faiss_avx2 ${FAISS_SRC}) -if(NOT FAISS_OPT_LEVEL STREQUAL "avx2") +if(NOT FAISS_OPT_LEVEL STREQUAL "avx2" AND NOT FAISS_OPT_LEVEL STREQUAL "avx512") set_target_properties(faiss_avx2 PROPERTIES EXCLUDE_FROM_ALL TRUE) endif() if(NOT WIN32) From 12637a2b127143fc59fc479aa86371af2cf489e2 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 11:26:51 -0800 Subject: [PATCH 052/206] Fix shadowed variable in faiss/utils/utils.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52959071 fbshipit-source-id: c71b331f9a1ee214cfef8143fdd41c336284d8a2 --- faiss/utils/utils.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/faiss/utils/utils.cpp b/faiss/utils/utils.cpp index c39a1bf5eb..dc6faddaf5 100644 --- a/faiss/utils/utils.cpp +++ b/faiss/utils/utils.cpp @@ -582,9 +582,9 @@ int64_t count_gt(int64_t n, const T* row, T threshold) { } // namespace template -void CombinerRangeKNN::compute_sizes(int64_t* L_res) { - this->L_res = L_res; - L_res[0] = 0; +void CombinerRangeKNN::compute_sizes(int64_t* L_res_2) { + this->L_res = L_res_2; + L_res_2[0] = 0; int64_t j = 0; for (int64_t i = 0; i < nq; i++) { int64_t n_in; @@ -595,11 +595,11 @@ void CombinerRangeKNN::compute_sizes(int64_t* L_res) { n_in = lim_remain[j + 1] - lim_remain[j]; j++; } - L_res[i + 1] = n_in; // L_res[i] + n_in; + L_res_2[i + 1] = n_in; // L_res_2[i] + n_in; } // cumsum for (int64_t i = 0; i < nq; i++) { - L_res[i + 1] += L_res[i]; + L_res_2[i + 1] += L_res_2[i]; } } From 7c4fb6dfe7d0892b9a76e5f28c778f8955bee86d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 11:27:22 -0800 Subject: [PATCH 053/206] Fix shadowed variable in faiss/impl/ResultHandler.h Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52958916 fbshipit-source-id: 408f0cc2c4687ef812b62631d708f2633754df69 --- faiss/impl/ResultHandler.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/faiss/impl/ResultHandler.h b/faiss/impl/ResultHandler.h index a532cf2a95..270de8dcd6 100644 --- a/faiss/impl/ResultHandler.h +++ b/faiss/impl/ResultHandler.h @@ -39,9 +39,9 @@ struct BlockResultHandler { size_t i0 = 0, i1 = 0; // start collecting results for queries [i0, i1) - virtual void begin_multiple(size_t i0, size_t i1) { - this->i0 = i0; - this->i1 = i1; + virtual void begin_multiple(size_t i0_2, size_t i1_2) { + this->i0 = i0_2; + this->i1 = i1_2; } // add results for queries [i0, i1) and database [j0, j1) @@ -96,8 +96,8 @@ struct Top1BlockResultHandler : BlockResultHandler { explicit SingleResultHandler(Top1BlockResultHandler& hr) : hr(hr) {} /// begin results for query # i - void begin(const size_t current_idx) { - this->current_idx = current_idx; + void begin(const size_t current_idx_2) { + this->current_idx = current_idx_2; threshold = C::neutral(); min_idx = -1; } @@ -130,9 +130,9 @@ struct Top1BlockResultHandler : BlockResultHandler { } /// add results for query i0..i1 and j0..j1 - void add_results(size_t j0, size_t j1, const T* dis_tab) final { + void add_results(size_t j0, size_t j1, const T* dis_tab_2) final { for (int64_t i = i0; i < i1; i++) { - const T* dis_tab_i = dis_tab + (j1 - j0) * (i - i0) - j0; + const T* dis_tab_i = dis_tab_2 + (j1 - j0) * (i - i0) - j0; auto& min_distance = this->dis_tab[i]; auto& min_index = this->ids_tab[i]; @@ -389,14 +389,14 @@ struct ReservoirBlockResultHandler : BlockResultHandler { size_t qno; /// begin results for query # i - void begin(size_t qno) { + void begin(size_t qno_2) { reservoir_dis.resize(hr.capacity); reservoir_ids.resize(hr.capacity); this->vals = reservoir_dis.data(); this->ids = reservoir_ids.data(); this->i = 0; // size of reservoir this->threshold = C::neutral(); - this->qno = qno; + this->qno = qno_2; } /// series of results for query qno is done From ae25b1bef1d1451bc39824004a319ca80de29ea8 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 11:28:16 -0800 Subject: [PATCH 054/206] Fix shadowed variable in faiss/impl/residual_quantizer_encode_steps.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52959180 fbshipit-source-id: 90f735f65f1306c817d80c99c8a2108aee7c599a --- faiss/impl/residual_quantizer_encode_steps.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/faiss/impl/residual_quantizer_encode_steps.cpp b/faiss/impl/residual_quantizer_encode_steps.cpp index d28537a577..8db6f9e5f7 100644 --- a/faiss/impl/residual_quantizer_encode_steps.cpp +++ b/faiss/impl/residual_quantizer_encode_steps.cpp @@ -292,8 +292,8 @@ void beam_search_encode_step( cent_ids.data() + i * beam_size * new_beam_size; // here we could be a tad more efficient by merging sorted arrays - for (int i = 0; i < new_beam_size; i++) { - new_distances_i[i] = C::neutral(); + for (int i_2 = 0; i_2 < new_beam_size; i_2++) { + new_distances_i[i_2] = C::neutral(); } std::vector perm(new_beam_size, -1); heap_addn( @@ -325,8 +325,8 @@ void beam_search_encode_step( const float* cent_distances_i = cent_distances.data() + i * beam_size * K; // then we have to select the best results - for (int i = 0; i < new_beam_size; i++) { - new_distances_i[i] = C::neutral(); + for (int i_2 = 0; i_2 < new_beam_size; i_2++) { + new_distances_i[i_2] = C::neutral(); } std::vector perm(new_beam_size, -1); @@ -558,8 +558,8 @@ void beam_search_encode_step_tab( const float* cent_distances_i = cent_distances.data(); // then we have to select the best results - for (int i = 0; i < new_beam_size; i++) { - new_distances_i[i] = C::neutral(); + for (int i_2 = 0; i_2 < new_beam_size; i_2++) { + new_distances_i[i_2] = C::neutral(); } std::vector perm(new_beam_size, -1); From a7b76a7d52ee74610470794ac5c6020434004c2b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 12:28:21 -0800 Subject: [PATCH 055/206] Fix shadowed variable in faiss/IndexAdditiveQuantizerFastScan.cpp Summary: Our upcoming compiler upgrade will require us not to have shadowed variables. Such variables have a _high_ bug rate and reduce readability, so we would like to avoid them even if the compiler was not forcing us to do so. This codemod attempts to fix an instance of a shadowed variable. Please review with care: if it's failed the result will be a silent bug. **What's a shadowed variable?** Shadowed variables are variables in an inner scope with the same name as another variable in an outer scope. Having the same name for both variables might be semantically correct, but it can make the code confusing to read! It can also hide subtle bugs. This diff fixes such an issue by renaming the variable. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52959038 fbshipit-source-id: 2b688a08710ff60aea0fea9d8be34f3c1f524f85 --- faiss/IndexAdditiveQuantizerFastScan.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/faiss/IndexAdditiveQuantizerFastScan.cpp b/faiss/IndexAdditiveQuantizerFastScan.cpp index 85a78647f3..1ad4d60926 100644 --- a/faiss/IndexAdditiveQuantizerFastScan.cpp +++ b/faiss/IndexAdditiveQuantizerFastScan.cpp @@ -35,30 +35,30 @@ IndexAdditiveQuantizerFastScan::IndexAdditiveQuantizerFastScan( } void IndexAdditiveQuantizerFastScan::init( - AdditiveQuantizer* aq, + AdditiveQuantizer* aq_2, MetricType metric, int bbs) { - FAISS_THROW_IF_NOT(aq != nullptr); - FAISS_THROW_IF_NOT(!aq->nbits.empty()); - FAISS_THROW_IF_NOT(aq->nbits[0] == 4); + FAISS_THROW_IF_NOT(aq_2 != nullptr); + FAISS_THROW_IF_NOT(!aq_2->nbits.empty()); + FAISS_THROW_IF_NOT(aq_2->nbits[0] == 4); if (metric == METRIC_INNER_PRODUCT) { FAISS_THROW_IF_NOT_MSG( - aq->search_type == AdditiveQuantizer::ST_LUT_nonorm, + aq_2->search_type == AdditiveQuantizer::ST_LUT_nonorm, "Search type must be ST_LUT_nonorm for IP metric"); } else { FAISS_THROW_IF_NOT_MSG( - aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 || - aq->search_type == AdditiveQuantizer::ST_norm_rq2x4, + aq_2->search_type == AdditiveQuantizer::ST_norm_lsq2x4 || + aq_2->search_type == AdditiveQuantizer::ST_norm_rq2x4, "Search type must be lsq2x4 or rq2x4 for L2 metric"); } - this->aq = aq; + this->aq = aq_2; if (metric == METRIC_L2) { - M = aq->M + 2; // 2x4 bits AQ + M = aq_2->M + 2; // 2x4 bits AQ } else { - M = aq->M; + M = aq_2->M; } - init_fastscan(aq->d, M, 4, metric, bbs); + init_fastscan(aq_2->d, M, 4, metric, bbs); max_train_points = 1024 * ksub * M; } From 6b2c79c0e320b1027c022ce5a18e9d119efacdf8 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 12:39:15 -0800 Subject: [PATCH 056/206] Remove extra semi colon from faiss/index_factory.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969102 fbshipit-source-id: f6e4992783a2a1ab0598bf96c664da950e5bba5d --- faiss/index_factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/index_factory.cpp b/faiss/index_factory.cpp index 5d7a505e09..0d61b73ecd 100644 --- a/faiss/index_factory.cpp +++ b/faiss/index_factory.cpp @@ -216,7 +216,7 @@ VectorTransform* parse_VectorTransform(const std::string& description, int d) { return new RemapDimensionsTransform(d, std::max(d_out, d), false); } return nullptr; -}; +} /*************************************************************** * Parse IndexIVF From fc4dbd513c712a714c03877a146b0c44bc27695b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 12:40:15 -0800 Subject: [PATCH 057/206] Remove extra semi colon from faiss/IndexIVFSpectralHash.cpp Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52968923 fbshipit-source-id: 5754c0b17b46bc90d0f05d66bbfacb24fee5caae --- faiss/IndexIVFSpectralHash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/IndexIVFSpectralHash.cpp b/faiss/IndexIVFSpectralHash.cpp index 5fb864c9a9..14741691d0 100644 --- a/faiss/IndexIVFSpectralHash.cpp +++ b/faiss/IndexIVFSpectralHash.cpp @@ -157,7 +157,7 @@ void binarize_with_freq( } } -}; // namespace +} // namespace void IndexIVFSpectralHash::encode_vectors( idx_t n, From a30fd74333356e74b93536fd83126748743e90fa Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 24 Jan 2024 13:19:29 -0800 Subject: [PATCH 058/206] Remove unused function from faiss/clone_index.cpp Summary: `-Wunused-function` has identified an unused function. This diff removes it. In many cases these functions have existed for years in an unused state. Reviewed By: palmje Differential Revision: D53049728 fbshipit-source-id: b3d6b98e4ef035f257e9120369b0e70b3200bec0 --- faiss/clone_index.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/faiss/clone_index.cpp b/faiss/clone_index.cpp index 39de1a8208..db16455f92 100644 --- a/faiss/clone_index.cpp +++ b/faiss/clone_index.cpp @@ -238,13 +238,6 @@ Index* clone_AdditiveQuantizerIndex(const Index* index) { namespace { -IndexHNSW* clone_HNSW(const IndexHNSW* ihnsw) { - TRYCLONE(IndexHNSWFlat, ihnsw) - TRYCLONE(IndexHNSWPQ, ihnsw) - TRYCLONE(IndexHNSWSQ, ihnsw) - return new IndexHNSW(*ihnsw); -} - InvertedLists* clone_InvertedLists(const InvertedLists* invlists) { if (auto* ails = dynamic_cast(invlists)) { return new ArrayInvertedLists(*ails); From c4b91a54d112a551b5ffa9988c49793a43f576c4 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 25 Jan 2024 07:24:04 -0800 Subject: [PATCH 059/206] Replace pickle serialization to address security vulnerability Summary: This diff replaces the use of pickle serialization with json to address a security vulnerability. Adding a warning message that this code is for demonstration purposes only. Reviewed By: mdouze Differential Revision: D52777650 fbshipit-source-id: d9d6a00fd341b29ac854adcbf675d2cd303d2f29 --- contrib/rpc.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/contrib/rpc.py b/contrib/rpc.py index cf89862260..e7145b9815 100755 --- a/contrib/rpc.py +++ b/contrib/rpc.py @@ -7,9 +7,12 @@ Simplistic RPC implementation. Exposes all functions of a Server object. -Uses pickle for serialization and the socket interface. +This code is for demonstration purposes only, and does not include certain +security protections. It is not meant to be run on an untrusted network or +in a production environment. """ +import importlib import os import pickle import sys @@ -23,22 +26,21 @@ # default PORT = 12032 +safe_modules = { + 'numpy', + 'numpy.core.multiarray', +} -######################################################################### -# simple I/O functions +class RestrictedUnpickler(pickle.Unpickler): -def inline_send_handle(f, conn): - st = os.fstat(f.fileno()) - size = st.st_size - pickle.dump(size, conn) - conn.write(f.read(size)) - - -def inline_send_string(s, conn): - size = len(s) - pickle.dump(size, conn) - conn.write(s) + def find_class(self, module, name): + # Only allow safe modules. + if module in safe_modules: + return getattr(importlib.import_module(module), name) + # Forbid everything else. + raise pickle.UnpicklingError("global '%s.%s' is forbidden" % + (module, name)) class FileSock: @@ -123,7 +125,7 @@ def one_function(self): """ try: - (fname,args)=pickle.load(self.fs) + (fname, args) = RestrictedUnpickler(self.fs).load() except EOFError: raise ClientExit("read args") self.log("executing method %s"%(fname)) @@ -214,7 +216,7 @@ def generic_fun(self, fname, args): return self.get_result() def get_result(self): - (st, ret) = pickle.load(self.fs) + (st, ret) = RestrictedUnpickler(self.fs).load() if st!=None: raise ServerException(st) else: From 51b6083187b1aa1b57fe805395525037c00e3dd6 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 25 Jan 2024 07:39:53 -0800 Subject: [PATCH 060/206] faiss on rocksdb demo (#3216) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3216 Reviewed By: mdouze Differential Revision: D53051090 Pulled By: algoriddle fbshipit-source-id: 13a027db36207af9be11a2f181116994b2aff2cb --- demos/rocksdb_ivf/CMakeLists.txt | 8 ++ demos/rocksdb_ivf/README.md | 23 +++++ demos/rocksdb_ivf/RocksDBInvertedLists.cpp | 108 +++++++++++++++++++++ demos/rocksdb_ivf/RocksDBInvertedLists.h | 58 +++++++++++ demos/rocksdb_ivf/demo_rocksdb_ivf.cpp | 81 ++++++++++++++++ 5 files changed, 278 insertions(+) create mode 100644 demos/rocksdb_ivf/CMakeLists.txt create mode 100644 demos/rocksdb_ivf/README.md create mode 100644 demos/rocksdb_ivf/RocksDBInvertedLists.cpp create mode 100644 demos/rocksdb_ivf/RocksDBInvertedLists.h create mode 100644 demos/rocksdb_ivf/demo_rocksdb_ivf.cpp diff --git a/demos/rocksdb_ivf/CMakeLists.txt b/demos/rocksdb_ivf/CMakeLists.txt new file mode 100644 index 0000000000..7bc3fe079c --- /dev/null +++ b/demos/rocksdb_ivf/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.17 FATAL_ERROR) +project (ROCKSDB_IVF) +set(CMAKE_BUILD_TYPE Debug) +find_package(faiss REQUIRED) +find_package(RocksDB REQUIRED) + +add_executable(demo_rocksdb_ivf demo_rocksdb_ivf.cpp RocksDBInvertedLists.cpp) +target_link_libraries(demo_rocksdb_ivf faiss RocksDB::rocksdb) diff --git a/demos/rocksdb_ivf/README.md b/demos/rocksdb_ivf/README.md new file mode 100644 index 0000000000..cf29ee2fde --- /dev/null +++ b/demos/rocksdb_ivf/README.md @@ -0,0 +1,23 @@ +# Storing Faiss inverted lists in RocksDB + +Demo of storing the inverted lists of any IVF index in RocksDB or any similar key-value store which supports the prefix scan operation. + +# How to build + +We use conda to create the build environment for simplicity. Only tested on Linux x86. + +``` +conda create -n rocksdb_ivf +conda activate rocksdb_ivf +conda install pytorch::faiss-cpu conda-forge::rocksdb cmake make gxx_linux-64 sysroot_linux-64 +cd ~/faiss/demos/rocksdb_ivf +cmake -B build . +make -C build -j$(nproc) +``` + +# Run the example + +``` +cd ~/faiss/demos/rocksdb_ivf/build +./rocksdb_ivf test_db +``` diff --git a/demos/rocksdb_ivf/RocksDBInvertedLists.cpp b/demos/rocksdb_ivf/RocksDBInvertedLists.cpp new file mode 100644 index 0000000000..99c51c1456 --- /dev/null +++ b/demos/rocksdb_ivf/RocksDBInvertedLists.cpp @@ -0,0 +1,108 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include "RocksDBInvertedLists.h" + +#include + +using namespace faiss; + +namespace faiss_rocksdb { + +RocksDBInvertedListsIterator::RocksDBInvertedListsIterator( + rocksdb::DB* db, + size_t list_no, + size_t code_size) + : InvertedListsIterator(), + it(db->NewIterator(rocksdb::ReadOptions())), + list_no(list_no), + code_size(code_size), + codes(code_size) { + it->Seek(rocksdb::Slice( + reinterpret_cast(&list_no), sizeof(size_t))); +} + +bool RocksDBInvertedListsIterator::is_available() const { + return it->Valid() && + it->key().starts_with(rocksdb::Slice( + reinterpret_cast(&list_no), sizeof(size_t))); +} + +void RocksDBInvertedListsIterator::next() { + it->Next(); +} + +std::pair RocksDBInvertedListsIterator:: + get_id_and_codes() { + idx_t id = + *reinterpret_cast(&it->key().data()[sizeof(size_t)]); + assert(code_size == it->value().size()); + return {id, reinterpret_cast(it->value().data())}; +} + +RocksDBInvertedLists::RocksDBInvertedLists( + const char* db_directory, + size_t nlist, + size_t code_size) + : InvertedLists(nlist, code_size) { + use_iterator = true; + + rocksdb::Options options; + options.create_if_missing = true; + rocksdb::DB* db; + rocksdb::Status status = rocksdb::DB::Open(options, db_directory, &db); + db_ = std::unique_ptr(db); + assert(status.ok()); +} + +size_t RocksDBInvertedLists::list_size(size_t /*list_no*/) const { + FAISS_THROW_MSG("list_size is not supported"); +} + +const uint8_t* RocksDBInvertedLists::get_codes(size_t /*list_no*/) const { + FAISS_THROW_MSG("get_codes is not supported"); +} + +const idx_t* RocksDBInvertedLists::get_ids(size_t /*list_no*/) const { + FAISS_THROW_MSG("get_ids is not supported"); +} + +size_t RocksDBInvertedLists::add_entries( + size_t list_no, + size_t n_entry, + const idx_t* ids, + const uint8_t* code) { + rocksdb::WriteOptions wo; + std::vector key(sizeof(size_t) + sizeof(idx_t)); + memcpy(key.data(), &list_no, sizeof(size_t)); + for (size_t i = 0; i < n_entry; i++) { + memcpy(key.data() + sizeof(size_t), ids + i, sizeof(idx_t)); + rocksdb::Status status = db_->Put( + wo, + rocksdb::Slice(key.data(), key.size()), + rocksdb::Slice( + reinterpret_cast(code + i * code_size), + code_size)); + assert(status.ok()); + } + return 0; // ignored +} + +void RocksDBInvertedLists::update_entries( + size_t /*list_no*/, + size_t /*offset*/, + size_t /*n_entry*/, + const idx_t* /*ids*/, + const uint8_t* /*code*/) { + FAISS_THROW_MSG("update_entries is not supported"); +} + +void RocksDBInvertedLists::resize(size_t /*list_no*/, size_t /*new_size*/) { + FAISS_THROW_MSG("resize is not supported"); +} + +InvertedListsIterator* RocksDBInvertedLists::get_iterator( + size_t list_no) const { + return new RocksDBInvertedListsIterator(db_.get(), list_no, code_size); +} + +} // namespace faiss_rocksdb diff --git a/demos/rocksdb_ivf/RocksDBInvertedLists.h b/demos/rocksdb_ivf/RocksDBInvertedLists.h new file mode 100644 index 0000000000..fdc83d1d27 --- /dev/null +++ b/demos/rocksdb_ivf/RocksDBInvertedLists.h @@ -0,0 +1,58 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#pragma once + +#include + +#include + +namespace faiss_rocksdb { + +struct RocksDBInvertedListsIterator : faiss::InvertedListsIterator { + RocksDBInvertedListsIterator( + rocksdb::DB* db, + size_t list_no, + size_t code_size); + virtual bool is_available() const override; + virtual void next() override; + virtual std::pair get_id_and_codes() override; + + private: + std::unique_ptr it; + size_t list_no; + size_t code_size; + std::vector codes; // buffer for returning codes in next() +}; + +struct RocksDBInvertedLists : faiss::InvertedLists { + RocksDBInvertedLists( + const char* db_directory, + size_t nlist, + size_t code_size); + + size_t list_size(size_t list_no) const override; + const uint8_t* get_codes(size_t list_no) const override; + const faiss::idx_t* get_ids(size_t list_no) const override; + + size_t add_entries( + size_t list_no, + size_t n_entry, + const faiss::idx_t* ids, + const uint8_t* code) override; + + void update_entries( + size_t list_no, + size_t offset, + size_t n_entry, + const faiss::idx_t* ids, + const uint8_t* code) override; + + void resize(size_t list_no, size_t new_size) override; + + faiss::InvertedListsIterator* get_iterator(size_t list_no) const override; + + private: + std::unique_ptr db_; +}; + +} // namespace faiss_rocksdb diff --git a/demos/rocksdb_ivf/demo_rocksdb_ivf.cpp b/demos/rocksdb_ivf/demo_rocksdb_ivf.cpp new file mode 100644 index 0000000000..72cf39eb03 --- /dev/null +++ b/demos/rocksdb_ivf/demo_rocksdb_ivf.cpp @@ -0,0 +1,81 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include "RocksDBInvertedLists.h" + +#include +#include +#include +#include +#include + +using namespace faiss; + +int main(int argc, char* argv[]) { + try { + if (argc != 2) { + std::cerr << "missing db directory argument" << std::endl; + return -1; + } + size_t d = 128; + size_t nlist = 100; + IndexFlatL2 quantizer(d); + IndexIVFFlat index(&quantizer, d, nlist); + faiss_rocksdb::RocksDBInvertedLists ril( + argv[1], nlist, index.code_size); + index.replace_invlists(&ril, false); + + idx_t nb = 10000; + std::vector xb(d * nb); + float_rand(xb.data(), d * nb, 12345); + std::vector xids(nb); + std::iota(xids.begin(), xids.end(), 0); + + index.train(nb, xb.data()); + index.add_with_ids(nb, xb.data(), xids.data()); + + idx_t nq = 20; // nb; + index.nprobe = 2; + + std::cout << "search" << std::endl; + idx_t k = 5; + std::vector distances(nq * k); + std::vector labels(nq * k, -1); + index.search( + nq, xb.data(), k, distances.data(), labels.data(), nullptr); + + for (idx_t iq = 0; iq < nq; iq++) { + std::cout << iq << ": "; + for (auto j = 0; j < k; j++) { + std::cout << labels[iq * k + j] << " " << distances[iq * k + j] + << " | "; + } + std::cout << std::endl; + } + + std::cout << std::endl << "range search" << std::endl; + float range = 15.0f; + RangeSearchResult result(nq); + index.range_search(nq, xb.data(), range, &result); + + for (idx_t iq = 0; iq < nq; iq++) { + std::cout << iq << ": "; + for (auto j = result.lims[iq]; j < result.lims[iq + 1]; j++) { + std::cout << result.labels[j] << " " << result.distances[j] + << " | "; + } + std::cout << std::endl; + } + + } catch (FaissException& e) { + std::cerr << e.what() << '\n'; + } catch (std::exception& e) { + std::cerr << e.what() << '\n'; + } catch (...) { + std::cerr << "Unrecognized exception!\n"; + } + return 0; +} From 1dcb5d314d63850c2f9e607d7558e05fac9415b5 Mon Sep 17 00:00:00 2001 From: Kota Yamaguchi Date: Thu, 25 Jan 2024 07:39:57 -0800 Subject: [PATCH 061/206] Add missing header files (#3218) Summary: The current CMakeList.txt misses a few header files. This PR adds these missing files. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3218 Reviewed By: mlomeli1 Differential Revision: D53081725 Pulled By: algoriddle fbshipit-source-id: 94531b39350f6d5b9f8c1bedbb1286f265e99a09 --- faiss/CMakeLists.txt | 2 ++ faiss/gpu/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index 72bf6d9e61..a890a46f11 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -147,6 +147,7 @@ set(FAISS_HEADERS index_io.h impl/AdditiveQuantizer.h impl/AuxIndexStructures.h + impl/CodePacker.h impl/IDSelector.h impl/DistanceComputer.h impl/FaissAssert.h @@ -198,6 +199,7 @@ set(FAISS_HEADERS utils/prefetch.h utils/quantize_lut.h utils/random.h + utils/sorting.h utils/simdlib.h utils/simdlib_avx2.h utils/simdlib_emulated.h diff --git a/faiss/gpu/CMakeLists.txt b/faiss/gpu/CMakeLists.txt index 24bafe4917..486546693f 100644 --- a/faiss/gpu/CMakeLists.txt +++ b/faiss/gpu/CMakeLists.txt @@ -238,6 +238,7 @@ generate_ivf_interleaved_code() if(FAISS_ENABLE_RAFT) list(APPEND FAISS_GPU_HEADERS + impl/RaftUtils.h impl/RaftIVFFlat.cuh impl/RaftFlatIndex.cuh) list(APPEND FAISS_GPU_SRC From 898ce35a8adb2ad23665d913b5c924dcff6fb7e1 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 25 Jan 2024 08:03:31 -0800 Subject: [PATCH 062/206] Remove unused function from faiss/utils/distances_simd.cpp Summary: `-Wunused-function` has identified an unused function. This diff removes it. In many cases these functions have existed for years in an unused state. Reviewed By: algoriddle Differential Revision: D53049745 fbshipit-source-id: aa6d9fa5b3ac93c777dd9a5ca239312d1a188a1c --- faiss/utils/distances_simd.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/faiss/utils/distances_simd.cpp b/faiss/utils/distances_simd.cpp index b5cbb3c7e6..d74ca664be 100644 --- a/faiss/utils/distances_simd.cpp +++ b/faiss/utils/distances_simd.cpp @@ -1630,21 +1630,6 @@ size_t fvec_L2sqr_ny_nearest_y_transposed( #ifdef USE_AVX -// reads 0 <= d < 8 floats as __m256 -static inline __m256 masked_read_8(int d, const float* x) { - assert(0 <= d && d < 8); - if (d < 4) { - __m256 res = _mm256_setzero_ps(); - res = _mm256_insertf128_ps(res, masked_read(d, x), 0); - return res; - } else { - __m256 res = _mm256_setzero_ps(); - res = _mm256_insertf128_ps(res, _mm_loadu_ps(x), 0); - res = _mm256_insertf128_ps(res, masked_read(d - 4, x + 4), 1); - return res; - } -} - float fvec_L1(const float* x, const float* y, size_t d) { __m256 msum1 = _mm256_setzero_ps(); __m256 signmask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffffUL)); @@ -1863,7 +1848,7 @@ void fvec_inner_products_ny( * heavily optimized table computations ***************************************************************************/ -static inline void fvec_madd_ref( +[[maybe_unused]] static inline void fvec_madd_ref( size_t n, const float* a, float bf, @@ -1930,7 +1915,7 @@ static inline void fvec_madd_avx2( #ifdef __SSE3__ -static inline void fvec_madd_sse( +[[maybe_unused]] static inline void fvec_madd_sse( size_t n, const float* a, float bf, From 67c6a191b784f407ab69ef702ddb57dfdfc535ff Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sat, 27 Jan 2024 10:28:14 -0800 Subject: [PATCH 063/206] Remove extra semi colon from faiss/impl/ProductAdditiveQuantizer.h Summary: `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: algoriddle Differential Revision: D52969139 fbshipit-source-id: 563843d43c64fb988ff0d08ccdb0408cd0eba454 --- faiss/impl/ProductAdditiveQuantizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/impl/ProductAdditiveQuantizer.h b/faiss/impl/ProductAdditiveQuantizer.h index 163d341cf2..a161180b16 100644 --- a/faiss/impl/ProductAdditiveQuantizer.h +++ b/faiss/impl/ProductAdditiveQuantizer.h @@ -151,4 +151,4 @@ struct ProductResidualQuantizer : ProductAdditiveQuantizer { ProductResidualQuantizer(); }; -}; // namespace faiss \ No newline at end of file +} // namespace faiss From 2817344f6f917ed744430beeeb1f53837c5f3607 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Mon, 29 Jan 2024 23:08:45 -0800 Subject: [PATCH 064/206] fix ACCESS VIOLATION error when searching using IDSelectorArray Summary: Fixes #3156 Metamate says: "This diff fixes an ACCESS VIOLATION error that occurs when searching using IDSelectorArray. The code changes include adding a new parameter to the knn_inner_products_by_idx and knn_L2sqr_by_idx functions in the distances.cpp file, as well as modifying the test_search_params.py file to test the bounds of the IDSelectorArray." Reviewed By: mdouze Differential Revision: D53185461 fbshipit-source-id: c7ec4783f77455684c078bba3aace160078f6c27 --- faiss/utils/distances.cpp | 17 ++++++++++++----- faiss/utils/distances.h | 2 ++ tests/test_search_params.py | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/faiss/utils/distances.cpp b/faiss/utils/distances.cpp index 784793c9a9..ebc3329c28 100644 --- a/faiss/utils/distances.cpp +++ b/faiss/utils/distances.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -670,7 +671,7 @@ void knn_inner_product( } if (auto sela = dynamic_cast(sel)) { knn_inner_products_by_idx( - x, y, sela->ids, d, nx, sela->n, k, vals, ids, 0); + x, y, sela->ids, d, nx, ny, sela->n, k, vals, ids, 0); return; } @@ -726,7 +727,7 @@ void knn_L2sqr( sel = nullptr; } if (auto sela = dynamic_cast(sel)) { - knn_L2sqr_by_idx(x, y, sela->ids, d, nx, sela->n, k, vals, ids, 0); + knn_L2sqr_by_idx(x, y, sela->ids, d, nx, ny, sela->n, k, vals, ids, 0); return; } if (k == 1) { @@ -904,6 +905,7 @@ void knn_inner_products_by_idx( size_t d, size_t nx, size_t ny, + size_t nsubset, size_t k, float* res_vals, int64_t* res_ids, @@ -921,9 +923,10 @@ void knn_inner_products_by_idx( int64_t* __restrict idxi = res_ids + i * k; minheap_heapify(k, simi, idxi); - for (j = 0; j < ny; j++) { - if (idsi[j] < 0) + for (j = 0; j < nsubset; j++) { + if (idsi[j] < 0 || idsi[j] >= ny) { break; + } float ip = fvec_inner_product(x_, y + d * idsi[j], d); if (ip > simi[0]) { @@ -941,6 +944,7 @@ void knn_L2sqr_by_idx( size_t d, size_t nx, size_t ny, + size_t nsubset, size_t k, float* res_vals, int64_t* res_ids, @@ -955,7 +959,10 @@ void knn_L2sqr_by_idx( float* __restrict simi = res_vals + i * k; int64_t* __restrict idxi = res_ids + i * k; maxheap_heapify(k, simi, idxi); - for (size_t j = 0; j < ny; j++) { + for (size_t j = 0; j < nsubset; j++) { + if (idsi[j] < 0 || idsi[j] >= ny) { + break; + } float disij = fvec_L2sqr(x_, y + d * idsi[j], d); if (disij < simi[0]) { diff --git a/faiss/utils/distances.h b/faiss/utils/distances.h index 898edeeb0e..c868581bb0 100644 --- a/faiss/utils/distances.h +++ b/faiss/utils/distances.h @@ -376,6 +376,7 @@ void knn_inner_products_by_idx( const int64_t* subset, size_t d, size_t nx, + size_t ny, size_t nsubset, size_t k, float* vals, @@ -398,6 +399,7 @@ void knn_L2sqr_by_idx( const int64_t* subset, size_t d, size_t nx, + size_t ny, size_t nsubset, size_t k, float* vals, diff --git a/tests/test_search_params.py b/tests/test_search_params.py index 8d3e42a49d..954d39cd00 100644 --- a/tests/test_search_params.py +++ b/tests/test_search_params.py @@ -257,6 +257,24 @@ def test_idmap(self): np.testing.assert_array_equal(Iref, Inew) np.testing.assert_array_almost_equal(Dref, Dnew, decimal=5) + def test_bounds(self): + # https://github.com/facebookresearch/faiss/issues/3156 + d = 64 # dimension + nb = 100000 # database size + xb = np.random.random((nb, d)) + index_ip = faiss.IndexFlatIP(d) + index_ip.add(xb) + index_l2 = faiss.IndexFlatIP(d) + index_l2.add(xb) + + out_of_bounds_id = nb + 15 # + 14 or lower will work fine + id_selector = faiss.IDSelectorArray([out_of_bounds_id]) + search_params = faiss.SearchParameters(sel=id_selector) + + # ignores out of bound, does not crash + distances, indices = index_ip.search(xb[:2], k=3, params=search_params) + distances, indices = index_l2.search(xb[:2], k=3, params=search_params) + class TestSearchParams(unittest.TestCase): From 31bddeb0cfa204791156522383c9470dcf8efbc1 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Tue, 30 Jan 2024 01:44:50 -0800 Subject: [PATCH 065/206] add faiss_gpu lib (#3222) Summary: 1. Split the GPU code into a separate static library to reduce build times. 2. faiss-gpu now depends on pytorch-cuda to stop clobbering of CUDA libraries when Faiss and Pytorch installed in the same environment 3. Add CUDA 12 (we support both 11.8 and 12.1) 4. Add Python 3.12 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3222 Reviewed By: mlomeli1 Differential Revision: D53215033 Pulled By: algoriddle fbshipit-source-id: d48c5707af20b7e5ff72c3aa27b0e677259f22f8 --- .circleci/config.yml | 77 +++++++++++++++++++++------------- conda/conda_build_config.yaml | 1 + conda/faiss-gpu-raft/meta.yaml | 7 ++-- conda/faiss-gpu/meta.yaml | 7 ++-- faiss/gpu/CMakeLists.txt | 29 +++++++------ 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 406817e09d..2901894577 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,13 +9,13 @@ executors: environment: CONDA_ARCH: Linux-x86_64 machine: - image: linux-cuda-11:default + image: linux-cuda-12:default resource_class: gpu.nvidia.medium linux-arm64-cpu: environment: CONDA_ARCH: Linux-aarch64 machine: - image: ubuntu-2004:current + image: ubuntu-2204:current resource_class: arm.medium macosx-arm64-cpu: environment: @@ -138,10 +138,9 @@ jobs: name: Conda build (GPU) no_output_timeout: 60m command: | - sudo update-alternatives --set cuda /usr/local/cuda-<> cd conda conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia + -c pytorch -c nvidia/label/cuda-<> - when: condition: and: @@ -153,10 +152,9 @@ jobs: name: Conda build (GPU) w/ anaconda upload no_output_timeout: 60m command: | - sudo update-alternatives --set cuda /usr/local/cuda-<> cd conda conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> - when: condition: and: @@ -168,7 +166,6 @@ jobs: name: Conda build (GPU w/ RAFT) no_output_timeout: 60m command: | - sudo update-alternatives --set cuda /usr/local/cuda-<> cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ -c pytorch -c nvidia -c rapidsai-nightly -c conda-forge @@ -183,10 +180,9 @@ jobs: name: Conda build (GPU w/ RAFT) w/ anaconda upload no_output_timeout: 60m command: | - sudo update-alternatives --set cuda /usr/local/cuda-<> cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia -c rapidsai-nightly -c conda-forge + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c rapidsai-nightly -c conda-forge build_cmake: parameters: @@ -216,27 +212,35 @@ jobs: bash miniconda.sh -b -p $HOME/miniconda ~/miniconda/bin/conda init fi - - when: - condition: - equal: [ "ON", << parameters.gpu >> ] - steps: - - run: - name: Configure CUDA - command: sudo update-alternatives --set cuda /usr/local/cuda-11.4 - run: name: Set up environment command: | conda config --set solver libmamba conda update -y -q conda - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 + - when: + condition: + equal: [ "OFF", << parameters.raft >> ] + steps: + - run: + name: Install env using main channel + command: | + conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 - when: condition: equal: [ "ON", << parameters.raft >> ] steps: - run: - name: Install libraft + name: Install env using conda-forge channel command: | - conda install -y -q libraft cuda-version=11.4 -c rapidsai-nightly -c nvidia -c pkgs/main -c conda-forge + conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + - when: + condition: + equal: [ "ON", << parameters.gpu >> ] + steps: + - run: + name: Install CUDA + command: | + conda install -y -q cuda-nvcc cuda-cudart-dev libcublas libcublas-dev cuda-toolkit -c "nvidia/label/cuda-11.8.0" - run: name: Build all targets no_output_timeout: 30m @@ -245,7 +249,7 @@ jobs: conda activate cmake -B build \ -DBUILD_TESTING=ON \ - -DBUILD_SHARED_LIBS=OFF \ + -DBUILD_SHARED_LIBS=ON \ -DFAISS_ENABLE_GPU=<< parameters.gpu >> \ -DFAISS_ENABLE_RAFT=<< parameters.raft >> \ -DFAISS_OPT_LEVEL=<< parameters.opt_level >> \ @@ -283,7 +287,7 @@ jobs: - run: name: Python tests (CPU + GPU) command: | - conda install -y -q pytorch pytorch-cuda=11 -c pytorch -c nvidia + conda install -y -q pytorch pytorch-cuda=11 -c pytorch -c nvidia/label/cuda-11.8.0 pytest --junitxml=test-results/pytest/results.xml tests/test_*.py pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py cp tests/common_faiss_tests.py faiss/gpu/test @@ -350,10 +354,10 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU packages (CUDA 11.4) + name: Linux x86_64 GPU packages (CUDA 11.8) exec: linux-x86_64-gpu label: main - cuda: "11.4" + cuda: "11.8" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: @@ -362,11 +366,11 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.4) + name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.8) exec: linux-x86_64-gpu label: main raft: "ON" - cuda: "11.4" + cuda: "11.8" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: @@ -416,17 +420,32 @@ workflows: exec: linux-x86_64-cpu label: nightly - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 11.4) + name: Linux x86_64 GPU nightlies (CUDA 11.8) + exec: linux-x86_64-gpu + cuda: "11.8.0" + cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + compiler_version: "11.2" + label: nightly + - build_conda: + name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 11.8.0) + exec: linux-x86_64-gpu + raft: "ON" + cuda: "11.8.0" + cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + compiler_version: "11.2" + label: nightly + - build_conda: + name: Linux x86_64 GPU nightlies (CUDA 12.1.0) exec: linux-x86_64-gpu - cuda: "11.4" + cuda: "12.1.0" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" label: nightly - build_conda: - name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 11.4) + name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 12.1.0) exec: linux-x86_64-gpu raft: "ON" - cuda: "11.4" + cuda: "12.1.0" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" label: nightly diff --git a/conda/conda_build_config.yaml b/conda/conda_build_config.yaml index 77f0eec0a2..cbfd2b0e81 100644 --- a/conda/conda_build_config.yaml +++ b/conda/conda_build_config.yaml @@ -2,3 +2,4 @@ python: - 3.9 - 3.10 - 3.11 + - 3.12 diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index b59c2d19b3..d5c893bd3d 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -44,15 +44,16 @@ outputs: - cmake >=3.23.1 - make # [not win] - mkl-devel =2023 # [x86_64] + - cuda-toolkit {{ cudatoolkit }} + - pytorch-cuda host: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - cuda-version {{ cudatoolkit }} - libraft =24.02 run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - {{ pin_compatible('cuda-version', max_pin='x') }} + - {{ pin_compatible('pytorch-cuda', max_pin='x') }} - libraft =24.02 test: requires: @@ -91,8 +92,6 @@ outputs: - numpy - scipy - pytorch - - pytorch-cuda =11.8 - - cuda-version =11.8 commands: - python -X faulthandler -m unittest discover -v -s tests/ -p "test_*" - python -X faulthandler -m unittest discover -v -s tests/ -p "torch_*" diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index 7cc6e4ff3d..c3e60c52ec 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -44,14 +44,15 @@ outputs: - cmake >=3.23.1 - make # [not win] - mkl-devel =2023 # [x86_64] + - cuda-toolkit {{ cudatoolkit }} + - pytorch-cuda host: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - cudatoolkit {{ cudatoolkit }} run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - {{ pin_compatible('cudatoolkit', max_pin='x') }} + - {{ pin_compatible('pytorch-cuda', max_pin='x') }} test: requires: - conda-build @@ -89,8 +90,6 @@ outputs: - numpy - scipy - pytorch - - pytorch-cuda =11.8 - - cudatoolkit =11.8 commands: - python -X faulthandler -m unittest discover -v -s tests/ -p "test_*" - python -X faulthandler -m unittest discover -v -s tests/ -p "torch_*" diff --git a/faiss/gpu/CMakeLists.txt b/faiss/gpu/CMakeLists.txt index 486546693f..713d3a287c 100644 --- a/faiss/gpu/CMakeLists.txt +++ b/faiss/gpu/CMakeLists.txt @@ -244,18 +244,29 @@ if(FAISS_ENABLE_RAFT) list(APPEND FAISS_GPU_SRC impl/RaftFlatIndex.cu impl/RaftIVFFlat.cu) +endif() + +add_library(faiss_gpu STATIC ${FAISS_GPU_SRC}) +set_target_properties(faiss_gpu PROPERTIES + POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON +) +target_include_directories(faiss_gpu PUBLIC + $) +if(FAISS_ENABLE_RAFT) target_compile_definitions(faiss PUBLIC USE_NVIDIA_RAFT=1) target_compile_definitions(faiss_avx2 PUBLIC USE_NVIDIA_RAFT=1) target_compile_definitions(faiss_avx512 PUBLIC USE_NVIDIA_RAFT=1) + target_compile_definitions(faiss_gpu PUBLIC USE_NVIDIA_RAFT=1) endif() # Export FAISS_GPU_HEADERS variable to parent scope. set(FAISS_GPU_HEADERS ${FAISS_GPU_HEADERS} PARENT_SCOPE) -target_sources(faiss PRIVATE ${FAISS_GPU_SRC}) -target_sources(faiss_avx2 PRIVATE ${FAISS_GPU_SRC}) -target_sources(faiss_avx512 PRIVATE ${FAISS_GPU_SRC}) +target_link_libraries(faiss PRIVATE "$") +target_link_libraries(faiss_avx2 PRIVATE "$") +target_link_libraries(faiss_avx512 PRIVATE "$") foreach(header ${FAISS_GPU_HEADERS}) get_filename_component(dir ${header} DIRECTORY ) @@ -277,14 +288,8 @@ __nv_relfatbin : { *(__nv_relfatbin) } } ]=] ) -target_link_options(faiss PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") -target_link_options(faiss_avx2 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") -target_link_options(faiss_avx512 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") +target_link_options(faiss_gpu PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") find_package(CUDAToolkit REQUIRED) -target_link_libraries(faiss PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) -target_link_libraries(faiss_avx2 PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) -target_link_libraries(faiss_avx512 PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) -target_compile_options(faiss PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) -target_compile_options(faiss_avx2 PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) -target_compile_options(faiss_avx512 PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) +target_link_libraries(faiss_gpu PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) +target_compile_options(faiss_gpu PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) From 420d25f51ca39e8cdfcd58c79bd21383f342a61e Mon Sep 17 00:00:00 2001 From: Maria Lomeli Date: Tue, 30 Jan 2024 09:20:07 -0800 Subject: [PATCH 066/206] Index pretransform support in search_preassigned (#3225) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3225 This diff fixes issue [#3113](https://github.com/facebookresearch/faiss/issues/3113), e.g. introduces support for index pretransform in `search_preassigned`. Reviewed By: mdouze Differential Revision: D53188584 fbshipit-source-id: 8189c0a59f957a2606391f22cf3fdc8874110a6e --- contrib/ivf_tools.py | 5 +++++ tests/test_contrib.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/contrib/ivf_tools.py b/contrib/ivf_tools.py index 26ada886a1..1c10eb0386 100644 --- a/contrib/ivf_tools.py +++ b/contrib/ivf_tools.py @@ -32,6 +32,11 @@ def search_preassigned(index_ivf, xq, k, list_nos, coarse_dis=None): Supports indexes with pretransforms (as opposed to the IndexIVF.search_preassigned, that cannot be applied with pretransform). """ + if isinstance(index_ivf, faiss.IndexPreTransform): + assert index_ivf.chain.size() == 1, "chain must have only one component" + transform = faiss.downcast_VectorTransform(index_ivf.chain.at(0)) + xq = transform.apply(xq) + index_ivf = faiss.downcast_index(index_ivf.index) n, d = xq.shape if isinstance(index_ivf, faiss.IndexBinaryIVF): d *= 8 diff --git a/tests/test_contrib.py b/tests/test_contrib.py index 36c17792ce..84b90a4e5f 100644 --- a/tests/test_contrib.py +++ b/tests/test_contrib.py @@ -306,6 +306,26 @@ def test_PR_multiple(self): class TestPreassigned(unittest.TestCase): + def test_index_pretransformed(self): + + ds = datasets.SyntheticDataset(128, 2000, 2000, 200) + xt = ds.get_train() + xq = ds.get_queries() + xb = ds.get_database() + index = faiss.index_factory(128, 'PCA64,IVF64,PQ4np') + index.train(xt) + index.add(xb) + index_downcasted = faiss.extract_index_ivf(index) + index_downcasted.nprobe = 10 + xq_trans = index.chain.at(0).apply_py(xq) + D_ref, I_ref = index.search(xq, 4) + + quantizer = index_downcasted.quantizer + Dq, Iq = quantizer.search(xq_trans, index_downcasted.nprobe) + D, I = ivf_tools.search_preassigned(index, xq, 4, Iq, Dq) + np.testing.assert_almost_equal(D_ref, D, decimal=4) + np.testing.assert_array_equal(I_ref, I) + def test_float(self): ds = datasets.SyntheticDataset(128, 2000, 2000, 200) From 75ae0bfb7fd50f321c5e5c361a177b1f7fdb835d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Tue, 30 Jan 2024 09:48:48 -0800 Subject: [PATCH 067/206] Remove unused variables in faiss/IndexScalarQuantizer.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: algoriddle Differential Revision: D52981077 fbshipit-source-id: ad164f9fbe267c6f594f9298132578f0a3805a2c --- faiss/IndexScalarQuantizer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/faiss/IndexScalarQuantizer.cpp b/faiss/IndexScalarQuantizer.cpp index 6b23315735..b7199df39d 100644 --- a/faiss/IndexScalarQuantizer.cpp +++ b/faiss/IndexScalarQuantizer.cpp @@ -210,12 +210,11 @@ void IndexIVFScalarQuantizer::add_core( const idx_t* coarse_idx) { FAISS_THROW_IF_NOT(is_trained); - size_t nadd = 0; std::unique_ptr squant(sq.select_quantizer()); DirectMapAdd dm_add(direct_map, n, xids); -#pragma omp parallel reduction(+ : nadd) +#pragma omp parallel { std::vector residual(d); std::vector one_code(code_size); @@ -240,7 +239,6 @@ void IndexIVFScalarQuantizer::add_core( size_t ofs = invlists->add_entry(list_no, id, one_code.data()); dm_add.add(i, list_no, ofs); - nadd++; } else if (rank == 0 && list_no == -1) { dm_add.add(i, -1, 0); From 1d0e8d489f15f7e34f5ebba978d44e675e2e35dd Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Tue, 30 Jan 2024 10:58:13 -0800 Subject: [PATCH 068/206] index optimizer (#3154) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3154 Using the benchmark to find Pareto optimal indices, in this case on BigANN as an example. Separately optimize the coarse quantizer and the vector codec and use Pareto optimal configurations to construct IVF indices, which are then retested at various scales. See `optimize()` in `optimize.py` as the main function driving the process. The results can be interpreted with `bench_fw_notebook.ipynb`, which allows: * filtering by maximum code size * maximum time * minimum accuracy * space or time Pareto optimal options * and visualize the results and output them as a table. This version is intentionally limited to IVF(Flat|HNSW),PQ|SQ indices... Reviewed By: mdouze Differential Revision: D51781670 fbshipit-source-id: 2c0f800d374ea845255934f519cc28095c00a51f --- benchs/bench_fw/benchmark.py | 122 +++- benchs/bench_fw/benchmark_io.py | 34 +- benchs/bench_fw/descriptors.py | 5 +- benchs/bench_fw/index.py | 203 ++++-- benchs/bench_fw/optimize.py | 333 +++++++++ benchs/bench_fw/utils.py | 169 ++++- benchs/bench_fw_notebook.ipynb | 1144 ++++++++++++++----------------- benchs/bench_fw_optimize.py | 58 ++ 8 files changed, 1318 insertions(+), 750 deletions(-) create mode 100644 benchs/bench_fw/optimize.py create mode 100644 benchs/bench_fw_optimize.py diff --git a/benchs/bench_fw/benchmark.py b/benchs/bench_fw/benchmark.py index ccdbf9c5d6..1053f99388 100644 --- a/benchs/bench_fw/benchmark.py +++ b/benchs/bench_fw/benchmark.py @@ -7,19 +7,20 @@ from copy import copy from dataclasses import dataclass from operator import itemgetter -from statistics import median, mean +from statistics import mean, median from typing import Any, Dict, List, Optional -from .utils import dict_merge -from .index import Index, IndexFromCodec, IndexFromFactory -from .descriptors import DatasetDescriptor, IndexDescriptor - import faiss # @manual=//faiss/python:pyfaiss_gpu import numpy as np from scipy.optimize import curve_fit +from .descriptors import DatasetDescriptor, IndexDescriptor +from .index import Index, IndexFromCodec, IndexFromFactory + +from .utils import dict_merge + logger = logging.getLogger(__name__) @@ -274,8 +275,8 @@ def range_search( search_parameters: Optional[Dict[str, int]], radius: Optional[float] = None, gt_radius: Optional[float] = None, - range_search_metric_function = None, - gt_rsm = None, + range_search_metric_function=None, + gt_rsm=None, ): logger.info("range_search: begin") if radius is None: @@ -328,7 +329,13 @@ def knn_ground_truth(self): logger.info("knn_ground_truth: begin") flat_desc = self.get_index_desc("Flat") self.build_index_wrapper(flat_desc) - self.gt_knn_D, self.gt_knn_I, _, _, requires = flat_desc.index.knn_search( + ( + self.gt_knn_D, + self.gt_knn_I, + _, + _, + requires, + ) = flat_desc.index.knn_search( dry_run=False, search_parameters=None, query_vectors=self.query_vectors, @@ -338,13 +345,13 @@ def knn_ground_truth(self): logger.info("knn_ground_truth: end") def search_benchmark( - self, + self, name, search_func, key_func, cost_metrics, perf_metrics, - results: Dict[str, Any], + results: Dict[str, Any], index: Index, ): index_name = index.get_index_name() @@ -376,11 +383,18 @@ def experiment(parameters, cost_metric, perf_metric): logger.info(f"{name}_benchmark: end") return results, requires - def knn_search_benchmark(self, dry_run, results: Dict[str, Any], index: Index): + def knn_search_benchmark( + self, dry_run, results: Dict[str, Any], index: Index + ): return self.search_benchmark( name="knn_search", search_func=lambda parameters: index.knn_search( - dry_run, parameters, self.query_vectors, self.k, self.gt_knn_I, self.gt_knn_D, + dry_run, + parameters, + self.query_vectors, + self.k, + self.gt_knn_I, + self.gt_knn_D, )[3:], key_func=lambda parameters: index.get_knn_search_name( search_parameters=parameters, @@ -394,11 +408,17 @@ def knn_search_benchmark(self, dry_run, results: Dict[str, Any], index: Index): index=index, ) - def reconstruct_benchmark(self, dry_run, results: Dict[str, Any], index: Index): + def reconstruct_benchmark( + self, dry_run, results: Dict[str, Any], index: Index + ): return self.search_benchmark( name="reconstruct", search_func=lambda parameters: index.reconstruct( - dry_run, parameters, self.query_vectors, self.k, self.gt_knn_I, + dry_run, + parameters, + self.query_vectors, + self.k, + self.gt_knn_I, ), key_func=lambda parameters: index.get_knn_search_name( search_parameters=parameters, @@ -426,19 +446,20 @@ def range_search_benchmark( return self.search_benchmark( name="range_search", search_func=lambda parameters: self.range_search( - dry_run=dry_run, - index=index, - search_parameters=parameters, + dry_run=dry_run, + index=index, + search_parameters=parameters, radius=radius, gt_radius=gt_radius, - range_search_metric_function=range_search_metric_function, + range_search_metric_function=range_search_metric_function, gt_rsm=gt_rsm, )[4:], key_func=lambda parameters: index.get_range_search_name( search_parameters=parameters, query_vectors=self.query_vectors, radius=radius, - ) + metric_key, + ) + + metric_key, cost_metrics=["time"], perf_metrics=["range_score_max_recall"], results=results, @@ -446,11 +467,12 @@ def range_search_benchmark( ) def build_index_wrapper(self, index_desc: IndexDescriptor): - if hasattr(index_desc, 'index'): + if hasattr(index_desc, "index"): return if index_desc.factory is not None: training_vectors = copy(self.training_vectors) - training_vectors.num_vectors = index_desc.training_size + if index_desc.training_size is not None: + training_vectors.num_vectors = index_desc.training_size index = IndexFromFactory( num_threads=self.num_threads, d=self.d, @@ -481,15 +503,24 @@ def clone_one(self, index_desc): training_vectors=self.training_vectors, database_vectors=self.database_vectors, query_vectors=self.query_vectors, - index_descs = [self.get_index_desc("Flat"), index_desc], + index_descs=[self.get_index_desc("Flat"), index_desc], range_ref_index_desc=self.range_ref_index_desc, k=self.k, distance_metric=self.distance_metric, ) - benchmark.set_io(self.io) + benchmark.set_io(self.io.clone()) return benchmark - def benchmark_one(self, dry_run, results: Dict[str, Any], index_desc: IndexDescriptor, train, reconstruct, knn, range): + def benchmark_one( + self, + dry_run, + results: Dict[str, Any], + index_desc: IndexDescriptor, + train, + reconstruct, + knn, + range, + ): faiss.omp_set_num_threads(self.num_threads) if not dry_run: self.knn_ground_truth() @@ -531,9 +562,12 @@ def benchmark_one(self, dry_run, results: Dict[str, Any], index_desc: IndexDescr ) assert requires is None - if self.range_ref_index_desc is None or not index_desc.index.supports_range_search(): + if ( + self.range_ref_index_desc is None + or not index_desc.index.supports_range_search() + ): return results, None - + ref_index_desc = self.get_index_desc(self.range_ref_index_desc) if ref_index_desc is None: raise ValueError( @@ -550,7 +584,9 @@ def benchmark_one(self, dry_run, results: Dict[str, Any], index_desc: IndexDescr coefficients, coefficients_training_data, ) = self.range_search_reference( - ref_index_desc.index, ref_index_desc.search_params, range_metric + ref_index_desc.index, + ref_index_desc.search_params, + range_metric, ) gt_rsm = self.range_ground_truth( gt_radius, range_search_metric_function @@ -583,7 +619,15 @@ def benchmark_one(self, dry_run, results: Dict[str, Any], index_desc: IndexDescr return results, None - def benchmark(self, result_file=None, local=False, train=False, reconstruct=False, knn=False, range=False): + def benchmark( + self, + result_file=None, + local=False, + train=False, + reconstruct=False, + knn=False, + range=False, + ): logger.info("begin evaluate") faiss.omp_set_num_threads(self.num_threads) @@ -656,20 +700,34 @@ def benchmark(self, result_file=None, local=False, train=False, reconstruct=Fals if current_todo: results_one = {"indices": {}, "experiments": {}} - params = [(self.clone_one(index_desc), results_one, index_desc, train, reconstruct, knn, range) for index_desc in current_todo] - for result in self.io.launch_jobs(run_benchmark_one, params, local=local): + params = [ + ( + index_desc, + self.clone_one(index_desc), + results_one, + train, + reconstruct, + knn, + range, + ) + for index_desc in current_todo + ] + for result in self.io.launch_jobs( + run_benchmark_one, params, local=local + ): dict_merge(results, result) - todo = next_todo + todo = next_todo if result_file is not None: self.io.write_json(results, result_file, overwrite=True) logger.info("end evaluate") return results + def run_benchmark_one(params): logger.info(params) - benchmark, results, index_desc, train, reconstruct, knn, range = params + index_desc, benchmark, results, train, reconstruct, knn, range = params results, requires = benchmark.benchmark_one( dry_run=False, results=results, diff --git a/benchs/bench_fw/benchmark_io.py b/benchs/bench_fw/benchmark_io.py index 483acba8c7..b39bb60290 100644 --- a/benchs/bench_fw/benchmark_io.py +++ b/benchs/bench_fw/benchmark_io.py @@ -10,13 +10,13 @@ import os import pickle from dataclasses import dataclass -import submitit from typing import Any, List, Optional from zipfile import ZipFile import faiss # @manual=//faiss/python:pyfaiss_gpu import numpy as np +import submitit from faiss.contrib.datasets import ( # @manual=//faiss/contrib:faiss_contrib_gpu dataset_from_name, ) @@ -47,6 +47,9 @@ def merge_rcq_itq( class BenchmarkIO: path: str + def clone(self): + return BenchmarkIO(path=self.path) + def __post_init__(self): self.cached_ds = {} @@ -119,18 +122,27 @@ def write_file( def get_dataset(self, dataset): if dataset not in self.cached_ds: - if dataset.namespace is not None and dataset.namespace[:4] == "std_": + if ( + dataset.namespace is not None + and dataset.namespace[:4] == "std_" + ): if dataset.tablename not in self.cached_ds: self.cached_ds[dataset.tablename] = dataset_from_name( dataset.tablename, ) p = dataset.namespace[4] if p == "t": - self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_train(dataset.num_vectors) + self.cached_ds[dataset] = self.cached_ds[ + dataset.tablename + ].get_train(dataset.num_vectors) elif p == "d": - self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_database() + self.cached_ds[dataset] = self.cached_ds[ + dataset.tablename + ].get_database() elif p == "q": - self.cached_ds[dataset] = self.cached_ds[dataset.tablename].get_queries() + self.cached_ds[dataset] = self.cached_ds[ + dataset.tablename + ].get_queries() else: raise ValueError elif dataset.namespace == "syn": @@ -233,8 +245,8 @@ def launch_jobs(self, func, params, local=True): if local: results = [func(p) for p in params] return results - print(f'launching {len(params)} jobs') - executor = submitit.AutoExecutor(folder='/checkpoint/gsz/jobs') + logger.info(f"launching {len(params)} jobs") + executor = submitit.AutoExecutor(folder="/checkpoint/gsz/jobs") executor.update_parameters( nodes=1, gpus_per_node=8, @@ -248,9 +260,9 @@ def launch_jobs(self, func, params, local=True): slurm_constraint="bldg1", ) jobs = executor.map_array(func, params) - print(f'launched {len(jobs)} jobs') - # for job, param in zip(jobs, params): - # print(f"{job.job_id=} {param=}") + logger.info(f"launched {len(jobs)} jobs") + for job, param in zip(jobs, params): + logger.info(f"{job.job_id=} {param[0]=}") results = [job.result() for job in jobs] - print(f'received {len(results)} results') + print(f"received {len(results)} results") return results diff --git a/benchs/bench_fw/descriptors.py b/benchs/bench_fw/descriptors.py index 113f46b545..f1dd7354c2 100644 --- a/benchs/bench_fw/descriptors.py +++ b/benchs/bench_fw/descriptors.py @@ -9,6 +9,7 @@ import faiss # @manual=//faiss/python:pyfaiss_gpu from .utils import timer + logger = logging.getLogger(__name__) @@ -101,7 +102,9 @@ def k_means(self, io, k, dry_run): tablename=f"{self.get_filename()}kmeans_{k}.npy" ) meta_filename = kmeans_vectors.tablename + ".json" - if not io.file_exist(kmeans_vectors.tablename) or not io.file_exist(meta_filename): + if not io.file_exist(kmeans_vectors.tablename) or not io.file_exist( + meta_filename + ): if dry_run: return None, None, kmeans_vectors.tablename x = io.get_dataset(self) diff --git a/benchs/bench_fw/index.py b/benchs/bench_fw/index.py index 4c536aa753..14f2158e64 100644 --- a/benchs/bench_fw/index.py +++ b/benchs/bench_fw/index.py @@ -4,19 +4,19 @@ # LICENSE file in the root directory of this source tree. -from copy import copy import logging import os from collections import OrderedDict +from copy import copy from dataclasses import dataclass from typing import ClassVar, Dict, List, Optional import faiss # @manual=//faiss/python:pyfaiss_gpu - import numpy as np + from faiss.contrib.evaluation import ( # @manual=//faiss/contrib:faiss_contrib_gpu - OperatingPointsWithRanges, knn_intersection_measure, + OperatingPointsWithRanges, ) from faiss.contrib.factory_tools import ( # @manual=//faiss/contrib:faiss_contrib_gpu reverse_index_factory, @@ -27,7 +27,13 @@ ) from .descriptors import DatasetDescriptor -from .utils import distance_ratio_measure, get_cpu_info, timer, refine_distances_knn, refine_distances_range +from .utils import ( + distance_ratio_measure, + get_cpu_info, + refine_distances_knn, + refine_distances_range, + timer, +) logger = logging.getLogger(__name__) @@ -106,7 +112,9 @@ def set_index_param(index, name, val, assert_same=False): icm_encoder_factory = faiss.GpuIcmEncoderFactory(ngpus) if isinstance(index, faiss.IndexProductLocalSearchQuantizer): for i in range(index.plsq.nsplits): - lsq = faiss.downcast_Quantizer(index.plsq.subquantizer(i)) + lsq = faiss.downcast_Quantizer( + index.plsq.subquantizer(i) + ) if lsq.icm_encoder_factory is None: lsq.icm_encoder_factory = icm_encoder_factory else: @@ -119,29 +127,39 @@ def set_index_param(index, name, val, assert_same=False): obj = faiss.extract_index_ivf(index) elif name in ["use_beam_LUT", "max_beam_size"]: if isinstance(index, faiss.IndexProductResidualQuantizer): - obj = [faiss.downcast_Quantizer(index.prq.subquantizer(i)) for i in range(index.prq.nsplits)] + obj = [ + faiss.downcast_Quantizer(index.prq.subquantizer(i)) + for i in range(index.prq.nsplits) + ] else: obj = index.rq elif name == "encode_ils_iters": if isinstance(index, faiss.IndexProductLocalSearchQuantizer): - obj = [faiss.downcast_Quantizer(index.plsq.subquantizer(i)) for i in range(index.plsq.nsplits)] + obj = [ + faiss.downcast_Quantizer(index.plsq.subquantizer(i)) + for i in range(index.plsq.nsplits) + ] else: obj = index.lsq else: obj = index - + if not isinstance(obj, list): obj = [obj] for o in obj: test = getattr(o, name) - if assert_same and not name == 'use_beam_LUT': + if assert_same and not name == "use_beam_LUT": assert test == val else: setattr(o, name, val) @staticmethod def filter_index_param_dict_list(param_dict_list): - if param_dict_list is not None and param_dict_list[0] is not None and "k_factor" in param_dict_list[0]: + if ( + param_dict_list is not None + and param_dict_list[0] is not None + and "k_factor" in param_dict_list[0] + ): filtered = copy(param_dict_list) del filtered[0]["k_factor"] return filtered @@ -153,6 +171,7 @@ def is_flat(self): return isinstance(model, faiss.IndexFlat) def is_ivf(self): + return False model = self.get_model() return faiss.try_extract_index_ivf(model) is not None @@ -243,7 +262,9 @@ def knn_search_quantizer(self, query_vectors, k): pretransform = None quantizer_query_vectors = query_vectors - quantizer, _, _ = self.get_quantizer(dry_run=False, pretransform=pretransform) + quantizer, _, _ = self.get_quantizer( + dry_run=False, pretransform=pretransform + ) QD, QI, _, QP, _ = quantizer.knn_search( dry_run=False, search_parameters=None, @@ -300,7 +321,9 @@ def knn_search( # Index2Layer doesn't support search xq = self.io.get_dataset(query_vectors) xb = index.reconstruct_n(0, index.ntotal) - (D, I), t, _ = timer("knn_search 2layer", lambda: faiss.knn(xq, xb, k)) + (D, I), t, _ = timer( + "knn_search 2layer", lambda: faiss.knn(xq, xb, k) + ) elif self.is_ivf() and not isinstance(index, faiss.IndexRefine): index_ivf = faiss.extract_index_ivf(index) nprobe = ( @@ -310,7 +333,7 @@ def knn_search( else index_ivf.nprobe ) xqt, QD, QI, QP = self.knn_search_quantizer( - query_vectors=query_vectors, + query_vectors=query_vectors, k=nprobe, ) if index_ivf.parallel_mode != 2: @@ -358,11 +381,19 @@ def knn_search( "construction_params": self.get_construction_params(), "search_params": search_parameters, "knn_intersection": knn_intersection_measure( - I, I_gt, - ) if I_gt is not None else None, + I, + I_gt, + ) + if I_gt is not None + else None, "distance_ratio": distance_ratio_measure( - I, R, D_gt, self.metric_type, - ) if D_gt is not None else None, + I, + R, + D_gt, + self.metric_type, + ) + if D_gt is not None + else None, } logger.info("knn_search: end") return D, I, R, P, None @@ -377,12 +408,14 @@ def reconstruct( ): logger.info("reconstruct: begin") filename = ( - self.get_knn_search_name(parameters, query_vectors, k, reconstruct=True) + self.get_knn_search_name( + parameters, query_vectors, k, reconstruct=True + ) + "zip" ) if self.io.file_exist(filename): logger.info(f"Using cached results for {filename}") - P, = self.io.read_file(filename, ["P"]) + (P,) = self.io.read_file(filename, ["P"]) P["index"] = self.get_index_name() P["codec"] = self.get_codec_name() P["factory"] = self.get_model_name() @@ -395,15 +428,21 @@ def reconstruct( codec_meta = self.fetch_meta() Index.set_index_param_dict(codec, parameters) xb = self.io.get_dataset(self.database_vectors) - xb_encoded, encode_t, _ = timer("sa_encode", lambda: codec.sa_encode(xb)) + xb_encoded, encode_t, _ = timer( + "sa_encode", lambda: codec.sa_encode(xb) + ) xq = self.io.get_dataset(query_vectors) if self.is_decode_supported(): - xb_decoded, decode_t, _ = timer("sa_decode", lambda: codec.sa_decode(xb_encoded)) + xb_decoded, decode_t, _ = timer( + "sa_decode", lambda: codec.sa_decode(xb_encoded) + ) mse = np.square(xb_decoded - xb).sum(axis=1).mean().item() _, I = faiss.knn(xq, xb_decoded, k, metric=self.metric_type) asym_recall = knn_intersection_measure(I, I_gt) xq_decoded = codec.sa_decode(codec.sa_encode(xq)) - _, I = faiss.knn(xq_decoded, xb_decoded, k, metric=self.metric_type) + _, I = faiss.knn( + xq_decoded, xb_decoded, k, metric=self.metric_type + ) else: mse = None asym_recall = None @@ -604,7 +643,7 @@ def fetch_index(self): if self.is_ivf() and not isinstance(index, faiss.IndexRefine): xbt, QD, QI, QP = self.knn_search_quantizer( - query_vectors=self.database_vectors, + query_vectors=self.database_vectors, k=1, ) index_ivf = faiss.extract_index_ivf(index) @@ -638,22 +677,21 @@ def get_index(self): def get_construction_params(self): return self.construction_params - # def get_code_size(self): - # def get_index_code_size(index): - # index = faiss.downcast_index(index) - # if isinstance(index, faiss.IndexPreTransform): - # return get_index_code_size(index.index) - # elif isinstance(index, faiss.IndexHNSWFlat): - # return index.d * 4 # TODO - # elif type(index) in [faiss.IndexRefine, faiss.IndexRefineFlat]: - # return get_index_code_size( - # index.base_index - # ) + get_index_code_size(index.refine_index) - # else: - # return index.code_size - - # codec = self.get_codec() - # return get_index_code_size(codec) + def get_code_size(self, codec=None): + def get_index_code_size(index): + index = faiss.downcast_index(index) + if isinstance(index, faiss.IndexPreTransform): + return get_index_code_size(index.index) + elif type(index) in [faiss.IndexRefine, faiss.IndexRefineFlat]: + return get_index_code_size( + index.base_index + ) + get_index_code_size(index.refine_index) + else: + return index.code_size if hasattr(index, "code_size") else 0 + + if codec is None: + codec = self.get_codec() + return get_index_code_size(codec) def get_sa_code_size(self, codec=None): if codec is None: @@ -680,32 +718,28 @@ def add_range_or_val(name, range): if model_ivf is not None: add_range_or_val( "nprobe", - # [ + [2**i for i in range(12) if 2**i <= model_ivf.nlist * 0.5], + # [1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28] + [ + # i + # for i in range(32, 64, 8) + # if i <= model_ivf.nlist * 0.1 + # ] + [ + # i + # for i in range(64, 128, 16) + # if i <= model_ivf.nlist * 0.1 + # ] + [ + # i + # for i in range(128, 256, 32) + # if i <= model_ivf.nlist * 0.1 + # ] + [ + # i + # for i in range(256, 512, 64) + # if i <= model_ivf.nlist * 0.1 + # ] + [ # 2**i - # for i in range(12) - # if 2**i <= model_ivf.nlist * 0.5 + # for i in range(9, 12) + # if 2**i <= model_ivf.nlist * 0.1 # ], - [1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28] + [ - i - for i in range(32, 64, 8) - if i <= model_ivf.nlist * 0.1 - ] + [ - i - for i in range(64, 128, 16) - if i <= model_ivf.nlist * 0.1 - ] + [ - i - for i in range(128, 256, 32) - if i <= model_ivf.nlist * 0.1 - ] + [ - i - for i in range(256, 512, 64) - if i <= model_ivf.nlist * 0.1 - ] + [ - 2**i - for i in range(9, 12) - if 2**i <= model_ivf.nlist * 0.1 - ], ) model = faiss.downcast_index(model) if isinstance(model, faiss.IndexRefine): @@ -718,7 +752,9 @@ def add_range_or_val(name, range): "efSearch", [2**i for i in range(3, 11)], ) - elif isinstance(model, faiss.IndexResidualQuantizer) or isinstance(model, faiss.IndexProductResidualQuantizer): + elif isinstance(model, faiss.IndexResidualQuantizer) or isinstance( + model, faiss.IndexProductResidualQuantizer + ): add_range_or_val( "max_beam_size", [1, 2, 4, 8, 16, 32], @@ -727,7 +763,9 @@ def add_range_or_val(name, range): "use_beam_LUT", [1], ) - elif isinstance(model, faiss.IndexLocalSearchQuantizer) or isinstance(model, faiss.IndexProductLocalSearchQuantizer): + elif isinstance(model, faiss.IndexLocalSearchQuantizer) or isinstance( + model, faiss.IndexProductLocalSearchQuantizer + ): add_range_or_val( "encode_ils_iters", [2, 4, 8, 16], @@ -854,7 +892,9 @@ def fetch_meta(self, dry_run=False): def fetch_codec(self, dry_run=False): codec_filename = self.get_codec_name() + "codec" meta_filename = self.get_codec_name() + "json" - if self.io.file_exist(codec_filename) and self.io.file_exist(meta_filename): + if self.io.file_exist(codec_filename) and self.io.file_exist( + meta_filename + ): codec = self.io.read_index(codec_filename) assert self.d == codec.d assert self.metric_type == codec.metric_type @@ -874,6 +914,7 @@ def fetch_codec(self, dry_run=False): "training_size": self.training_vectors.num_vectors, "codec_size": codec_size, "sa_code_size": self.get_sa_code_size(codec), + "code_size": self.get_code_size(codec), "cpu": get_cpu_info(), } self.io.write_json(meta, meta_filename, overwrite=True) @@ -921,7 +962,9 @@ def get_quantizer(self, dry_run, pretransform=None): training_vectors = self.training_vectors else: training_vectors = pretransform.transform(self.training_vectors) - centroids, t, requires = training_vectors.k_means(self.io, model_ivf.nlist, dry_run) + centroids, t, requires = training_vectors.k_means( + self.io, model_ivf.nlist, dry_run + ) if requires is not None: return None, None, requires quantizer = IndexFromFactory( @@ -944,11 +987,11 @@ def assemble(self, dry_run): model = self.get_model() opaque = True t_aggregate = 0 - try: - reverse_index_factory(model) - opaque = False - except NotImplementedError: - opaque = True + # try: + # reverse_index_factory(model) + # opaque = False + # except NotImplementedError: + # opaque = True if opaque: codec = model else: @@ -958,7 +1001,9 @@ def assemble(self, dry_run): if not isinstance(sub_index, faiss.IndexFlat): # replace the sub-index with Flat and fetch pre-trained pretransform = self.get_pretransform() - codec, meta, report = pretransform.fetch_codec(dry_run=dry_run) + codec, meta, report = pretransform.fetch_codec( + dry_run=dry_run + ) if report is not None: return None, None, report t_aggregate += meta["training_time"] @@ -978,7 +1023,9 @@ def assemble(self, dry_run): training_vectors=transformed_training_vectors, ) wrapper.set_io(self.io) - codec.index, meta, report = wrapper.fetch_codec(dry_run=dry_run) + codec.index, meta, report = wrapper.fetch_codec( + dry_run=dry_run + ) if report is not None: return None, None, report t_aggregate += meta["training_time"] @@ -1008,14 +1055,18 @@ def assemble(self, dry_run): d=model.base_index.d, metric=model.base_index.metric_type, database_vectors=self.database_vectors, - construction_params=IndexBase.filter_index_param_dict_list(self.construction_params), + construction_params=IndexBase.filter_index_param_dict_list( + self.construction_params + ), search_params=None, factory=reverse_index_factory(model.base_index), training_vectors=self.training_vectors, ) wrapper.set_io(self.io) codec = faiss.clone_index(model) - codec.base_index, meta, requires = wrapper.fetch_codec(dry_run=dry_run) + codec.base_index, meta, requires = wrapper.fetch_codec( + dry_run=dry_run + ) if requires is not None: return None, None, requires t_aggregate += meta["training_time"] diff --git a/benchs/bench_fw/optimize.py b/benchs/bench_fw/optimize.py new file mode 100644 index 0000000000..473436ea68 --- /dev/null +++ b/benchs/bench_fw/optimize.py @@ -0,0 +1,333 @@ +# 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 logging +from dataclasses import dataclass +from typing import Dict, List, Tuple + +import faiss # @manual=//faiss/python:pyfaiss_gpu + +# from faiss.contrib.evaluation import ( # @manual=//faiss/contrib:faiss_contrib_gpu +# OperatingPoints, +# ) + +from .benchmark import Benchmark +from .descriptors import DatasetDescriptor, IndexDescriptor +from .utils import dict_merge, filter_results, ParetoMetric, ParetoMode + +logger = logging.getLogger(__name__) + + +@dataclass +class Optimizer: + distance_metric: str = "L2" + num_threads: int = 32 + run_local: bool = True + + def __post_init__(self): + self.cached_benchmark = None + if self.distance_metric == "IP": + self.distance_metric_type = faiss.METRIC_INNER_PRODUCT + elif self.distance_metric == "L2": + self.distance_metric_type = faiss.METRIC_L2 + else: + raise ValueError + + def set_io(self, benchmark_io): + self.io = benchmark_io + self.io.distance_metric = self.distance_metric + self.io.distance_metric_type = self.distance_metric_type + + def benchmark_and_filter_candidates( + self, + index_descs, + training_vectors, + database_vectors, + query_vectors, + result_file, + include_flat, + min_accuracy, + pareto_metric, + ): + benchmark = Benchmark( + num_threads=self.num_threads, + training_vectors=training_vectors, + database_vectors=database_vectors, + query_vectors=query_vectors, + index_descs=index_descs, + k=10, + distance_metric=self.distance_metric, + ) + benchmark.set_io(self.io) + results = benchmark.benchmark( + result_file=result_file, local=self.run_local, train=True, knn=True + ) + assert results + filtered = filter_results( + results=results, + evaluation="knn", + accuracy_metric="knn_intersection", + min_accuracy=min_accuracy, + name_filter=None + if include_flat + else (lambda n: not n.startswith("Flat")), + pareto_mode=ParetoMode.GLOBAL, + pareto_metric=pareto_metric, + ) + assert filtered + index_descs = [ + IndexDescriptor( + factory=v["factory"], + construction_params=v["construction_params"], + search_params=v["search_params"], + ) + for _, _, _, _, v in filtered + ] + return index_descs, filtered + + def optimize_quantizer( + self, + training_vectors: DatasetDescriptor, + query_vectors: DatasetDescriptor, + nlists: List[int], + min_accuracy: float, + ): + quantizer_descs = {} + for nlist in nlists: + # cluster + centroids, _, _ = training_vectors.k_means( + self.io, + nlist, + dry_run=False, + ) + + descs = [IndexDescriptor(factory="Flat"),] + [ + IndexDescriptor( + factory="HNSW32", + construction_params=[{"efConstruction": 2**i}], + ) + for i in range(6, 11) + ] + + descs, _ = self.benchmark_and_filter_candidates( + descs, + training_vectors=centroids, + database_vectors=centroids, + query_vectors=query_vectors, + result_file=f"result_{centroids.get_filename()}json", + include_flat=True, + min_accuracy=min_accuracy, + pareto_metric=ParetoMetric.TIME, + ) + quantizer_descs[nlist] = descs + + return quantizer_descs + + def optimize_ivf( + self, + result_file: str, + training_vectors: DatasetDescriptor, + database_vectors: DatasetDescriptor, + query_vectors: DatasetDescriptor, + quantizers: Dict[int, List[IndexDescriptor]], + codecs: List[Tuple[str, str]], + min_accuracy: float, + ): + ivf_descs = [] + for nlist, quantizer_descs in quantizers.items(): + # build IVF index + for quantizer_desc in quantizer_descs: + for pretransform, fine_ivf in codecs: + if pretransform is None: + pretransform = "" + else: + pretransform = pretransform + "," + if quantizer_desc.construction_params is None: + construction_params = [ + None, + quantizer_desc.search_params, + ] + else: + construction_params = [ + None + ] + quantizer_desc.construction_params + if quantizer_desc.search_params is not None: + dict_merge( + construction_params[1], + quantizer_desc.search_params, + ) + ivf_descs.append( + IndexDescriptor( + factory=f"{pretransform}IVF{nlist}({quantizer_desc.factory}),{fine_ivf}", + construction_params=construction_params, + ) + ) + return self.benchmark_and_filter_candidates( + ivf_descs, + training_vectors, + database_vectors, + query_vectors, + result_file, + include_flat=False, + min_accuracy=min_accuracy, + pareto_metric=ParetoMetric.TIME_SPACE, + ) + + # train an IVFFlat index + # find the nprobe required for the given accuracy + def ivf_flat_nprobe_required_for_accuracy( + self, + result_file: str, + training_vectors: DatasetDescriptor, + database_vectors: DatasetDescriptor, + query_vectors: DatasetDescriptor, + nlist, + accuracy, + ): + _, results = self.benchmark_and_filter_candidates( + index_descs=[ + IndexDescriptor(factory=f"IVF{nlist}(Flat),Flat"), + ], + training_vectors=training_vectors, + database_vectors=database_vectors, + query_vectors=query_vectors, + result_file=result_file, + include_flat=False, + min_accuracy=accuracy, + pareto_metric=ParetoMetric.TIME, + ) + nprobe = nlist // 2 + for _, _, _, k, v in results: + if ( + ".knn" in k + and "nprobe" in v["search_params"] + and v["knn_intersection"] >= accuracy + ): + nprobe = min(nprobe, v["search_params"]["nprobe"]) + return nprobe + + # train candidate IVF codecs + # benchmark them at the same nprobe + # keep only the space _and_ time Pareto optimal + def optimize_codec( + self, + result_file: str, + d: int, + training_vectors: DatasetDescriptor, + database_vectors: DatasetDescriptor, + query_vectors: DatasetDescriptor, + nlist: int, + nprobe: int, + min_accuracy: float, + ): + codecs = ( + [ + (None, "Flat"), + (None, "SQfp16"), + (None, "SQ8"), + ] + [ + (f"OPQ{M}_{M * dim}", f"PQ{M}x{b}") + for M in [8, 12, 16, 32, 48, 64, 96, 128, 192, 256] + if d % M == 0 + for dim in range(2, 18, 2) + if M * dim <= d + for b in range(4, 14, 2) + if M * b < d * 8 # smaller than SQ8 + ] + [ + (None, f"PQ{M}x{b}") + for M in [8, 12, 16, 32, 48, 64, 96, 128, 192, 256] + if d % M == 0 + for b in range(8, 14, 2) + if M * b < d * 8 # smaller than SQ8 + ] + ) + factory = {} + for opq, pq in codecs: + factory[ + f"IVF{nlist},{pq}" if opq is None else f"{opq},IVF{nlist},{pq}" + ] = ( + opq, + pq, + ) + + _, filtered = self.benchmark_and_filter_candidates( + index_descs=[ + IndexDescriptor( + factory=f"IVF{nlist},{pq}" + if opq is None + else f"{opq},IVF{nlist},{pq}", + search_params={ + "nprobe": nprobe, + }, + ) + for opq, pq in codecs + ], + training_vectors=training_vectors, + database_vectors=database_vectors, + query_vectors=query_vectors, + result_file=result_file, + include_flat=False, + min_accuracy=min_accuracy, + pareto_metric=ParetoMetric.TIME_SPACE, + ) + results = [ + factory[r] for r in set(v["factory"] for _, _, _, k, v in filtered) + ] + return results + + def optimize( + self, + d: int, + training_vectors: DatasetDescriptor, + database_vectors_list: List[DatasetDescriptor], + query_vectors: DatasetDescriptor, + min_accuracy: float, + ): + # train an IVFFlat index + # find the nprobe required for near perfect accuracy + nlist = 4096 + nprobe_at_95 = self.ivf_flat_nprobe_required_for_accuracy( + result_file=f"result_ivf{nlist}_flat.json", + training_vectors=training_vectors, + database_vectors=database_vectors_list[0], + query_vectors=query_vectors, + nlist=nlist, + accuracy=0.95, + ) + + # train candidate IVF codecs + # benchmark them at the same nprobe + # keep only the space and time Pareto optima + codecs = self.optimize_codec( + result_file=f"result_ivf{nlist}_codec.json", + d=d, + training_vectors=training_vectors, + database_vectors=database_vectors_list[0], + query_vectors=query_vectors, + nlist=nlist, + nprobe=nprobe_at_95, + min_accuracy=min_accuracy, + ) + + # optimize coarse quantizers + quantizers = self.optimize_quantizer( + training_vectors=training_vectors, + query_vectors=query_vectors, + nlists=[4096, 8192, 16384, 32768], + min_accuracy=0.7, + ) + + # combine them with the codecs + # test them at different scales + for database_vectors in database_vectors_list: + self.optimize_ivf( + result_file=f"result_{database_vectors.get_filename()}json", + training_vectors=training_vectors, + database_vectors=database_vectors, + query_vectors=query_vectors, + quantizers=quantizers, + codecs=codecs, + min_accuracy=min_accuracy, + ) diff --git a/benchs/bench_fw/utils.py b/benchs/bench_fw/utils.py index e1e513169b..3151c0c2da 100644 --- a/benchs/bench_fw/utils.py +++ b/benchs/bench_fw/utils.py @@ -3,15 +3,22 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from time import perf_counter +import functools import logging +from enum import Enum from multiprocessing.pool import ThreadPool -import numpy as np +from time import perf_counter + import faiss # @manual=//faiss/python:pyfaiss_gpu -import functools +import numpy as np + +from faiss.contrib.evaluation import ( # @manual=//faiss/contrib:faiss_contrib_gpu + OperatingPoints, +) logger = logging.getLogger(__name__) + def timer(name, func, once=False) -> float: logger.info(f"Measuring {name}") t1 = perf_counter() @@ -34,28 +41,41 @@ def timer(name, func, once=False) -> float: def refine_distances_knn( - xq: np.ndarray, xb: np.ndarray, I: np.ndarray, metric, + xq: np.ndarray, + xb: np.ndarray, + I: np.ndarray, + metric, ): - """ Recompute distances between xq[i] and xb[I[i, :]] """ + """Recompute distances between xq[i] and xb[I[i, :]]""" nq, k = I.shape - xq = np.ascontiguousarray(xq, dtype='float32') + xq = np.ascontiguousarray(xq, dtype="float32") nq2, d = xq.shape - xb = np.ascontiguousarray(xb, dtype='float32') + xb = np.ascontiguousarray(xb, dtype="float32") nb, d2 = xb.shape - I = np.ascontiguousarray(I, dtype='int64') + I = np.ascontiguousarray(I, dtype="int64") assert nq2 == nq assert d2 == d - D = np.empty(I.shape, dtype='float32') + D = np.empty(I.shape, dtype="float32") D[:] = np.inf if metric == faiss.METRIC_L2: faiss.fvec_L2sqr_by_idx( - faiss.swig_ptr(D), faiss.swig_ptr(xq), faiss.swig_ptr(xb), - faiss.swig_ptr(I), d, nq, k + faiss.swig_ptr(D), + faiss.swig_ptr(xq), + faiss.swig_ptr(xb), + faiss.swig_ptr(I), + d, + nq, + k, ) else: faiss.fvec_inner_products_by_idx( - faiss.swig_ptr(D), faiss.swig_ptr(xq), faiss.swig_ptr(xb), - faiss.swig_ptr(I), d, nq, k + faiss.swig_ptr(D), + faiss.swig_ptr(xq), + faiss.swig_ptr(xb), + faiss.swig_ptr(I), + d, + nq, + k, ) return D @@ -97,7 +117,10 @@ def distance_ratio_measure(I, R, D_GT, metric): @functools.cache def get_cpu_info(): - return [l for l in open("/proc/cpuinfo", "r") if "model name" in l][0][13:].strip() + return [l for l in open("/proc/cpuinfo", "r") if "model name" in l][0][ + 13: + ].strip() + def dict_merge(target, source): for k, v in source.items(): @@ -105,3 +128,121 @@ def dict_merge(target, source): dict_merge(target[k], v) else: target[k] = v + + +class Cost: + def __init__(self, values): + self.values = values + + def __le__(self, other): + return all( + v1 <= v2 for v1, v2 in zip(self.values, other.values, strict=True) + ) + + def __lt__(self, other): + return all( + v1 < v2 for v1, v2 in zip(self.values, other.values, strict=True) + ) + + +class ParetoMode(Enum): + DISABLE = 1 # no Pareto filtering + INDEX = 2 # index-local optima + GLOBAL = 3 # global optima + + +class ParetoMetric(Enum): + TIME = 0 # time vs accuracy + SPACE = 1 # space vs accuracy + TIME_SPACE = 2 # (time, space) vs accuracy + + +def range_search_recall_at_precision(experiment, precision): + return round( + max( + r + for r, p in zip( + experiment["range_search_pr"]["recall"], + experiment["range_search_pr"]["precision"], + ) + if p > precision + ), + 6, + ) + + +def filter_results( + results, + evaluation, + accuracy_metric, # str or func + time_metric=None, # func or None -> use default + space_metric=None, # func or None -> use default + min_accuracy=0, + max_space=0, + max_time=0, + scaling_factor=1.0, + name_filter=None, # func + pareto_mode=ParetoMode.DISABLE, + pareto_metric=ParetoMetric.TIME, +): + if isinstance(accuracy_metric, str): + accuracy_key = accuracy_metric + accuracy_metric = lambda v: v[accuracy_key] + + if time_metric is None: + time_metric = lambda v: v["time"] * scaling_factor + ( + v["quantizer"]["time"] if "quantizer" in v else 0 + ) + + if space_metric is None: + space_metric = lambda v: results["indices"][v["codec"]]["code_size"] + + fe = [] + ops = {} + if pareto_mode == ParetoMode.GLOBAL: + op = OperatingPoints() + ops["global"] = op + for k, v in results["experiments"].items(): + if f".{evaluation}" in k: + accuracy = accuracy_metric(v) + if min_accuracy > 0 and accuracy < min_accuracy: + continue + space = space_metric(v) + if space is None: + space = 0 + if max_space > 0 and space > max_space: + continue + time = time_metric(v) + if max_time > 0 and time > max_time: + continue + idx_name = v["index"] + ( + "snap" + if "search_params" in v and v["search_params"]["snap"] == 1 + else "" + ) + if name_filter is not None and not name_filter(idx_name): + continue + experiment = (accuracy, space, time, k, v) + if pareto_mode == ParetoMode.DISABLE: + fe.append(experiment) + continue + if pareto_mode == ParetoMode.INDEX: + if idx_name not in ops: + ops[idx_name] = OperatingPoints() + op = ops[idx_name] + if pareto_metric == ParetoMetric.TIME: + op.add_operating_point(experiment, accuracy, time) + elif pareto_metric == ParetoMetric.SPACE: + op.add_operating_point(experiment, accuracy, space) + else: + op.add_operating_point( + experiment, accuracy, Cost([time, space]) + ) + + if ops: + for op in ops.values(): + for v, _, _ in op.operating_points: + fe.append(v) + + fe.sort() + return fe diff --git a/benchs/bench_fw_notebook.ipynb b/benchs/bench_fw_notebook.ipynb index c6183a8eb9..5752aaf5fb 100644 --- a/benchs/bench_fw_notebook.ipynb +++ b/benchs/bench_fw_notebook.ipynb @@ -1,617 +1,529 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "be081589-e1b2-4569-acb7-44203e273899", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import itertools\n", - "from faiss.contrib.evaluation import OperatingPoints\n", - "from enum import Enum\n", - "from bench_fw.benchmark_io import BenchmarkIO as BIO\n", - "from copy import copy\n", - "import numpy as np\n", - "import datetime\n", - "import glob\n", - "import io\n", - "import json\n", - "from zipfile import ZipFile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6492e95-24c7-4425-bf0a-27e10e879ca6", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "root = \"/checkpoint/gsz/bench_fw/range/ssnpp\"\n", - "results = BIO(root).read_json(\"result.json\")\n", - "results.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0875d269-aef4-426d-83dd-866970f43777", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "results['experiments']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a7ff7078-29c7-407c-a079-201877b764ad", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "class Cost:\n", - " def __init__(self, values):\n", - " self.values = values\n", - "\n", - " def __le__(self, other):\n", - " return all(v1 <= v2 for v1, v2 in zip(self.values, other.values, strict=True))\n", - "\n", - " def __lt__(self, other):\n", - " return all(v1 < v2 for v1, v2 in zip(self.values, other.values, strict=True))\n", - "\n", - "class ParetoMode(Enum):\n", - " DISABLE = 1 # no Pareto filtering\n", - " INDEX = 2 # index-local optima\n", - " GLOBAL = 3 # global optima\n", - "\n", - "\n", - "class ParetoMetric(Enum):\n", - " TIME = 0 # time vs accuracy\n", - " SPACE = 1 # space vs accuracy\n", - " TIME_SPACE = 2 # (time, space) vs accuracy\n", - "\n", - "def range_search_recall_at_precision(experiment, precision):\n", - " return round(max(r for r, p in zip(experiment['range_search_pr']['recall'], experiment['range_search_pr']['precision']) if p > precision), 6)\n", - "\n", - "def filter_results(\n", - " results,\n", - " evaluation,\n", - " accuracy_metric, # str or func\n", - " time_metric=None, # func or None -> use default\n", - " space_metric=None, # func or None -> use default\n", - " min_accuracy=0,\n", - " max_space=0,\n", - " max_time=0,\n", - " scaling_factor=1.0,\n", - " \n", - " pareto_mode=ParetoMode.DISABLE,\n", - " pareto_metric=ParetoMetric.TIME,\n", - "):\n", - " if isinstance(accuracy_metric, str):\n", - " accuracy_key = accuracy_metric\n", - " accuracy_metric = lambda v: v[accuracy_key]\n", - "\n", - " if time_metric is None:\n", - " time_metric = lambda v: v['time'] * scaling_factor + (v['quantizer']['time'] if 'quantizer' in v else 0)\n", - "\n", - " if space_metric is None:\n", - " space_metric = lambda v: results['indices'][v['codec']]['sa_code_size']\n", - " \n", - " fe = []\n", - " ops = {}\n", - " if pareto_mode == ParetoMode.GLOBAL:\n", - " op = OperatingPoints()\n", - " ops[\"global\"] = op\n", - " for k, v in results['experiments'].items():\n", - " if f\".{evaluation}\" in k:\n", - " accuracy = accuracy_metric(v)\n", - " if min_accuracy > 0 and accuracy < min_accuracy:\n", - " continue\n", - " space = space_metric(v)\n", - " if space is None:\n", - " space = 0 \n", - " if max_space > 0 and space > max_space:\n", - " continue\n", - " time = time_metric(v)\n", - " if max_time > 0 and time > max_time:\n", - " continue\n", - " idx_name = v['index'] + (\"snap\" if 'search_params' in v and v['search_params'][\"snap\"] == 1 else \"\")\n", - " # if idx_name.startswith(\"HNSW\"):\n", - " # continue\n", - " experiment = (accuracy, space, time, k, v)\n", - " if pareto_mode == ParetoMode.DISABLE:\n", - " fe.append(experiment)\n", - " continue\n", - " if pareto_mode == ParetoMode.INDEX:\n", - " if idx_name not in ops:\n", - " ops[idx_name] = OperatingPoints()\n", - " op = ops[idx_name]\n", - " if pareto_metric == ParetoMetric.TIME:\n", - " op.add_operating_point(experiment, accuracy, time)\n", - " elif pareto_metric == ParetoMetric.SPACE:\n", - " op.add_operating_point(experiment, accuracy, space)\n", - " else:\n", - " op.add_operating_point(experiment, accuracy, Cost([time, space]))\n", - "\n", - " if ops:\n", - " for op in ops.values():\n", - " for v, _, _ in op.operating_points:\n", - " fe.append(v)\n", - "\n", - " fe.sort()\n", - " return fe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f080a6e2-1565-418b-8732-4adeff03a099", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def plot_metric(experiments, accuracy_title, cost_title, plot_space=False, plot=None):\n", - " if plot is None:\n", - " plot = plt.subplot()\n", - " x = {}\n", - " y = {}\n", - " for accuracy, space, time, k, v in experiments:\n", - " idx_name = v['index'] + (\"snap\" if 'search_params' in v and v['search_params'][\"snap\"] == 1 else \"\")\n", - " if idx_name not in x:\n", - " x[idx_name] = []\n", - " y[idx_name] = []\n", - " x[idx_name].append(accuracy)\n", - " if plot_space:\n", - " y[idx_name].append(space)\n", - " else:\n", - " y[idx_name].append(time)\n", - "\n", - " #plt.figure(figsize=(10,6))\n", - " #plt.title(accuracy_title)\n", - " plot.set_xlabel(accuracy_title)\n", - " plot.set_ylabel(cost_title)\n", - " marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", - " for index in x.keys():\n", - " plot.plot(x[index], y[index], marker=next(marker), label=index, linewidth=0)\n", - " plot.legend(bbox_to_anchor=(1, 1), loc='upper left')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61007155-5edc-449e-835e-c141a01a2ae5", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# index local optima\n", - "accuracy_metric = \"knn_intersection\"\n", - "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\", plot_space=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f9f94dcc-5abe-4cad-9619-f5d1d24fb8c1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# global optima\n", - "accuracy_metric = \"knn_intersection\"\n", - "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.5, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36e82084-18f6-4546-a717-163eb0224ee8", - "metadata": {}, - "outputs": [], - "source": [ - "# index local optima @ precision 0.8\n", - "precision = 0.8\n", - "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", - "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aff79376-39f7-47c0-8b83-1efe5192bb7e", - "metadata": {}, - "outputs": [], - "source": [ - "# index local optima @ precision 0.2\n", - "precision = 0.2\n", - "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", - "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b4834f1f-bbbe-4cae-9aa0-a459b0c842d1", - "metadata": {}, - "outputs": [], - "source": [ - "# global optima @ precision 0.8\n", - "precision = 0.8\n", - "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", - "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9aead830-6209-4956-b7ea-4a5e0029d616", - "metadata": {}, - "outputs": [], - "source": [ - "def plot_range_search_pr_curves(experiments):\n", - " x = {}\n", - " y = {}\n", - " show = {\n", - " 'Flat': None,\n", - " }\n", - " for _, _, _, k, v in fr:\n", - " if \".weighted\" in k: # and v['index'] in show:\n", - " x[k] = v['range_search_pr']['recall']\n", - " y[k] = v['range_search_pr']['precision']\n", - " \n", - " plt.title(\"range search recall\")\n", - " plt.xlabel(\"recall\")\n", - " plt.ylabel(\"precision\")\n", - " for index in x.keys():\n", - " plt.plot(x[index], y[index], '.', label=index)\n", - " plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper left')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92e45502-7a31-4a15-90df-fa3032d7d350", - "metadata": {}, - "outputs": [], - "source": [ - "precision = 0.8\n", - "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", - "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME_SPACE, scaling_factor=1)\n", - "plot_range_search_pr_curves(fr)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fdf8148a-0da6-4c5e-8d60-f8f85314574c", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", - "scales = [1, 2, 5, 10, 20, 50]\n", - "fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", - "fig.tight_layout()\n", - "for plot, scale in zip(plots, scales, strict=True):\n", - " results = BIO(root).read_json(f\"result{scale}.json\")\n", - " accuracy_metric = \"knn_intersection\"\n", - " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - " plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e503828c-ee61-45f7-814b-cce6461109bc", - "metadata": {}, - "outputs": [], - "source": [ - "x = {}\n", - "y = {}\n", - "accuracy=0.9\n", - "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", - "scales = [1, 2, 5, 10, 20, 50]\n", - "#fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", - "#fig.tight_layout()\n", - "for scale in scales:\n", - " results = BIO(root).read_json(f\"result{scale}.json\")\n", - " scale *= 1_000_000\n", - " accuracy_metric = \"knn_intersection\"\n", - " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=accuracy, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - " seen = set()\n", - " print(scale)\n", - " for _, _, _, _, exp in fr:\n", - " fact = exp[\"factory\"]\n", - " # \"HNSW\" in fact or \n", - " if fact in seen or fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", - " continue\n", - " seen.add(fact)\n", - " if fact not in x:\n", - " x[fact] = []\n", - " y[fact] = []\n", - " x[fact].append(scale)\n", - " y[fact].append(exp[\"time\"] + exp[\"quantizer\"][\"time\"])\n", - " if (exp[\"knn_intersection\"] > 0.92):\n", - " print(fact)\n", - " print(exp[\"search_params\"])\n", - " print(exp[\"knn_intersection\"])\n", - "\n", - " #plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)\n", - " \n", - "plt.title(f\"recall @ 1 = {accuracy*100}%\")\n", - "plt.xlabel(\"database size\")\n", - "plt.ylabel(\"time\")\n", - "plt.xscale(\"log\")\n", - "plt.yscale(\"log\")\n", - "\n", - "marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", - "for index in x.keys():\n", - " if \"HNSW\" in index:\n", - " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker), linestyle=\"dashed\")\n", - " else:\n", - " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker))\n", - "plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper left')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "37a99bb2-f998-461b-a345-7cc6e702cb3a", - "metadata": {}, - "outputs": [], - "source": [ - "# global optima\n", - "accuracy_metric = \"sym_recall\"\n", - "fr = filter_results(results, evaluation=\"rec\", accuracy_metric=accuracy_metric, time_metric=lambda e:e['encode_time'], min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.SPACE, scaling_factor=1)\n", - "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"space\", plot_space=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c973ce4e-3566-4f02-bd93-f113e3e0c791", - "metadata": {}, - "outputs": [], - "source": [ - "def pretty_time(s):\n", - " if s is None:\n", - " return \"None\"\n", - " s = int(s * 1000) / 1000\n", - " m, s = divmod(s, 60)\n", - " h, m = divmod(m, 60)\n", - " d, h = divmod(h, 24)\n", - " r = \"\"\n", - " if d > 0:\n", - " r += f\"{int(d)}d \"\n", - " if h > 0:\n", - " r += f\"{int(h)}h \"\n", - " if m > 0:\n", - " r += f\"{int(m)}m \"\n", - " if s > 0 or len(r) == 0:\n", - " r += f\"{s:.3f}s\"\n", - " return r\n", - "\n", - "def pretty_size(s):\n", - " if s > 1024 * 1024:\n", - " return f\"{s / 1024 / 1024:.1f}\".rstrip('0').rstrip('.') + \"MB\"\n", - " if s > 1024:\n", - " return f\"{s / 1024:.1f}\".rstrip('0').rstrip('.') + \"KB\"\n", - " return f\"{s}\"\n", - "\n", - "def pretty_mse(m):\n", - " if m is None:\n", - " return \"None\"\n", - " else:\n", - " return f\"{m:.6f}\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ddcf226-fb97-4a59-9fc3-3ed8f7d5e703", - "metadata": {}, - "outputs": [], - "source": [ - "data = {}\n", - "root = \"/checkpoint/gsz/bench_fw/bigann\"\n", - "scales = [1, 2, 5, 10, 20, 50]\n", - "for scale in scales:\n", - " results = BIO(root).read_json(f\"result{scale}.json\")\n", - " accuracy_metric = \"knn_intersection\"\n", - " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", - " d = {}\n", - " data[f\"{scale}M\"] = d\n", - " for _, _, _, _, exp in fr:\n", - " fact = exp[\"factory\"]\n", - " # \"HNSW\" in fact or \n", - " if fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", - " continue\n", - " if fact not in d:\n", - " d[fact] = []\n", - " d[fact].append({\n", - " \"nprobe\": exp[\"search_params\"][\"nprobe\"],\n", - " \"recall\": exp[\"knn_intersection\"],\n", - " \"time\": exp[\"time\"] + exp[\"quantizer\"][\"time\"],\n", - " })\n", - "data\n", - "# with open(\"/checkpoint/gsz/bench_fw/codecs.json\", \"w\") as f:\n", - "# json.dump(data, f)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e54eebb6-0a9f-4a72-84d2-f12c5bd44510", - "metadata": {}, - "outputs": [], - "source": [ - "ds = \"deep1b\"\n", - "data = []\n", - "jss = []\n", - "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", - "results = BIO(root).read_json(f\"result.json\")\n", - "for k, e in results[\"experiments\"].items():\n", - " if \"rec\" in k and e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", - " code_size = results['indices'][e['codec']]['sa_code_size']\n", - " codec_size = results['indices'][e['codec']]['codec_size']\n", - " training_time = results['indices'][e['codec']]['training_time']\n", - " # training_size = results['indices'][e['codec']]['training_size']\n", - " cpu = e['cpu'] if 'cpu' in e else \"\"\n", - " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", - " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", - " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{training_size}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", - " jss.append({\n", - " 'factory': e['factory'],\n", - " 'parameters': e['construction_params'][0] if e['construction_params'] else \"\",\n", - " 'evaluation_params': e['reconstruct_params'],\n", - " 'code_size': code_size,\n", - " 'codec_size': codec_size,\n", - " 'training_time': training_time,\n", - " 'training_size': training_size,\n", - " 'mse': e['mse'],\n", - " 'sym_recall': e['sym_recall'],\n", - " 'asym_recall': e['asym_recall'],\n", - " 'encode_time': e['encode_time'],\n", - " 'decode_time': e['decode_time'],\n", - " 'cpu': cpu,\n", - " })\n", - "\n", - "print(\"|factory key|construction parameters|evaluation parameters|code size|codec size|training time|training size|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", - "print(\"|-|-|-|-|-|-|-|-|-|\")\n", - "data.sort()\n", - "for d in data:\n", - " print(d[1])\n", - "\n", - "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_test.json\", \"w\") as f:\n", - " json.dump(jss, f)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d1216733-9670-407c-b3d2-5f87bce0321c", - "metadata": {}, - "outputs": [], - "source": [ - "def read_file(filename: str, keys):\n", - " results = []\n", - " with ZipFile(filename, \"r\") as zip_file:\n", - " for key in keys:\n", - " with zip_file.open(key, \"r\") as f:\n", - " if key in [\"D\", \"I\", \"R\", \"lims\"]:\n", - " results.append(np.load(f))\n", - " elif key in [\"P\"]:\n", - " t = io.TextIOWrapper(f)\n", - " results.append(json.load(t))\n", - " else:\n", - " raise AssertionError()\n", - " return results" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56de051e-22db-4bef-b242-1ddabc9e0bb9", - "metadata": {}, - "outputs": [], - "source": [ - "ds = \"contriever\"\n", - "data = []\n", - "jss = []\n", - "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", - "for lf in glob.glob(root + '/*rec*.zip'):\n", - " e, = read_file(lf, ['P'])\n", - " if e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", - " code_size = e['codec_meta']['sa_code_size']\n", - " codec_size = e['codec_meta']['codec_size']\n", - " training_time = e['codec_meta']['training_time']\n", - " training_size = None # e['codec_meta']['training_size']\n", - " cpu = e['cpu'] if 'cpu' in e else \"\"\n", - " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", - " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", - " if eps in ps and eps != \"encode_ils_iters=16\" and eps != \"max_beam_size=32\":\n", - " eps = \" \"\n", - " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", - " eps = e['reconstruct_params']\n", - " del eps['snap']\n", - " params = copy(e['construction_params'][0]) if e['construction_params'] else {}\n", - " for k, v in e['reconstruct_params'].items():\n", - " params[k] = v\n", - " jss.append({\n", - " 'factory': e['factory'],\n", - " 'params': params,\n", - " 'construction_params': e['construction_params'][0] if e['construction_params'] else {},\n", - " 'evaluation_params': e['reconstruct_params'],\n", - " 'code_size': code_size,\n", - " 'codec_size': codec_size,\n", - " 'training_time': training_time,\n", - " # 'training_size': training_size,\n", - " 'mse': e['mse'],\n", - " 'sym_recall': e['sym_recall'],\n", - " 'asym_recall': e['asym_recall'],\n", - " 'encode_time': e['encode_time'],\n", - " 'decode_time': e['decode_time'],\n", - " 'cpu': cpu,\n", - " })\n", - "\n", - "print(\"|factory key|construction parameters|encode/decode parameters|code size|codec size|training time|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", - "print(\"|-|-|-|-|-|-|-|-|-|\")\n", - "data.sort()\n", - "# for d in data:\n", - "# print(d[1])\n", - "\n", - "print(len(data))\n", - "\n", - "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_5.json\", \"w\") as f:\n", - " json.dump(jss, f)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2fd712bf-f147-4c1b-9dbf-b04428e4c1eb", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python [conda env:.conda-faiss_from_source] *", - "language": "python", - "name": "conda-env-.conda-faiss_from_source-py" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "be081589-e1b2-4569-acb7-44203e273899", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import itertools\n", + "from faiss.contrib.evaluation import OperatingPoints\n", + "from enum import Enum\n", + "from bench_fw.benchmark_io import BenchmarkIO as BIO\n", + "from bench_fw.utils import filter_results, ParetoMode, ParetoMetric\n", + "from copy import copy\n", + "import numpy as np\n", + "import datetime\n", + "import glob\n", + "import io\n", + "import json\n", + "from zipfile import ZipFile\n", + "import tabulate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6492e95-24c7-4425-bf0a-27e10e879ca6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "root = \"/checkpoint/gsz/bench_fw/optimize/bigann\"\n", + "results = BIO(root).read_json(\"result_std_d_bigann10M.json\")\n", + "results.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0875d269-aef4-426d-83dd-866970f43777", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "results['experiments']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f080a6e2-1565-418b-8732-4adeff03a099", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def plot_metric(experiments, accuracy_title, cost_title, plot_space=False, plot=None):\n", + " if plot is None:\n", + " plot = plt.subplot()\n", + " x = {}\n", + " y = {}\n", + " for accuracy, space, time, k, v in experiments:\n", + " idx_name = v['index'] + (\"snap\" if 'search_params' in v and v['search_params'][\"snap\"] == 1 else \"\")\n", + " if idx_name not in x:\n", + " x[idx_name] = []\n", + " y[idx_name] = []\n", + " x[idx_name].append(accuracy)\n", + " if plot_space:\n", + " y[idx_name].append(space)\n", + " else:\n", + " y[idx_name].append(time)\n", + "\n", + " #plt.figure(figsize=(10,6))\n", + " #plt.title(accuracy_title)\n", + " plot.set_xlabel(accuracy_title)\n", + " plot.set_ylabel(cost_title)\n", + " plot.set_yscale(\"log\")\n", + " marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", + " for index in x.keys():\n", + " plot.plot(x[index], y[index], marker=next(marker), label=index, linewidth=0)\n", + " plot.legend(bbox_to_anchor=(1, 1), loc='upper left')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61007155-5edc-449e-835e-c141a01a2ae5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# index local optima\n", + "accuracy_metric = \"knn_intersection\"\n", + "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1, min_accuracy=0.95)\n", + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\", plot_space=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9f94dcc-5abe-4cad-9619-f5d1d24fb8c1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# global optima\n", + "accuracy_metric = \"knn_intersection\"\n", + "fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.90, max_space=64, max_time=0, name_filter=lambda n: not n.startswith(\"Flat\"), pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 32 cores)\", plot_space=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c10f587-26ef-49ec-83a9-88f6a2a433e8", + "metadata": {}, + "outputs": [], + "source": [ + "def pretty_params(p):\n", + " p = copy(p)\n", + " if 'snap' in p and p['snap'] == 0:\n", + " del p['snap']\n", + " return p\n", + " \n", + "tabulate.tabulate([(accuracy, space, time, v['factory'], pretty_params(v['construction_params'][1]), pretty_params(v['search_params'])) \n", + " for accuracy, space, time, k, v in fr],\n", + " tablefmt=\"html\",\n", + " headers=[\"accuracy\",\"space\", \"time\", \"factory\", \"quantizer cfg\", \"search cfg\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36e82084-18f6-4546-a717-163eb0224ee8", + "metadata": {}, + "outputs": [], + "source": [ + "# index local optima @ precision 0.8\n", + "precision = 0.8\n", + "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", + "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aff79376-39f7-47c0-8b83-1efe5192bb7e", + "metadata": {}, + "outputs": [], + "source": [ + "# index local optima @ precision 0.2\n", + "precision = 0.2\n", + "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", + "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b4834f1f-bbbe-4cae-9aa0-a459b0c842d1", + "metadata": {}, + "outputs": [], + "source": [ + "# global optima @ precision 0.8\n", + "precision = 0.8\n", + "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", + "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=f\"range recall @ precision {precision}\", cost_title=\"time (seconds, 16 cores)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9aead830-6209-4956-b7ea-4a5e0029d616", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_range_search_pr_curves(experiments):\n", + " x = {}\n", + " y = {}\n", + " show = {\n", + " 'Flat': None,\n", + " }\n", + " for _, _, _, k, v in fr:\n", + " if \".weighted\" in k: # and v['index'] in show:\n", + " x[k] = v['range_search_pr']['recall']\n", + " y[k] = v['range_search_pr']['precision']\n", + " \n", + " plt.title(\"range search recall\")\n", + " plt.xlabel(\"recall\")\n", + " plt.ylabel(\"precision\")\n", + " for index in x.keys():\n", + " plt.plot(x[index], y[index], '.', label=index)\n", + " plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper left')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92e45502-7a31-4a15-90df-fa3032d7d350", + "metadata": {}, + "outputs": [], + "source": [ + "precision = 0.8\n", + "accuracy_metric = lambda exp: range_search_recall_at_precision(exp, precision)\n", + "fr = filter_results(results, evaluation=\"weighted\", accuracy_metric=accuracy_metric, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME_SPACE, scaling_factor=1)\n", + "plot_range_search_pr_curves(fr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fdf8148a-0da6-4c5e-8d60-f8f85314574c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", + "fig.tight_layout()\n", + "for plot, scale in zip(plots, scales, strict=True):\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e503828c-ee61-45f7-814b-cce6461109bc", + "metadata": {}, + "outputs": [], + "source": [ + "x = {}\n", + "y = {}\n", + "accuracy=0.9\n", + "root = \"/checkpoint/gsz/bench_fw/ivf/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "#fig, plots = plt.subplots(len(scales), sharex=True, figsize=(5,25))\n", + "#fig.tight_layout()\n", + "for scale in scales:\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " scale *= 1_000_000\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=accuracy, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " seen = set()\n", + " print(scale)\n", + " for _, _, _, _, exp in fr:\n", + " fact = exp[\"factory\"]\n", + " # \"HNSW\" in fact or \n", + " if fact in seen or fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", + " continue\n", + " seen.add(fact)\n", + " if fact not in x:\n", + " x[fact] = []\n", + " y[fact] = []\n", + " x[fact].append(scale)\n", + " y[fact].append(exp[\"time\"] + exp[\"quantizer\"][\"time\"])\n", + " if (exp[\"knn_intersection\"] > 0.92):\n", + " print(fact)\n", + " print(exp[\"search_params\"])\n", + " print(exp[\"knn_intersection\"])\n", + "\n", + " #plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"time (seconds, 64 cores)\", plot=plot)\n", + " \n", + "plt.title(f\"recall @ 1 = {accuracy*100}%\")\n", + "plt.xlabel(\"database size\")\n", + "plt.ylabel(\"time\")\n", + "plt.xscale(\"log\")\n", + "plt.yscale(\"log\")\n", + "\n", + "marker = itertools.cycle((\"o\", \"v\", \"^\", \"<\", \">\", \"s\", \"p\", \"P\", \"*\", \"h\", \"X\", \"D\")) \n", + "for index in x.keys():\n", + " if \"HNSW\" in index:\n", + " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker), linestyle=\"dashed\")\n", + " else:\n", + " plt.plot(x[index], y[index], label=index, linewidth=1, marker=next(marker))\n", + "plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper left')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37a99bb2-f998-461b-a345-7cc6e702cb3a", + "metadata": {}, + "outputs": [], + "source": [ + "# global optima\n", + "accuracy_metric = \"sym_recall\"\n", + "fr = filter_results(results, evaluation=\"rec\", accuracy_metric=accuracy_metric, time_metric=lambda e:e['encode_time'], min_accuracy=0.9, pareto_mode=ParetoMode.GLOBAL, pareto_metric=ParetoMetric.SPACE, scaling_factor=1)\n", + "plot_metric(fr, accuracy_title=\"knn intersection\", cost_title=\"space\", plot_space=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c973ce4e-3566-4f02-bd93-f113e3e0c791", + "metadata": {}, + "outputs": [], + "source": [ + "def pretty_time(s):\n", + " if s is None:\n", + " return \"None\"\n", + " s = int(s * 1000) / 1000\n", + " m, s = divmod(s, 60)\n", + " h, m = divmod(m, 60)\n", + " d, h = divmod(h, 24)\n", + " r = \"\"\n", + " if d > 0:\n", + " r += f\"{int(d)}d \"\n", + " if h > 0:\n", + " r += f\"{int(h)}h \"\n", + " if m > 0:\n", + " r += f\"{int(m)}m \"\n", + " if s > 0 or len(r) == 0:\n", + " r += f\"{s:.3f}s\"\n", + " return r\n", + "\n", + "def pretty_size(s):\n", + " if s > 1024 * 1024:\n", + " return f\"{s / 1024 / 1024:.1f}\".rstrip('0').rstrip('.') + \"MB\"\n", + " if s > 1024:\n", + " return f\"{s / 1024:.1f}\".rstrip('0').rstrip('.') + \"KB\"\n", + " return f\"{s}\"\n", + "\n", + "def pretty_mse(m):\n", + " if m is None:\n", + " return \"None\"\n", + " else:\n", + " return f\"{m:.6f}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ddcf226-fb97-4a59-9fc3-3ed8f7d5e703", + "metadata": {}, + "outputs": [], + "source": [ + "data = {}\n", + "root = \"/checkpoint/gsz/bench_fw/bigann\"\n", + "scales = [1, 2, 5, 10, 20, 50]\n", + "for scale in scales:\n", + " results = BIO(root).read_json(f\"result{scale}.json\")\n", + " accuracy_metric = \"knn_intersection\"\n", + " fr = filter_results(results, evaluation=\"knn\", accuracy_metric=accuracy_metric, min_accuracy=0, pareto_mode=ParetoMode.INDEX, pareto_metric=ParetoMetric.TIME, scaling_factor=1)\n", + " d = {}\n", + " data[f\"{scale}M\"] = d\n", + " for _, _, _, _, exp in fr:\n", + " fact = exp[\"factory\"]\n", + " # \"HNSW\" in fact or \n", + " if fact in [\"Flat\", \"IVF512,Flat\", \"IVF1024,Flat\", \"IVF2048,Flat\"]:\n", + " continue\n", + " if fact not in d:\n", + " d[fact] = []\n", + " d[fact].append({\n", + " \"nprobe\": exp[\"search_params\"][\"nprobe\"],\n", + " \"recall\": exp[\"knn_intersection\"],\n", + " \"time\": exp[\"time\"] + exp[\"quantizer\"][\"time\"],\n", + " })\n", + "data\n", + "# with open(\"/checkpoint/gsz/bench_fw/codecs.json\", \"w\") as f:\n", + "# json.dump(data, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e54eebb6-0a9f-4a72-84d2-f12c5bd44510", + "metadata": {}, + "outputs": [], + "source": [ + "ds = \"deep1b\"\n", + "data = []\n", + "jss = []\n", + "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", + "results = BIO(root).read_json(f\"result.json\")\n", + "for k, e in results[\"experiments\"].items():\n", + " if \"rec\" in k and e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", + " code_size = results['indices'][e['codec']]['sa_code_size']\n", + " codec_size = results['indices'][e['codec']]['codec_size']\n", + " training_time = results['indices'][e['codec']]['training_time']\n", + " # training_size = results['indices'][e['codec']]['training_size']\n", + " cpu = e['cpu'] if 'cpu' in e else \"\"\n", + " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", + " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", + " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{training_size}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", + " jss.append({\n", + " 'factory': e['factory'],\n", + " 'parameters': e['construction_params'][0] if e['construction_params'] else \"\",\n", + " 'evaluation_params': e['reconstruct_params'],\n", + " 'code_size': code_size,\n", + " 'codec_size': codec_size,\n", + " 'training_time': training_time,\n", + " 'training_size': training_size,\n", + " 'mse': e['mse'],\n", + " 'sym_recall': e['sym_recall'],\n", + " 'asym_recall': e['asym_recall'],\n", + " 'encode_time': e['encode_time'],\n", + " 'decode_time': e['decode_time'],\n", + " 'cpu': cpu,\n", + " })\n", + "\n", + "print(\"|factory key|construction parameters|evaluation parameters|code size|codec size|training time|training size|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", + "print(\"|-|-|-|-|-|-|-|-|-|\")\n", + "data.sort()\n", + "for d in data:\n", + " print(d[1])\n", + "\n", + "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_test.json\", \"w\") as f:\n", + " json.dump(jss, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d1216733-9670-407c-b3d2-5f87bce0321c", + "metadata": {}, + "outputs": [], + "source": [ + "def read_file(filename: str, keys):\n", + " results = []\n", + " with ZipFile(filename, \"r\") as zip_file:\n", + " for key in keys:\n", + " with zip_file.open(key, \"r\") as f:\n", + " if key in [\"D\", \"I\", \"R\", \"lims\"]:\n", + " results.append(np.load(f))\n", + " elif key in [\"P\"]:\n", + " t = io.TextIOWrapper(f)\n", + " results.append(json.load(t))\n", + " else:\n", + " raise AssertionError()\n", + " return results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56de051e-22db-4bef-b242-1ddabc9e0bb9", + "metadata": {}, + "outputs": [], + "source": [ + "ds = \"contriever\"\n", + "data = []\n", + "jss = []\n", + "root = f\"/checkpoint/gsz/bench_fw/codecs/{ds}\"\n", + "for lf in glob.glob(root + '/*rec*.zip'):\n", + " e, = read_file(lf, ['P'])\n", + " if e['factory'] != 'Flat': # and e['sym_recall'] > 0.0: # and \"PRQ\" in e['factory'] and e['sym_recall'] > 0.0:\n", + " code_size = e['codec_meta']['sa_code_size']\n", + " codec_size = e['codec_meta']['codec_size']\n", + " training_time = e['codec_meta']['training_time']\n", + " training_size = None # e['codec_meta']['training_size']\n", + " cpu = e['cpu'] if 'cpu' in e else \"\"\n", + " ps = ', '.join([f\"{k}={v}\" for k,v in e['construction_params'][0].items()]) if e['construction_params'] else \" \"\n", + " eps = ', '.join([f\"{k}={v}\" for k,v in e['reconstruct_params'].items() if k != \"snap\"]) if e['reconstruct_params'] else \" \"\n", + " if eps in ps and eps != \"encode_ils_iters=16\" and eps != \"max_beam_size=32\":\n", + " eps = \" \"\n", + " data.append((code_size, f\"|{e['factory']}|{ps}|{eps}|{code_size}|{pretty_size(codec_size)}|{pretty_time(training_time)}|{pretty_mse(e['mse'])}|{e['sym_recall']}|{e['asym_recall']}|{pretty_time(e['encode_time'])}|{pretty_time(e['decode_time'])}|{cpu}|\"))\n", + " eps = e['reconstruct_params']\n", + " del eps['snap']\n", + " params = copy(e['construction_params'][0]) if e['construction_params'] else {}\n", + " for k, v in e['reconstruct_params'].items():\n", + " params[k] = v\n", + " jss.append({\n", + " 'factory': e['factory'],\n", + " 'params': params,\n", + " 'construction_params': e['construction_params'][0] if e['construction_params'] else {},\n", + " 'evaluation_params': e['reconstruct_params'],\n", + " 'code_size': code_size,\n", + " 'codec_size': codec_size,\n", + " 'training_time': training_time,\n", + " # 'training_size': training_size,\n", + " 'mse': e['mse'],\n", + " 'sym_recall': e['sym_recall'],\n", + " 'asym_recall': e['asym_recall'],\n", + " 'encode_time': e['encode_time'],\n", + " 'decode_time': e['decode_time'],\n", + " 'cpu': cpu,\n", + " })\n", + "\n", + "print(\"|factory key|construction parameters|encode/decode parameters|code size|codec size|training time|mean squared error|sym recall @ 1|asym recall @ 1|encode time|decode time|cpu|\")\n", + "print(\"|-|-|-|-|-|-|-|-|-|\")\n", + "data.sort()\n", + "# for d in data:\n", + "# print(d[1])\n", + "\n", + "print(len(data))\n", + "\n", + "with open(f\"/checkpoint/gsz/bench_fw/codecs_{ds}_5.json\", \"w\") as f:\n", + " json.dump(jss, f)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:.conda-faiss_from_source] *", + "language": "python", + "name": "conda-env-.conda-faiss_from_source-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 + } diff --git a/benchs/bench_fw_optimize.py b/benchs/bench_fw_optimize.py new file mode 100644 index 0000000000..31b56f9f51 --- /dev/null +++ b/benchs/bench_fw_optimize.py @@ -0,0 +1,58 @@ +# 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 bench_fw.benchmark_io import BenchmarkIO +from bench_fw.descriptors import DatasetDescriptor +from bench_fw.optimize import Optimizer + +logging.basicConfig(level=logging.INFO) + + +def bigann(bio): + optimizer = Optimizer( + distance_metric="L2", + num_threads=32, + run_local=False, + ) + optimizer.set_io(bio) + query_vectors = DatasetDescriptor(namespace="std_q", tablename="bigann1M") + xt = bio.get_dataset(query_vectors) + optimizer.optimize( + d=xt.shape[1], + training_vectors=DatasetDescriptor( + namespace="std_t", + tablename="bigann1M", + num_vectors=2_000_000, + ), + database_vectors_list=[ + DatasetDescriptor( + namespace="std_d", + tablename="bigann1M", + ), + DatasetDescriptor(namespace="std_d", tablename="bigann10M"), + ], + query_vectors=query_vectors, + min_accuracy=0.85, + ) + + +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 == "bigann": + bigann(bio) From c1822a81b22a70a6a38848be2c18b44244db57b5 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Wed, 31 Jan 2024 14:25:13 -0800 Subject: [PATCH 069/206] cuda dependencies (#3230) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3230 Reviewed By: mlomeli1 Differential Revision: D53271742 Pulled By: algoriddle fbshipit-source-id: b0f09e26ab0b4cfcbdb10528b2f57e15c10f4265 --- .circleci/config.yml | 53 +++++++++++++++++++++++++--------- conda/conda_build_config.yaml | 2 +- conda/faiss-gpu-raft/meta.yaml | 14 +++++++-- conda/faiss-gpu/meta.yaml | 12 ++++++-- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2901894577..2b79762dc7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -140,7 +140,7 @@ jobs: command: | cd conda conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia/label/cuda-<> + -c pytorch -c nvidia/label/cuda-<> -c nvidia - when: condition: and: @@ -154,7 +154,7 @@ jobs: command: | cd conda conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia - when: condition: and: @@ -168,7 +168,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia -c rapidsai-nightly -c conda-forge + -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai-nightly -c conda-forge - when: condition: and: @@ -182,7 +182,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c rapidsai-nightly -c conda-forge + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai-nightly -c conda-forge build_cmake: parameters: @@ -232,15 +232,17 @@ jobs: - run: name: Install env using conda-forge channel command: | - conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - when: condition: - equal: [ "ON", << parameters.gpu >> ] + and: + - equal: [ "ON", << parameters.gpu >> ] + - equal: [ "OFF", << parameters.raft >> ] steps: - run: name: Install CUDA command: | - conda install -y -q cuda-nvcc cuda-cudart-dev libcublas libcublas-dev cuda-toolkit -c "nvidia/label/cuda-11.8.0" + conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" - run: name: Build all targets no_output_timeout: 30m @@ -287,7 +289,7 @@ jobs: - run: name: Python tests (CPU + GPU) command: | - conda install -y -q pytorch pytorch-cuda=11 -c pytorch -c nvidia/label/cuda-11.8.0 + conda install -y -q pytorch pytorch-cuda=11.8 -c pytorch -c nvidia/label/cuda-11.8.0 pytest --junitxml=test-results/pytest/results.xml tests/test_*.py pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py cp tests/common_faiss_tests.py faiss/gpu/test @@ -354,10 +356,10 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU packages (CUDA 11.8) + name: Linux x86_64 GPU packages (CUDA 11.8.0) exec: linux-x86_64-gpu label: main - cuda: "11.8" + cuda: "11.8.0" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: @@ -366,11 +368,36 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.8) + name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.8.0) exec: linux-x86_64-gpu label: main raft: "ON" - cuda: "11.8" + cuda: "11.8.0" + cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + compiler_version: "11.2" + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + - build_conda: + name: Linux x86_64 GPU packages (CUDA 12.1.0) + exec: linux-x86_64-gpu + label: main + cuda: "12.1.0" + cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + compiler_version: "11.2" + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ + - build_conda: + name: Linux x86_64 GPU w/ RAFT packages (CUDA 12.1.0) + exec: linux-x86_64-gpu + label: main + raft: "ON" + cuda: "12.1.0" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: @@ -420,7 +447,7 @@ workflows: exec: linux-x86_64-cpu label: nightly - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 11.8) + name: Linux x86_64 GPU nightlies (CUDA 11.8.0) exec: linux-x86_64-gpu cuda: "11.8.0" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" diff --git a/conda/conda_build_config.yaml b/conda/conda_build_config.yaml index cbfd2b0e81..4df05146df 100644 --- a/conda/conda_build_config.yaml +++ b/conda/conda_build_config.yaml @@ -2,4 +2,4 @@ python: - 3.9 - 3.10 - 3.11 - - 3.12 + - 3.12 # [not aarch64] diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index d5c893bd3d..7bd3ed2d2b 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -6,6 +6,13 @@ {% set version = environ.get('GIT_DESCRIBE_TAG').lstrip('v') %} {% set suffix = "_nightly" if environ.get('PACKAGE_TYPE') == 'nightly' else "" %} {% set number = GIT_DESCRIBE_NUMBER %} +{% if cudatoolkit == '11.8.0' %} +{% set cuda_constraints=">=11.8,<11.9" %} +{% set libcublas_constraints=">=11.11,<12" %} +{% elif cudatoolkit == '12.1.0' %} +{% set cuda_constraints=">=12.1,<12.2" %} +{% set libcublas_constraints=">=12.1,<12.2" %} +{% endif %} package: name: faiss-pkg @@ -45,16 +52,18 @@ outputs: - make # [not win] - mkl-devel =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} - - pytorch-cuda host: - mkl =2023 # [x86_64] - openblas # [not x86_64] - libraft =24.02 + - cuda-version {{ cuda_constraints }} run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - {{ pin_compatible('pytorch-cuda', max_pin='x') }} + - cuda-cudart {{ cuda_constraints }} + - libcublas {{ libcublas_constraints }} - libraft =24.02 + - cuda-version {{ cuda_constraints }} test: requires: - conda-build @@ -92,6 +101,7 @@ outputs: - numpy - scipy - pytorch + - pytorch-cuda {{ cuda_constraints }} commands: - python -X faulthandler -m unittest discover -v -s tests/ -p "test_*" - python -X faulthandler -m unittest discover -v -s tests/ -p "torch_*" diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index c3e60c52ec..865c385c8c 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -6,6 +6,13 @@ {% set version = environ.get('GIT_DESCRIBE_TAG').lstrip('v') %} {% set suffix = "_nightly" if environ.get('PACKAGE_TYPE') == 'nightly' else "" %} {% set number = GIT_DESCRIBE_NUMBER %} +{% if cudatoolkit == '11.8.0' %} +{% set cuda_constraints=">=11.8,<11.9" %} +{% set libcublas_constraints=">=11.11,<12" %} +{% elif cudatoolkit == '12.1.0' %} +{% set cuda_constraints=">=12.1,<12.2" %} +{% set libcublas_constraints=">=12.1,<12.2" %} +{% endif %} package: name: faiss-pkg @@ -45,14 +52,14 @@ outputs: - make # [not win] - mkl-devel =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} - - pytorch-cuda host: - mkl =2023 # [x86_64] - openblas # [not x86_64] run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - {{ pin_compatible('pytorch-cuda', max_pin='x') }} + - cuda-cudart {{ cuda_constraints }} + - libcublas {{ libcublas_constraints }} test: requires: - conda-build @@ -90,6 +97,7 @@ outputs: - numpy - scipy - pytorch + - pytorch-cuda {{ cuda_constraints }} commands: - python -X faulthandler -m unittest discover -v -s tests/ -p "test_*" - python -X faulthandler -m unittest discover -v -s tests/ -p "torch_*" From 31a29d03784b49183df31debedcbf26a1a33148d Mon Sep 17 00:00:00 2001 From: xinhuitian Date: Fri, 2 Feb 2024 02:31:57 -0800 Subject: [PATCH 070/206] HNSW search use efSearch from params if provided (#3233) Summary: I found that HNSW search method uses its own efSearch to create candidates, which should be got from params if provided I think? Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3233 Reviewed By: algoriddle Differential Revision: D53342879 Pulled By: mdouze fbshipit-source-id: 4f47f19d3673d1bb8d7e8e82745f9e5c1b9afb42 --- faiss/impl/HNSW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index fb4de67899..a9fb9daf5b 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -829,7 +829,7 @@ HNSWStats HNSW::search( greedy_update_nearest(*this, qdis, level, nearest, d_nearest); } - int ef = std::max(efSearch, k); + int ef = std::max(params ? params->efSearch : efSearch, k); if (search_bounded_queue) { // this is the most common branch MinimaxHeap candidates(ef); From ed3f6e5fdf942a69b5334195b9e3d4fd84a1855d Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 2 Feb 2024 09:01:10 -0800 Subject: [PATCH 071/206] faiss-gpu to use 11.4.4 and be the only one supporting P100 (#3237) Summary: Considering that only GPU classic works on Pascal and only if compiled with cuda 11.4, this sets up the conda builds as follows. tl;dr: Pascal will only be supported by faiss-gpu on cuda 11. ## faiss-gpu 1. build on cuda 11.4.4, supports Pascal, works with pytorch-cuda=11 (including hosts with cuda 12 drivers) 2. build on cuda 12.1.1, does NOT support Pascal, works with pytorch-cuda=12 ## faiss-gpu-raft 1. build on cuda 11.8.0, does NOT support Pascal, works with pytorch-cuda=11.8 2. build on cuda 12.1.1, does NOT support Pascal, works with pytorch-cuda=12 The reason faiss-gpu-raft is built with and supports only 11.8 is due to the risk of clobbering otherwise between libraft and pytorch-cuda dependencies. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3237 Reviewed By: mdouze Differential Revision: D53354121 Pulled By: algoriddle fbshipit-source-id: 86108e975168759572f84922bf0ccef55ae75ef8 --- .circleci/config.yml | 44 +++++++++++++++++----------------- conda/faiss-gpu-raft/meta.yaml | 8 +++---- conda/faiss-gpu/meta.yaml | 12 +++++----- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2b79762dc7..0d9b5bdf01 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -356,10 +356,10 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU packages (CUDA 11.8.0) + name: Linux x86_64 GPU packages (CUDA 11.4.4) exec: linux-x86_64-gpu label: main - cuda: "11.8.0" + cuda: "11.4.4" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: @@ -373,7 +373,7 @@ workflows: label: main raft: "ON" cuda: "11.8.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + cuda_archs: "70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: tags: @@ -381,11 +381,11 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU packages (CUDA 12.1.0) + name: Linux x86_64 GPU packages (CUDA 12.1.1) exec: linux-x86_64-gpu label: main - cuda: "12.1.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + cuda: "12.1.1" + cuda_archs: "70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: tags: @@ -393,12 +393,12 @@ workflows: branches: ignore: /.*/ - build_conda: - name: Linux x86_64 GPU w/ RAFT packages (CUDA 12.1.0) + name: Linux x86_64 GPU w/ RAFT packages (CUDA 12.1.1) exec: linux-x86_64-gpu label: main raft: "ON" - cuda: "12.1.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + cuda: "12.1.1" + cuda_archs: "70-real;72-real;75-real;80;86-real" compiler_version: "11.2" filters: tags: @@ -447,35 +447,35 @@ workflows: exec: linux-x86_64-cpu label: nightly - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 11.8.0) + name: Linux x86_64 GPU nightlies (CUDA 11.4.4) exec: linux-x86_64-gpu - cuda: "11.8.0" + label: nightly + cuda: "11.4.4" cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" compiler_version: "11.2" - label: nightly - build_conda: name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 11.8.0) exec: linux-x86_64-gpu + label: nightly raft: "ON" cuda: "11.8.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + cuda_archs: "70-real;72-real;75-real;80;86-real" compiler_version: "11.2" - label: nightly - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 12.1.0) + name: Linux x86_64 GPU nightlies (CUDA 12.1.1) exec: linux-x86_64-gpu - cuda: "12.1.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" label: nightly + cuda: "12.1.1" + cuda_archs: "70-real;72-real;75-real;80;86-real" + compiler_version: "11.2" - build_conda: - name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 12.1.0) + name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 12.1.1) exec: linux-x86_64-gpu + label: nightly raft: "ON" - cuda: "12.1.0" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + cuda: "12.1.1" + cuda_archs: "70-real;72-real;75-real;80;86-real" compiler_version: "11.2" - label: nightly - build_conda: name: Windows x86_64 nightlies exec: windows-x86_64-cpu diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 7bd3ed2d2b..b365571777 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -7,11 +7,11 @@ {% set suffix = "_nightly" if environ.get('PACKAGE_TYPE') == 'nightly' else "" %} {% set number = GIT_DESCRIBE_NUMBER %} {% if cudatoolkit == '11.8.0' %} -{% set cuda_constraints=">=11.8,<11.9" %} +{% set cuda_constraints=">=11.8,<12" %} {% set libcublas_constraints=">=11.11,<12" %} -{% elif cudatoolkit == '12.1.0' %} -{% set cuda_constraints=">=12.1,<12.2" %} -{% set libcublas_constraints=">=12.1,<12.2" %} +{% elif cudatoolkit == '12.1.1' %} +{% set cuda_constraints=">=12.1,<13" %} +{% set libcublas_constraints=">=12.1,<13" %} {% endif %} package: diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index 865c385c8c..b0df707181 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -6,12 +6,12 @@ {% set version = environ.get('GIT_DESCRIBE_TAG').lstrip('v') %} {% set suffix = "_nightly" if environ.get('PACKAGE_TYPE') == 'nightly' else "" %} {% set number = GIT_DESCRIBE_NUMBER %} -{% if cudatoolkit == '11.8.0' %} -{% set cuda_constraints=">=11.8,<11.9" %} -{% set libcublas_constraints=">=11.11,<12" %} -{% elif cudatoolkit == '12.1.0' %} -{% set cuda_constraints=">=12.1,<12.2" %} -{% set libcublas_constraints=">=12.1,<12.2" %} +{% if cudatoolkit == '11.4.4' %} +{% set cuda_constraints=">=11.4,<12" %} +{% set libcublas_constraints=">=11.6,<12" %} +{% elif cudatoolkit == '12.1.1' %} +{% set cuda_constraints=">=12.1,<13" %} +{% set libcublas_constraints=">=12.1,<13" %} {% endif %} package: From bfa46a3a5902074862bf96750063a68f9baf9901 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 9 Feb 2024 03:26:44 -0800 Subject: [PATCH 072/206] pin circleci windows image (#3248) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3248 Build scripts can't find conda in the 'stable' image, trying to pin to a specific version. Reviewed By: mlomeli1 Differential Revision: D53608347 fbshipit-source-id: 3f7c350608afc9c253cf0153e37ceeb4fceca92c --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0d9b5bdf01..5b42164509 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ executors: resource_class: macos.m1.large.gen1 windows-x86_64-cpu: machine: - image: windows-server-2019-vs2019:stable + image: windows-server-2019-vs2019:2023.04.1 shell: bash.exe resource_class: windows.medium From ebb5f8401bdff6b5802738bb93385963e0f73c33 Mon Sep 17 00:00:00 2001 From: Xiaozhong Pan Date: Fri, 9 Feb 2024 09:14:38 -0800 Subject: [PATCH 073/206] add a context parameter to InvertedLists and InvertedListsIterator (#3247) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3247 add a context parameter to be passed to InvertedLists and InvertedListsIterator. - add a context field in `SearchParametersIVF`, the context will be passed to `InvertedLists::get_iterator`. The user can create `InvertedListsIterator` with the context object - add a context parameter in `IndexIVF::add_core` method. the context will be passed to `InvertedLists::add_entry`. The user can use the context object to pass storage handlers, store error codes from storage layer, logging information, etc. Reviewed By: mdouze Differential Revision: D53113911 fbshipit-source-id: ff31d247d3dc949d0bb50bcaffc3142efd027089 --- faiss/IndexIVF.cpp | 25 +++- faiss/IndexIVF.h | 5 +- faiss/IndexIVFFlat.cpp | 7 +- faiss/IndexIVFFlat.h | 3 +- faiss/IndexIVFPQ.cpp | 14 +- faiss/IndexIVFPQ.h | 6 +- faiss/IndexIVFPQR.cpp | 3 +- faiss/IndexIVFPQR.h | 3 +- faiss/IndexScalarQuantizer.cpp | 6 +- faiss/IndexScalarQuantizer.h | 3 +- faiss/invlists/InvertedLists.cpp | 18 ++- faiss/invlists/InvertedLists.h | 12 +- tests/CMakeLists.txt | 1 + tests/test_ivf_index.cpp | 242 +++++++++++++++++++++++++++++++ 14 files changed, 314 insertions(+), 34 deletions(-) create mode 100644 tests/test_ivf_index.cpp diff --git a/faiss/IndexIVF.cpp b/faiss/IndexIVF.cpp index a1fa8cd16b..65d017aa5a 100644 --- a/faiss/IndexIVF.cpp +++ b/faiss/IndexIVF.cpp @@ -203,7 +203,8 @@ void IndexIVF::add_core( idx_t n, const float* x, const idx_t* xids, - const idx_t* coarse_idx) { + const idx_t* coarse_idx, + void* inverted_list_context) { // do some blocking to avoid excessive allocs idx_t bs = 65536; if (n > bs) { @@ -218,7 +219,8 @@ void IndexIVF::add_core( i1 - i0, x + i0 * d, xids ? xids + i0 : nullptr, - coarse_idx + i0); + coarse_idx + i0, + inverted_list_context); } return; } @@ -249,7 +251,10 @@ void IndexIVF::add_core( if (list_no >= 0 && list_no % nt == rank) { idx_t id = xids ? xids[i] : ntotal + i; size_t ofs = invlists->add_entry( - list_no, id, flat_codes.get() + i * code_size); + list_no, + id, + flat_codes.get() + i * code_size, + inverted_list_context); dm_adder.add(i, list_no, ofs); @@ -445,6 +450,9 @@ void IndexIVF::search_preassigned( : pmode == 1 ? nprobe > 1 : nprobe * n > 1); + void* inverted_list_context = + params ? params->inverted_list_context : nullptr; + #pragma omp parallel if (do_parallel) reduction(+ : nlistv, ndis, nheap) { std::unique_ptr scanner( @@ -507,7 +515,7 @@ void IndexIVF::search_preassigned( nlist); // don't waste time on empty lists - if (invlists->is_empty(key)) { + if (invlists->is_empty(key, inverted_list_context)) { return (size_t)0; } @@ -520,7 +528,7 @@ void IndexIVF::search_preassigned( size_t list_size = 0; std::unique_ptr it( - invlists->get_iterator(key)); + invlists->get_iterator(key, inverted_list_context)); nheap += scanner->iterate_codes( it.get(), simi, idxi, k, list_size); @@ -783,6 +791,9 @@ void IndexIVF::range_search_preassigned( : pmode == 1 ? nprobe > 1 : nprobe * nx > 1); + void* inverted_list_context = + params ? params->inverted_list_context : nullptr; + #pragma omp parallel if (do_parallel) reduction(+ : nlistv, ndis) { RangeSearchPartialResult pres(result); @@ -804,7 +815,7 @@ void IndexIVF::range_search_preassigned( ik, nlist); - if (invlists->is_empty(key)) { + if (invlists->is_empty(key, inverted_list_context)) { return; } @@ -813,7 +824,7 @@ void IndexIVF::range_search_preassigned( scanner->set_list(key, coarse_dis[i * nprobe + ik]); if (invlists->use_iterator) { std::unique_ptr it( - invlists->get_iterator(key)); + invlists->get_iterator(key, inverted_list_context)); scanner->iterate_codes_range( it.get(), radius, qres, list_size); diff --git a/faiss/IndexIVF.h b/faiss/IndexIVF.h index d0981caa42..45c65ef839 100644 --- a/faiss/IndexIVF.h +++ b/faiss/IndexIVF.h @@ -72,6 +72,8 @@ struct SearchParametersIVF : SearchParameters { size_t nprobe = 1; ///< number of probes at query time size_t max_codes = 0; ///< max nb of codes to visit to do a query SearchParameters* quantizer_params = nullptr; + /// context object to pass to InvertedLists + void* inverted_list_context = nullptr; virtual ~SearchParametersIVF() {} }; @@ -232,7 +234,8 @@ struct IndexIVF : Index, IndexIVFInterface { idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx); + const idx_t* precomputed_idx, + void* inverted_list_context = nullptr); /** Encodes a set of vectors as they would appear in the inverted lists * diff --git a/faiss/IndexIVFFlat.cpp b/faiss/IndexIVFFlat.cpp index e985683eba..1b36fea379 100644 --- a/faiss/IndexIVFFlat.cpp +++ b/faiss/IndexIVFFlat.cpp @@ -47,7 +47,8 @@ void IndexIVFFlat::add_core( idx_t n, const float* x, const idx_t* xids, - const idx_t* coarse_idx) { + const idx_t* coarse_idx, + void* inverted_list_context) { FAISS_THROW_IF_NOT(is_trained); FAISS_THROW_IF_NOT(coarse_idx); FAISS_THROW_IF_NOT(!by_residual); @@ -70,8 +71,8 @@ void IndexIVFFlat::add_core( if (list_no >= 0 && list_no % nt == rank) { idx_t id = xids ? xids[i] : ntotal + i; const float* xi = x + i * d; - size_t offset = - invlists->add_entry(list_no, id, (const uint8_t*)xi); + size_t offset = invlists->add_entry( + list_no, id, (const uint8_t*)xi, inverted_list_context); dm_adder.add(i, list_no, offset); n_add++; } else if (rank == 0 && list_no == -1) { diff --git a/faiss/IndexIVFFlat.h b/faiss/IndexIVFFlat.h index a0233052fa..8e47547e02 100644 --- a/faiss/IndexIVFFlat.h +++ b/faiss/IndexIVFFlat.h @@ -32,7 +32,8 @@ struct IndexIVFFlat : IndexIVF { idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx) override; + const idx_t* precomputed_idx, + void* inverted_list_context = nullptr) override; void encode_vectors( idx_t n, diff --git a/faiss/IndexIVFPQ.cpp b/faiss/IndexIVFPQ.cpp index 6de78b9539..5d02c5ee0e 100644 --- a/faiss/IndexIVFPQ.cpp +++ b/faiss/IndexIVFPQ.cpp @@ -135,8 +135,9 @@ void IndexIVFPQ::add_core( idx_t n, const float* x, const idx_t* xids, - const idx_t* coarse_idx) { - add_core_o(n, x, xids, nullptr, coarse_idx); + const idx_t* coarse_idx, + void* inverted_list_context) { + add_core_o(n, x, xids, nullptr, coarse_idx, inverted_list_context); } static std::unique_ptr compute_residuals( @@ -212,7 +213,8 @@ void IndexIVFPQ::add_core_o( const float* x, const idx_t* xids, float* residuals_2, - const idx_t* precomputed_idx) { + const idx_t* precomputed_idx, + void* inverted_list_context) { idx_t bs = index_ivfpq_add_core_o_bs; if (n > bs) { for (idx_t i0 = 0; i0 < n; i0 += bs) { @@ -229,7 +231,8 @@ void IndexIVFPQ::add_core_o( x + i0 * d, xids ? xids + i0 : nullptr, residuals_2 ? residuals_2 + i0 * d : nullptr, - precomputed_idx ? precomputed_idx + i0 : nullptr); + precomputed_idx ? precomputed_idx + i0 : nullptr, + inverted_list_context); } return; } @@ -281,7 +284,8 @@ void IndexIVFPQ::add_core_o( } uint8_t* code = xcodes.get() + i * code_size; - size_t offset = invlists->add_entry(key, id, code); + size_t offset = + invlists->add_entry(key, id, code, inverted_list_context); if (residuals_2) { float* res2 = residuals_2 + i * d; diff --git a/faiss/IndexIVFPQ.h b/faiss/IndexIVFPQ.h index ab49f1e549..d5d21da49d 100644 --- a/faiss/IndexIVFPQ.h +++ b/faiss/IndexIVFPQ.h @@ -71,7 +71,8 @@ struct IndexIVFPQ : IndexIVF { idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx) override; + const idx_t* precomputed_idx, + void* inverted_list_context = nullptr) override; /// same as add_core, also: /// - output 2nd level residuals if residuals_2 != NULL @@ -81,7 +82,8 @@ struct IndexIVFPQ : IndexIVF { const float* x, const idx_t* xids, float* residuals_2, - const idx_t* precomputed_idx = nullptr); + const idx_t* precomputed_idx = nullptr, + void* inverted_list_context = nullptr); /// trains the product quantizer void train_encoder(idx_t n, const float* x, const idx_t* assign) override; diff --git a/faiss/IndexIVFPQR.cpp b/faiss/IndexIVFPQR.cpp index 2dd967e829..f55332cddf 100644 --- a/faiss/IndexIVFPQR.cpp +++ b/faiss/IndexIVFPQR.cpp @@ -91,7 +91,8 @@ void IndexIVFPQR::add_core( idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx) { + const idx_t* precomputed_idx, + void* /*inverted_list_context*/) { std::unique_ptr residual_2(new float[n * d]); idx_t n0 = ntotal; diff --git a/faiss/IndexIVFPQR.h b/faiss/IndexIVFPQR.h index 73502879f2..7642d2f232 100644 --- a/faiss/IndexIVFPQR.h +++ b/faiss/IndexIVFPQR.h @@ -48,7 +48,8 @@ struct IndexIVFPQR : IndexIVFPQ { idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx) override; + const idx_t* precomputed_idx, + void* inverted_list_context = nullptr) override; void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons) const override; diff --git a/faiss/IndexScalarQuantizer.cpp b/faiss/IndexScalarQuantizer.cpp index b7199df39d..9203a98932 100644 --- a/faiss/IndexScalarQuantizer.cpp +++ b/faiss/IndexScalarQuantizer.cpp @@ -207,7 +207,8 @@ void IndexIVFScalarQuantizer::add_core( idx_t n, const float* x, const idx_t* xids, - const idx_t* coarse_idx) { + const idx_t* coarse_idx, + void* inverted_list_context) { FAISS_THROW_IF_NOT(is_trained); std::unique_ptr squant(sq.select_quantizer()); @@ -236,7 +237,8 @@ void IndexIVFScalarQuantizer::add_core( memset(one_code.data(), 0, code_size); squant->encode_vector(xi, one_code.data()); - size_t ofs = invlists->add_entry(list_no, id, one_code.data()); + size_t ofs = invlists->add_entry( + list_no, id, one_code.data(), inverted_list_context); dm_add.add(i, list_no, ofs); diff --git a/faiss/IndexScalarQuantizer.h b/faiss/IndexScalarQuantizer.h index c064bbeeb3..27332500c1 100644 --- a/faiss/IndexScalarQuantizer.h +++ b/faiss/IndexScalarQuantizer.h @@ -91,7 +91,8 @@ struct IndexIVFScalarQuantizer : IndexIVF { idx_t n, const float* x, const idx_t* xids, - const idx_t* precomputed_idx) override; + const idx_t* precomputed_idx, + void* inverted_list_context = nullptr) override; InvertedListScanner* get_InvertedListScanner( bool store_pairs, diff --git a/faiss/invlists/InvertedLists.cpp b/faiss/invlists/InvertedLists.cpp index ca87ae00ea..cc337d004b 100644 --- a/faiss/invlists/InvertedLists.cpp +++ b/faiss/invlists/InvertedLists.cpp @@ -28,11 +28,12 @@ InvertedLists::InvertedLists(size_t nlist, size_t code_size) InvertedLists::~InvertedLists() {} -bool InvertedLists::is_empty(size_t list_no) const { - return use_iterator - ? !std::unique_ptr(get_iterator(list_no)) - ->is_available() - : list_size(list_no) == 0; +bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context) + const { + return use_iterator ? !std::unique_ptr( + get_iterator(list_no, inverted_list_context)) + ->is_available() + : list_size(list_no) == 0; } idx_t InvertedLists::get_single_id(size_t list_no, size_t offset) const { @@ -58,7 +59,8 @@ const uint8_t* InvertedLists::get_single_code(size_t list_no, size_t offset) size_t InvertedLists::add_entry( size_t list_no, idx_t theid, - const uint8_t* code) { + const uint8_t* code, + void* /*inverted_list_context*/) { return add_entries(list_no, 1, &theid, code); } @@ -76,7 +78,9 @@ void InvertedLists::reset() { } } -InvertedListsIterator* InvertedLists::get_iterator(size_t /*list_no*/) const { +InvertedListsIterator* InvertedLists::get_iterator( + size_t /*list_no*/, + void* /*inverted_list_context*/) const { FAISS_THROW_MSG("get_iterator is not supported"); } diff --git a/faiss/invlists/InvertedLists.h b/faiss/invlists/InvertedLists.h index c4d681452b..90a9d65411 100644 --- a/faiss/invlists/InvertedLists.h +++ b/faiss/invlists/InvertedLists.h @@ -51,13 +51,15 @@ struct InvertedLists { * Read only functions */ // check if the list is empty - bool is_empty(size_t list_no) const; + bool is_empty(size_t list_no, void* inverted_list_context) const; /// get the size of a list virtual size_t list_size(size_t list_no) const = 0; /// get iterable for lists that use_iterator - virtual InvertedListsIterator* get_iterator(size_t list_no) const; + virtual InvertedListsIterator* get_iterator( + size_t list_no, + void* inverted_list_context) const; /** get the codes for an inverted list * must be released by release_codes @@ -94,7 +96,11 @@ struct InvertedLists { * writing functions */ /// add one entry to an inverted list - virtual size_t add_entry(size_t list_no, idx_t theid, const uint8_t* code); + virtual size_t add_entry( + size_t list_no, + idx_t theid, + const uint8_t* code, + void* inverted_list_context = nullptr); virtual size_t add_entries( size_t list_no, diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cc0a4f4cfd..a1c3266961 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,7 @@ set(FAISS_TEST_SRC test_ivfpq_codec.cpp test_ivfpq_indexing.cpp test_lowlevel_ivf.cpp + test_ivf_index.cpp test_merge.cpp test_omp_threads.cpp test_ondisk_ivf.cpp diff --git a/tests/test_ivf_index.cpp b/tests/test_ivf_index.cpp new file mode 100644 index 0000000000..54cb7945f9 --- /dev/null +++ b/tests/test_ivf_index.cpp @@ -0,0 +1,242 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace { + +// stores all ivf lists, used to verify the context +// object is passed to the iterator +class TestContext { + public: + TestContext() {} + + void save_code(size_t list_no, const uint8_t* code, size_t code_size) { + list_nos.emplace(id, list_no); + codes.emplace(id, std::vector(code_size)); + for (size_t i = 0; i < code_size; i++) { + codes[id][i] = code[i]; + } + id++; + } + + // id to codes map + std::unordered_map> codes; + // id to list_no map + std::unordered_map list_nos; + faiss::idx_t id = 0; + std::set lists_probed; +}; + +// the iterator that iterates over the codes stored in context object +class TestInvertedListIterator : public faiss::InvertedListsIterator { + public: + TestInvertedListIterator(size_t list_no, TestContext* context) + : list_no{list_no}, context{context} { + it = context->codes.cbegin(); + seek_next(); + } + ~TestInvertedListIterator() override {} + + // move the cursor to the first valid entry + void seek_next() { + while (it != context->codes.cend() && + context->list_nos[it->first] != list_no) { + it++; + } + } + + virtual bool is_available() const override { + return it != context->codes.cend(); + } + + virtual void next() override { + it++; + seek_next(); + } + + virtual std::pair get_id_and_codes() + override { + if (it == context->codes.cend()) { + FAISS_THROW_MSG("invalid state"); + } + return std::make_pair(it->first, it->second.data()); + } + + private: + size_t list_no; + TestContext* context; + decltype(context->codes.cbegin()) it; +}; + +class TestInvertedLists : public faiss::InvertedLists { + public: + TestInvertedLists(size_t nlist, size_t code_size) + : faiss::InvertedLists(nlist, code_size) { + use_iterator = true; + } + + ~TestInvertedLists() override {} + size_t list_size(size_t /*list_no*/) const override { + FAISS_THROW_MSG("unexpected call"); + } + + faiss::InvertedListsIterator* get_iterator(size_t list_no, void* context) + const override { + auto testContext = (TestContext*)context; + testContext->lists_probed.insert(list_no); + return new TestInvertedListIterator(list_no, testContext); + } + + const uint8_t* get_codes(size_t /* list_no */) const override { + FAISS_THROW_MSG("unexpected call"); + } + + const faiss::idx_t* get_ids(size_t /* list_no */) const override { + FAISS_THROW_MSG("unexpected call"); + } + + // store the codes in context object + size_t add_entry( + size_t list_no, + faiss::idx_t /*theid*/, + const uint8_t* code, + void* context) override { + auto testContext = (TestContext*)context; + testContext->save_code(list_no, code, code_size); + return 0; + } + + size_t add_entries( + size_t /*list_no*/, + size_t /*n_entry*/, + const faiss::idx_t* /*ids*/, + const uint8_t* /*code*/) override { + FAISS_THROW_MSG("unexpected call"); + } + + void update_entries( + size_t /*list_no*/, + size_t /*offset*/, + size_t /*n_entry*/, + const faiss::idx_t* /*ids*/, + const uint8_t* /*code*/) override { + FAISS_THROW_MSG("unexpected call"); + } + + void resize(size_t /*list_no*/, size_t /*new_size*/) override { + FAISS_THROW_MSG("unexpected call"); + } +}; +} // namespace + +TEST(IVF, list_context) { + // this test verifies that the context object is passed + // to the InvertedListsIterator and InvertedLists::add_entry. + // the test InvertedLists and InvertedListsIterator reads/writes + // to the test context object. + // the test verifies the context object is modified as expected. + + constexpr int d = 32; // dimension + constexpr int nb = 100000; // database size + constexpr int nlist = 100; + + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + + // disable parallism, or we need to make Context object + // thread-safe + omp_set_num_threads(1); + + faiss::IndexFlatL2 quantizer(d); // the other index + faiss::IndexIVFFlat index(&quantizer, d, nlist); + TestInvertedLists inverted_lists(nlist, index.code_size); + index.replace_invlists(&inverted_lists); + { + // training + constexpr size_t nt = 1500; // nb of training vectors + std::vector trainvecs(nt * d); + for (size_t i = 0; i < nt * d; i++) { + trainvecs[i] = distrib(rng); + } + index.verbose = true; + index.train(nt, trainvecs.data()); + } + TestContext context; + std::vector query_vector; + constexpr faiss::idx_t query_vector_id = 100; + { + // populating the database + std::vector database(nb * d); + for (size_t i = 0; i < nb * d; i++) { + database[i] = distrib(rng); + // populate the query vector + if (i >= query_vector_id * d && i < query_vector_id * d + d) { + query_vector.push_back(database[i]); + } + } + std::vector coarse_idx(nb); + index.quantizer->assign(nb, database.data(), coarse_idx.data()); + // pass dummy ids, the acutal ids are assigned in TextContext object + std::vector xids(nb, 42); + index.add_core( + nb, database.data(), xids.data(), coarse_idx.data(), &context); + + // check the context object get updated + EXPECT_EQ(nb, context.id) << "should have added all ids"; + EXPECT_EQ(nb, context.codes.size()) + << "should have correct number of codes"; + EXPECT_EQ(nb, context.list_nos.size()) + << "should have correct number of list numbers"; + } + { + constexpr faiss::idx_t k = 100; + constexpr size_t nprobe = 10; + std::vector distances(k); + std::vector labels(k); + faiss::SearchParametersIVF params; + params.inverted_list_context = &context; + params.nprobe = nprobe; + index.search( + 1, + query_vector.data(), + k, + distances.data(), + labels.data(), + ¶ms); + EXPECT_EQ(nprobe, context.lists_probed.size()) + << "should probe nprobe lists"; + + // check the result contains the query vector, the probablity of + // this fail should be low + auto query_vector_listno = context.list_nos[query_vector_id]; + auto& lists_probed = context.lists_probed; + EXPECT_TRUE( + std::find( + lists_probed.cbegin(), + lists_probed.cend(), + query_vector_listno) != lists_probed.cend()) + << "should probe the list of the query vector"; + EXPECT_TRUE( + std::find(labels.cbegin(), labels.cend(), query_vector_id) != + labels.cend()) + << "should return the query vector"; + } +} From 8898eabe9f16e7bbebdc19667c993f7dc55a6a0c Mon Sep 17 00:00:00 2001 From: yuhaijun999 <115384644+yuhaijun999@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:36:36 -0800 Subject: [PATCH 074/206] Add feature in IndexIDMap.cpp range_search with Parameters. (#3213) Summary: for example: #include #include #include #include #include #include #include #include // 64-bit int using idx_t = faiss::idx_t; int main() { int d = 64; // dimension int nb = 10000; // database size int nq = 5; // nb of queries std::mt19937 rng; std::uniform_real_distribution<> distrib; float* xb = new float[d * nb]; float* xq = new float[d * nq]; for (int i = 0; i < nb; i++) { for (int j = 0; j < d; j++) xb[d * i + j] = distrib(rng); xb[d * i] += i / 1000.; } for (int i = 0; i < nq; i++) { for (int j = 0; j < d; j++) xq[d * i + j] = distrib(rng); xq[d * i] += i / 1000.; } faiss::IndexFlatL2 index(d); faiss::IndexIDMap2 index_id_map2(&index); idx_t* xids = new idx_t[nb](); for (int i = 0; i < nb; i++) { xids[i] = i + nb; // add ids } index_id_map2.add_with_ids(nb, xb, xids); faiss::SearchParameters params; std::vector ids; ids.reserve(nb / 2); for (faiss::idx_t i = 0; i < nb / 2; i++) { ids.push_back(i + nb); // search ids } faiss::IDSelectorArray id_selector_array(ids.size(), ids.data()); params.sel = &id_selector_array; // range search with param { float radius = 7.0f; faiss::RangeSearchResult* result = new faiss::RangeSearchResult(nq); index_id_map2.range_search(nq, xb, radius, result, ¶ms); size_t off = 0; for (size_t i = 0; i < result->nq; i++) { size_t n = (result->lims[i + 1] - result->lims[i]); std::cout << "i : " << i << std::endl; for (size_t j = 0; j < n; j++) { std::cout << "\t label : " << result->labels[off + j] << " distance : " << result->distances[off + j] << std::endl; } off += n; } delete result; } delete[] xb; delete[] xq; delete[] xids; return 0; } outputs: server@dingo11 cpp [main] $ ./6-Range-Search i : 0 label : 10000 distance : 0 i : 1 label : 10001 distance : 0 label : 10136 distance : 6.72638 label : 10183 distance : 6.73293 label : 10223 distance : 6.76569 label : 10555 distance : 6.93339 label : 10995 distance : 5.78548 i : 2 label : 10002 distance : 0 label : 10253 distance : 6.84876 label : 10312 distance : 5.07469 i : 3 label : 10003 distance : 0 label : 10983 distance : 6.77275 i : 4 label : 10004 distance : 0 label : 10112 distance : 6.89793 label : 10403 distance : 6.84196 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3213 Reviewed By: mdouze Differential Revision: D53704072 Pulled By: algoriddle fbshipit-source-id: ca7f03f5a474a59089ebdf9685fb83e54ae198b0 --- faiss/IndexIDMap.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/faiss/IndexIDMap.cpp b/faiss/IndexIDMap.cpp index e093bbda83..dc84052b2f 100644 --- a/faiss/IndexIDMap.cpp +++ b/faiss/IndexIDMap.cpp @@ -146,9 +146,16 @@ void IndexIDMapTemplate::range_search( typename IndexT::distance_t radius, RangeSearchResult* result, const SearchParameters* params) const { - FAISS_THROW_IF_NOT_MSG( - !params, "search params not supported for this index"); - index->range_search(n, x, radius, result); + if (params) { + SearchParameters internal_search_parameters; + IDSelectorTranslated id_selector_translated(id_map, params->sel); + internal_search_parameters.sel = &id_selector_translated; + + index->range_search(n, x, radius, result, &internal_search_parameters); + } else { + index->range_search(n, x, radius, result); + } + #pragma omp parallel for for (idx_t i = 0; i < result->lims[result->nq]; i++) { result->labels[i] = result->labels[i] < 0 ? result->labels[i] From f2620119f05e2570b28a54cead864839e82abf8a Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Tue, 13 Feb 2024 12:21:00 -0800 Subject: [PATCH 075/206] fix omp parallelism in fast scan range search Summary: Fix omp n^2 parallelism Reviewed By: mdouze Differential Revision: D53705601 fbshipit-source-id: 3fcc2368c436185119f6e988ee2867dfd7d8eb07 --- faiss/IndexIVFFastScan.cpp | 2 +- tests/CMakeLists.txt | 1 + tests/test_fastscan_perf.cpp | 70 ++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/test_fastscan_perf.cpp diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 855665c617..00bc6c823e 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -643,7 +643,7 @@ void IndexIVFFastScan::range_search_dispatch_implem( { RangeSearchPartialResult pres(&rres); -#pragma omp parallel for reduction(+ : ndis, nlist_visited) +#pragma omp for reduction(+ : ndis, nlist_visited) for (int slice = 0; slice < nslice; slice++) { idx_t i0 = n * slice / nslice; idx_t i1 = n * (slice + 1) / nslice; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1c3266961..8522fa613d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,6 +31,7 @@ set(FAISS_TEST_SRC test_code_distance.cpp test_hnsw.cpp test_partitioning.cpp + test_fastscan_perf.cpp ) add_executable(faiss_test ${FAISS_TEST_SRC}) diff --git a/tests/test_fastscan_perf.cpp b/tests/test_fastscan_perf.cpp new file mode 100644 index 0000000000..82321b2ede --- /dev/null +++ b/tests/test_fastscan_perf.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +TEST(TestFastScan, knnVSrange) { + // small vectors and database + int d = 64; + size_t nb = 1000; + + // ivf centroids + size_t nlist = 4; + + // more than 2 threads to surface + // problems related to multi-threading + omp_set_num_threads(8); + + // random database, also used as queries + std::vector database(nb * d); + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + for (size_t i = 0; i < nb * d; i++) { + database[i] = distrib(rng); + } + + // build index + faiss::IndexFlatL2 coarse_quantizer(d); + faiss::IndexIVFPQFastScan index( + &coarse_quantizer, d, nlist, d / 2, 4, faiss::METRIC_L2, 32); + index.pq.cp.niter = 10; // speed up train + index.nprobe = nlist; + index.train(nb, database.data()); + index.add(nb, database.data()); + + std::vector distances(nb); + std::vector labels(nb); + auto t = std::chrono::high_resolution_clock::now(); + index.search(nb, database.data(), 1, distances.data(), labels.data()); + auto knn_time = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - t) + .count(); + + faiss::RangeSearchResult rsr(nb); + t = std::chrono::high_resolution_clock::now(); + index.range_search(nb, database.data(), 1.0, &rsr); + auto range_time = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - t) + .count(); + + // we expect the perf of knn and range search + // to be similar, at least within a factor of 2 + ASSERT_LT(range_time, knn_time * 2); + ASSERT_LT(knn_time, range_time * 2); +} From a187394a8a72359e7e1a54ca6f160a16ece37b5e Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Wed, 14 Feb 2024 04:38:45 -0800 Subject: [PATCH 076/206] libraft 24.02 is released, switching channel Summary: libraft 24.02 is now in the main channel of rapidsai (and no longer in the nightly), switching channel we build against to prepare for the release of faiss-gpu-raft cmake build will continue to use the nightly, but the conda packages will be built against the release Reviewed By: mlomeli1 Differential Revision: D53712646 fbshipit-source-id: de60c3336e6a199b496fc3829d71a778e5ea8cbd --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5b42164509..94aad3b11e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -168,7 +168,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai-nightly -c conda-forge + -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c conda-forge - when: condition: and: @@ -182,7 +182,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai-nightly -c conda-forge + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c conda-forge build_cmake: parameters: From aaca1c24715b90040d38b2c0aa45a800c58f94e5 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 14 Feb 2024 14:37:40 -0800 Subject: [PATCH 077/206] Remove semicolon(s) from 3 files inc facer/engine/utils/UDPServer.h Summary: `-Wextra-semi` or `-Wextra-semi-stmt` found an extra semi If the code compiles, this is safe to land. Reviewed By: palmje, dmm-fb Differential Revision: D53776211 fbshipit-source-id: c256f5197537251bbe0f583869089b3035a8ee77 --- tests/test_ondisk_ivf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_ondisk_ivf.cpp b/tests/test_ondisk_ivf.cpp index 94c23381eb..7c41e082f8 100644 --- a/tests/test_ondisk_ivf.cpp +++ b/tests/test_ondisk_ivf.cpp @@ -92,7 +92,7 @@ TEST(ONDISK, make_invlists) { } } EXPECT_EQ(ntot, nadd); -}; +} TEST(ONDISK, test_add) { int d = 8; @@ -155,7 +155,7 @@ TEST(ONDISK, test_add) { delete index3; } -}; +} // WARN this thest will run multithreaded only in opt mode TEST(ONDISK, make_invlists_threaded) { @@ -204,4 +204,4 @@ TEST(ONDISK, make_invlists_threaded) { } } EXPECT_EQ(ntot, nadd); -}; +} From 53fc6171a690df495425dcd68acef5abb2a279df Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 14 Feb 2024 15:59:23 -0800 Subject: [PATCH 078/206] Remove unused variables in faiss/tests/test_threaded_index.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779512 fbshipit-source-id: 038967a05306d921cc09f48ae71b4e6d4eda6664 --- tests/test_threaded_index.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_threaded_index.cpp b/tests/test_threaded_index.cpp index b10d3806e0..3dc2660d9e 100644 --- a/tests/test_threaded_index.cpp +++ b/tests/test_threaded_index.cpp @@ -169,7 +169,7 @@ TEST(ThreadedIndex, TestReplica) { int k = 6; // Try with threading and without - for (bool threaded : {true, false}) { + for ([[maybe_unused]] const bool threaded : {true, false}) { std::vector> idxs; faiss::IndexReplicas replica(d); @@ -247,8 +247,6 @@ TEST(ThreadedIndex, TestShards) { shards.search(n, x.data(), k, distances.data(), labels.data()); for (int i = 0; i < idxs.size(); ++i) { - auto perShard = n / idxs.size(); - EXPECT_EQ(idxs[i]->nCalled, n); EXPECT_EQ(idxs[i]->xCalled, x.data()); EXPECT_EQ(idxs[i]->kCalled, k); From 1b0d274f4e334537f16d926af4af2cae6bf0fb74 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 14 Feb 2024 23:14:00 -0800 Subject: [PATCH 079/206] Remove unused variables in faiss/IndexIVF.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779599 fbshipit-source-id: 7f872cecdff078681748d18dfdea78e361a9a72f --- faiss/IndexIVF.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/IndexIVF.cpp b/faiss/IndexIVF.cpp index 65d017aa5a..95d3bc9e68 100644 --- a/faiss/IndexIVF.cpp +++ b/faiss/IndexIVF.cpp @@ -668,7 +668,6 @@ void IndexIVF::search_preassigned( #pragma omp for schedule(dynamic) for (int64_t ij = 0; ij < n * nprobe; ij++) { size_t i = ij / nprobe; - size_t j = ij % nprobe; scanner->set_query(x + i * d); init_result(local_dis.data(), local_idx.data()); From 1338e0de58d7b16ddf6dd8a36e13274c594b308a Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 14 Feb 2024 23:21:12 -0800 Subject: [PATCH 080/206] Remove unused variables in faiss/IndexBinaryIVF.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779472 fbshipit-source-id: 0efad740e4741950ee023ac77c4ca8c2f0d03c61 --- faiss/IndexBinaryIVF.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/IndexBinaryIVF.cpp b/faiss/IndexBinaryIVF.cpp index 1937b1f87d..686785a987 100644 --- a/faiss/IndexBinaryIVF.cpp +++ b/faiss/IndexBinaryIVF.cpp @@ -357,7 +357,6 @@ struct IVFBinaryScannerL2 : BinaryInvertedListScanner { const idx_t* __restrict ids, int radius, RangeQueryResult& result) const override { - size_t nup = 0; for (size_t j = 0; j < n; j++) { uint32_t dis = hc.hamming(codes); if (dis < radius) { @@ -651,7 +650,6 @@ void search_knn_hamming_per_invlist( idx_t max_codes = params ? params->max_codes : ivf->max_codes; FAISS_THROW_IF_NOT(max_codes == 0); FAISS_THROW_IF_NOT(!store_pairs); - MetricType metric_type = ivf->metric_type; // reorder buckets std::vector lims(n + 1); From a87b4320eb548b1e7b49624b51099f69bbbfc04d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 14 Feb 2024 23:58:45 -0800 Subject: [PATCH 081/206] Remove unused variables in faiss/IndexIVFPQ.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779571 fbshipit-source-id: 008ce210aee7eb8668587cb40154563ada0172db --- faiss/IndexIVFPQ.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/IndexIVFPQ.cpp b/faiss/IndexIVFPQ.cpp index 5d02c5ee0e..0b7f4d05d4 100644 --- a/faiss/IndexIVFPQ.cpp +++ b/faiss/IndexIVFPQ.cpp @@ -1046,7 +1046,7 @@ struct IVFPQScannerT : QueryTables { const uint8_t* codes, SearchResultType& res) const { int ht = ivfpq.polysemous_ht; - size_t n_hamming_pass = 0, nup = 0; + size_t n_hamming_pass = 0; int code_size = pq.code_size; From c0624d2346800811530baa32c9407d61d96a8320 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 15 Feb 2024 00:02:37 -0800 Subject: [PATCH 082/206] Remove unused variables in faiss/invlists/OnDiskInvertedLists.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779541 fbshipit-source-id: 7184c46a38d126debaebbda40aedcb4e9a048040 --- faiss/invlists/OnDiskInvertedLists.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/invlists/OnDiskInvertedLists.cpp b/faiss/invlists/OnDiskInvertedLists.cpp index 81f76dbf7f..3017d164c6 100644 --- a/faiss/invlists/OnDiskInvertedLists.cpp +++ b/faiss/invlists/OnDiskInvertedLists.cpp @@ -407,7 +407,7 @@ void OnDiskInvertedLists::update_entries( FAISS_THROW_IF_NOT(!read_only); if (n_entry == 0) return; - const List& l = lists[list_no]; + [[maybe_unused]] const List& l = lists[list_no]; assert(n_entry + offset <= l.size); idx_t* ids = const_cast(get_ids(list_no)); memcpy(ids + offset, ids_in, sizeof(ids_in[0]) * n_entry); From 6d00c416f4ede4f7575d2c58033cdeebbc844494 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 15 Feb 2024 00:14:53 -0800 Subject: [PATCH 083/206] Remove unused variables in faiss/utils/hamming_distance/neon-inl.h Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779537 fbshipit-source-id: 698cdc6720c10d219e56ecd2aad8f4cbe636c639 --- faiss/utils/hamming_distance/neon-inl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/faiss/utils/hamming_distance/neon-inl.h b/faiss/utils/hamming_distance/neon-inl.h index adc09651e3..d8a42f7218 100644 --- a/faiss/utils/hamming_distance/neon-inl.h +++ b/faiss/utils/hamming_distance/neon-inl.h @@ -260,7 +260,6 @@ struct HammingComputer32 { } inline int hamming(const uint8_t* b8) const { - const uint64_t* b = (uint64_t*)b8; uint8x16_t b0 = vld1q_u8(b8); uint8x16_t b1 = vld1q_u8(b8 + 16); From 873b1bc68cec5b6ffc88d0ced7152444fca5587f Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 15 Feb 2024 04:08:09 -0800 Subject: [PATCH 084/206] fix perf test (#3253) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3253 relaxing thresholds + allow equal, duh Reviewed By: mlomeli1 Differential Revision: D53803000 fbshipit-source-id: 7b68386523d9a44a0cd8e099fc1d72b3ed7d5e43 --- tests/test_fastscan_perf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_fastscan_perf.cpp b/tests/test_fastscan_perf.cpp index 82321b2ede..b1d662a224 100644 --- a/tests/test_fastscan_perf.cpp +++ b/tests/test_fastscan_perf.cpp @@ -64,7 +64,7 @@ TEST(TestFastScan, knnVSrange) { .count(); // we expect the perf of knn and range search - // to be similar, at least within a factor of 2 - ASSERT_LT(range_time, knn_time * 2); - ASSERT_LT(knn_time, range_time * 2); + // to be similar, at least within a factor of 4 + ASSERT_LE(range_time, knn_time * 4); + ASSERT_LE(knn_time, range_time * 4); } From 8400ece2b0b3cb05c82d2530403171530fc89c34 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 15 Feb 2024 07:42:30 -0800 Subject: [PATCH 085/206] Remove unused variables in faiss/utils/partitioning.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje Differential Revision: D53779589 fbshipit-source-id: 2631d7b23f2bc79b0468a8d983f74547c15f9c15 --- faiss/utils/partitioning.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/faiss/utils/partitioning.cpp b/faiss/utils/partitioning.cpp index 8d4ee94fb4..4b44126cc7 100644 --- a/faiss/utils/partitioning.cpp +++ b/faiss/utils/partitioning.cpp @@ -206,7 +206,8 @@ typename C::T partition_fuzzy_median3( assert(n_eq_1 <= n_eq); } - int wp = compress_array(vals, ids, n, thresh, n_eq_1); + [[maybe_unused]] const int wp = + compress_array(vals, ids, n, thresh, n_eq_1); assert(wp == q); if (q_out) { From c577f43be6ea332226e9a533cd439396c9784ac8 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 15 Feb 2024 10:38:55 -0800 Subject: [PATCH 086/206] fix perf test (#3255) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3255 Reviewed By: mlomeli1 Differential Revision: D53811550 fbshipit-source-id: b103dc2d0cf43cabb9e4e7e74f4e737ff39fbbbc --- tests/test_fastscan_perf.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/test_fastscan_perf.cpp b/tests/test_fastscan_perf.cpp index b1d662a224..f7d114d738 100644 --- a/tests/test_fastscan_perf.cpp +++ b/tests/test_fastscan_perf.cpp @@ -22,7 +22,7 @@ TEST(TestFastScan, knnVSrange) { // small vectors and database int d = 64; - size_t nb = 1000; + size_t nb = 4000; // ivf centroids size_t nlist = 4; @@ -52,16 +52,12 @@ TEST(TestFastScan, knnVSrange) { std::vector labels(nb); auto t = std::chrono::high_resolution_clock::now(); index.search(nb, database.data(), 1, distances.data(), labels.data()); - auto knn_time = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - t) - .count(); + auto knn_time = std::chrono::high_resolution_clock::now() - t; faiss::RangeSearchResult rsr(nb); t = std::chrono::high_resolution_clock::now(); index.range_search(nb, database.data(), 1.0, &rsr); - auto range_time = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - t) - .count(); + auto range_time = std::chrono::high_resolution_clock::now() - t; // we expect the perf of knn and range search // to be similar, at least within a factor of 4 From 87d43b95295890220eafda3e0c63369e69325662 Mon Sep 17 00:00:00 2001 From: Jim Borden Date: Thu, 15 Feb 2024 14:05:04 -0800 Subject: [PATCH 087/206] Fix AVX2 build on Windows (#3238) Summary: Tested with both MSVC (with /openmp:llvm) and clang-cl (no particular extra flags needed). This PR is separated into two commits (three after I found out that lines need to be 80 chars or less): 1. Changes needed for clang-cl (and probably stock clang too) 2. Changes needed for MSVC So FAISS can decide either to require using LLVM for Windows (not a hard thing to do these days since it is fully supported inside Visual Studio) and discarding the second commits, or taking them all and documenting the need to use /openmp:llvm Closes https://github.com/facebookresearch/faiss/issues/3193 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3238 Reviewed By: mdouze Differential Revision: D53479325 Pulled By: algoriddle fbshipit-source-id: e8628f44626b6f49c5d9d7f259a9e3061cfe5568 --- faiss/impl/LocalSearchQuantizer.cpp | 4 +++- faiss/impl/platform_macros.h | 9 +++++++++ faiss/utils/distances.cpp | 8 ++++---- faiss/utils/distances_fused/simdlib_based.cpp | 2 +- faiss/utils/distances_simd.cpp | 18 +++++++++--------- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/faiss/impl/LocalSearchQuantizer.cpp b/faiss/impl/LocalSearchQuantizer.cpp index abbfe74901..8da989a9a4 100644 --- a/faiss/impl/LocalSearchQuantizer.cpp +++ b/faiss/impl/LocalSearchQuantizer.cpp @@ -628,7 +628,9 @@ void LocalSearchQuantizer::icm_encode_step( { size_t binary_idx = (other_m + 1) * M * K * K + m * K * K + code2 * K + code; - _mm_prefetch(binaries + binary_idx, _MM_HINT_T0); + _mm_prefetch( + (const char*)(binaries + binary_idx), + _MM_HINT_T0); } } #endif diff --git a/faiss/impl/platform_macros.h b/faiss/impl/platform_macros.h index aeafb9531a..2aecc51222 100644 --- a/faiss/impl/platform_macros.h +++ b/faiss/impl/platform_macros.h @@ -40,11 +40,13 @@ #include +#ifndef __clang__ inline int __builtin_ctzll(uint64_t x) { unsigned long ret; _BitScanForward64(&ret, x); return (int)ret; } +#endif // cudatoolkit provides __builtin_ctz for NVCC >= 11.0 #if !defined(__CUDACC__) || __CUDACC_VER_MAJOR__ < 11 @@ -55,13 +57,20 @@ inline int __builtin_ctz(unsigned long x) { } #endif +#ifndef __clang__ inline int __builtin_clzll(uint64_t x) { return (int)__lzcnt64(x); } +#endif #define __builtin_popcount __popcnt #define __builtin_popcountl __popcnt64 +#ifndef __clang__ +#define __m128i_u __m128i +#define __m256i_u __m256i +#endif + // MSVC does not define __SSEx__, and _M_IX86_FP is only defined on 32-bit // processors cf. // https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros diff --git a/faiss/utils/distances.cpp b/faiss/utils/distances.cpp index ebc3329c28..82bc164ae1 100644 --- a/faiss/utils/distances.cpp +++ b/faiss/utils/distances.cpp @@ -417,8 +417,8 @@ void exhaustive_L2sqr_blas_cmax_avx2( for (int64_t i = i0; i < i1; i++) { float* ip_line = ip_block.get() + (i - i0) * (j1 - j0); - _mm_prefetch(ip_line, _MM_HINT_NTA); - _mm_prefetch(ip_line + 16, _MM_HINT_NTA); + _mm_prefetch((const char*)ip_line, _MM_HINT_NTA); + _mm_prefetch((const char*)(ip_line + 16), _MM_HINT_NTA); // constant const __m256 mul_minus2 = _mm256_set1_ps(-2); @@ -445,8 +445,8 @@ void exhaustive_L2sqr_blas_cmax_avx2( // process 16 elements per loop for (; idx_j < (count / 16) * 16; idx_j += 16, ip_line += 16) { - _mm_prefetch(ip_line + 32, _MM_HINT_NTA); - _mm_prefetch(ip_line + 48, _MM_HINT_NTA); + _mm_prefetch((const char*)(ip_line + 32), _MM_HINT_NTA); + _mm_prefetch((const char*)(ip_line + 48), _MM_HINT_NTA); // load values for norms const __m256 y_norm_0 = diff --git a/faiss/utils/distances_fused/simdlib_based.cpp b/faiss/utils/distances_fused/simdlib_based.cpp index 31239e866b..309fb72118 100644 --- a/faiss/utils/distances_fused/simdlib_based.cpp +++ b/faiss/utils/distances_fused/simdlib_based.cpp @@ -73,7 +73,7 @@ void kernel( // prefetch the next point #if defined(__AVX2__) - _mm_prefetch(xd_0 + DIM * sizeof(float), _MM_HINT_NTA); + _mm_prefetch((const char*)(xd_0 + DIM * sizeof(float)), _MM_HINT_NTA); #endif // load a single point from x diff --git a/faiss/utils/distances_simd.cpp b/faiss/utils/distances_simd.cpp index d74ca664be..323859f43b 100644 --- a/faiss/utils/distances_simd.cpp +++ b/faiss/utils/distances_simd.cpp @@ -439,14 +439,14 @@ void fvec_op_ny_D2( if (ny8 > 0) { // process 8 D2-vectors per loop. - _mm_prefetch(y, _MM_HINT_T0); - _mm_prefetch(y + 16, _MM_HINT_T0); + _mm_prefetch((const char*)y, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 16), _MM_HINT_T0); const __m256 m0 = _mm256_set1_ps(x[0]); const __m256 m1 = _mm256_set1_ps(x[1]); for (i = 0; i < ny8 * 8; i += 8) { - _mm_prefetch(y + 32, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 32), _MM_HINT_T0); // load 8x2 matrix and transpose it in registers. // the typical bottleneck is memory access, so @@ -496,14 +496,14 @@ void fvec_op_ny_D2( if (ny8 > 0) { // process 8 D2-vectors per loop. - _mm_prefetch(y, _MM_HINT_T0); - _mm_prefetch(y + 16, _MM_HINT_T0); + _mm_prefetch((const char*)y, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 16), _MM_HINT_T0); const __m256 m0 = _mm256_set1_ps(x[0]); const __m256 m1 = _mm256_set1_ps(x[1]); for (i = 0; i < ny8 * 8; i += 8) { - _mm_prefetch(y + 32, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 32), _MM_HINT_T0); // load 8x2 matrix and transpose it in registers. // the typical bottleneck is memory access, so @@ -1084,8 +1084,8 @@ size_t fvec_L2sqr_ny_nearest_D2( // process 8 D2-vectors per loop. const size_t ny8 = ny / 8; if (ny8 > 0) { - _mm_prefetch(y, _MM_HINT_T0); - _mm_prefetch(y + 16, _MM_HINT_T0); + _mm_prefetch((const char*)y, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 16), _MM_HINT_T0); // track min distance and the closest vector independently // for each of 8 AVX2 components. @@ -1100,7 +1100,7 @@ size_t fvec_L2sqr_ny_nearest_D2( const __m256 m1 = _mm256_set1_ps(x[1]); for (; i < ny8 * 8; i += 8) { - _mm_prefetch(y + 32, _MM_HINT_T0); + _mm_prefetch((const char*)(y + 32), _MM_HINT_T0); __m256 v0; __m256 v1; From 27b1055cc6c9a70b8822ec5dbdd54b43b69a47e1 Mon Sep 17 00:00:00 2001 From: Tarang Jain Date: Wed, 21 Feb 2024 06:41:08 -0800 Subject: [PATCH 088/206] Integrate IVF-PQ from RAFT (#3044) Summary: Imports changes from https://github.com/facebookresearch/faiss/issues/3133 and https://github.com/facebookresearch/faiss/issues/3171. So this single PR adds all the changes together. - [x] Implement RaftIVFPQ class - [x] Update gtests to test correctness with RAFT enabled - [x] All googleTests for RAFT enabled IVFPQ pass - [x] Move some common functions in RaftIVFFlat and RaftIVFPQ to helper: RaftUtils.h - [x] update Quantizer retroactively after building RAFT index -- both IVFFlat and IVFPQ - [x] resolve failing LargeBatch (classical GPU) - [x] add checks for Pascal deprecation - [x] apply RMM changes from https://github.com/facebookresearch/faiss/issues/3171 - [x] apply robertmaynard's changes from https://github.com/facebookresearch/faiss/issues/3133 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3044 Reviewed By: junjieqi Differential Revision: D51074065 Pulled By: algoriddle fbshipit-source-id: 6871257921bcaff2064a20637e2ed358acbdc363 --- CMakeLists.txt | 6 +- benchs/bench_ivfflat_raft.py | 193 ++++++++ benchs/bench_ivfpq_raft.py | 168 +++++++ cmake/thirdparty/fetch_rapids.cmake | 2 +- faiss/gpu/CMakeLists.txt | 31 +- faiss/gpu/GpuCloner.cpp | 7 +- faiss/gpu/GpuClonerOptions.h | 4 + faiss/gpu/GpuDistance.cu | 21 +- faiss/gpu/GpuDistance.h | 7 + faiss/gpu/GpuIndex.cu | 15 +- faiss/gpu/GpuIndex.h | 8 + faiss/gpu/GpuIndexFlat.cu | 10 +- faiss/gpu/GpuIndexIVF.cu | 51 +- faiss/gpu/GpuIndexIVFFlat.cu | 200 +++++--- faiss/gpu/GpuIndexIVFFlat.h | 4 +- faiss/gpu/GpuIndexIVFPQ.cu | 313 +++++++++--- faiss/gpu/GpuIndexIVFPQ.h | 19 +- faiss/gpu/GpuResources.h | 5 + faiss/gpu/StandardGpuResources.cpp | 39 +- faiss/gpu/StandardGpuResources.h | 11 +- faiss/gpu/impl/IVFBase.cuh | 4 +- faiss/gpu/impl/IVFPQ.cuh | 4 +- faiss/gpu/impl/RaftFlatIndex.cu | 4 +- faiss/gpu/impl/RaftFlatIndex.cuh | 2 + faiss/gpu/impl/RaftIVFFlat.cu | 250 ++++------ faiss/gpu/impl/RaftIVFFlat.cuh | 23 +- faiss/gpu/impl/RaftIVFPQ.cu | 546 +++++++++++++++++++++ faiss/gpu/impl/RaftIVFPQ.cuh | 150 ++++++ faiss/gpu/test/TestGpuIndexFlat.cpp | 1 + faiss/gpu/test/TestGpuIndexIVFFlat.cpp | 51 +- faiss/gpu/test/TestGpuIndexIVFPQ.cpp | 507 +++++++++++-------- faiss/gpu/test/TestGpuMemoryException.cpp | 1 + faiss/gpu/test/test_gpu_index.py | 24 +- faiss/gpu/test/test_gpu_index_ivfsq.py | 12 +- faiss/gpu/test/test_gpu_index_serialize.py | 11 +- faiss/gpu/test/test_multi_gpu.py | 8 +- faiss/gpu/utils/CopyUtils.cuh | 1 + faiss/gpu/utils/RaftUtils.cu | 117 +++++ faiss/gpu/{impl => utils}/RaftUtils.h | 22 +- tests/CMakeLists.txt | 1 + 40 files changed, 2199 insertions(+), 654 deletions(-) create mode 100644 benchs/bench_ivfflat_raft.py create mode 100644 benchs/bench_ivfpq_raft.py create mode 100644 faiss/gpu/impl/RaftIVFPQ.cu create mode 100644 faiss/gpu/impl/RaftIVFPQ.cuh create mode 100644 faiss/gpu/utils/RaftUtils.cu rename faiss/gpu/{impl => utils}/RaftUtils.h (73%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85c8a820bc..445b39d59e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,9 +62,9 @@ if(FAISS_ENABLE_GPU) enable_language(CUDA) endif() -if(FAISS_ENABLE_RAFT) - find_package(raft COMPONENTS compiled distributed) -endif() +if(FAISS_ENABLE_RAFT AND NOT TARGET raft::raft) + find_package(raft COMPONENTS compiled distributed) + endif() add_subdirectory(faiss) diff --git a/benchs/bench_ivfflat_raft.py b/benchs/bench_ivfflat_raft.py new file mode 100644 index 0000000000..9ebfcb3422 --- /dev/null +++ b/benchs/bench_ivfflat_raft.py @@ -0,0 +1,193 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import numpy as np +import faiss +import time +import argparse +import rmm + +###################################################### +# Command-line parsing +###################################################### + +parser = argparse.ArgumentParser() + + +def aa(*args, **kwargs): + group.add_argument(*args, **kwargs) + + +group = parser.add_argument_group('benchmarking options') + +aa('--bm_train', default=False, action='store_true', + help='whether to benchmark train operation on GPU index') +aa('--bm_add', default=False, action='store_true', + help='whether to benchmark add operation on GPU index') +aa('--bm_search', default=True, + help='whether to benchmark search operation on GPU index') +aa('--raft_only', default=False, action='store_true', + help='whether to only produce RAFT enabled benchmarks') + + +group = parser.add_argument_group('IVF options') +aa('--n_centroids', default=256, type=int, + help="number of IVF centroids") + + +group = parser.add_argument_group('searching') + +aa('--k', default=100, type=int, help='nb of nearest neighbors') +aa('--nprobe', default=50, help='nb of IVF lists to probe') + +args = parser.parse_args() + +print("args:", args) + +rs = np.random.RandomState(123) + +res = faiss.StandardGpuResources() + +# Use an RMM pool memory resource for device allocations +mr = rmm.mr.PoolMemoryResource(rmm.mr.CudaMemoryResource()) +rmm.mr.set_current_device_resource(mr) + +def bench_train_milliseconds(index, trainVecs, use_raft): + co = faiss.GpuMultipleClonerOptions() + co.use_raft = use_raft + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + t0 = time.time() + index_gpu.train(trainVecs) + return 1000*(time.time() - t0) + + +if args.bm_train: + print("=" * 40) + print("GPU Train Benchmarks") + print("=" * 40) + trainset_sizes = [5000, 10000, 100000, 1000000, 5000000] + dataset_dims = [128, 256, 1024] + for n_rows in trainset_sizes: + for n_cols in dataset_dims: + index = faiss.index_factory(n_cols, "IVF{},Flat".format(args.n_centroids)) + trainVecs = rs.rand(n_rows, n_cols).astype('float32') + raft_gpu_train_time = bench_train_milliseconds( + index, trainVecs, True) + if args.raft_only: + print("Method: IVFFlat, Operation: TRAIN, dim: %d, n_centroids %d, numTrain: %d, RAFT enabled GPU train time: %.3f milliseconds" % ( + n_cols, args.n_centroids, n_rows, raft_gpu_train_time)) + else: + classical_gpu_train_time = bench_train_milliseconds( + index, trainVecs, False) + print("Method: IVFFlat, Operation: TRAIN, dim: %d, n_centroids %d, numTrain: %d, classical GPU train time: %.3f milliseconds, RAFT enabled GPU train time: %.3f milliseconds" % ( + n_cols, args.n_centroids, n_rows, classical_gpu_train_time, raft_gpu_train_time)) + + +def bench_add_milliseconds(index, addVecs, use_raft): + co = faiss.GpuMultipleClonerOptions() + co.use_raft = use_raft + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + index_gpu.copyFrom(index) + t0 = time.time() + index_gpu.add(addVecs) + return 1000*(time.time() - t0) + + +if args.bm_add: + print("=" * 40) + print("GPU Add Benchmarks") + print("=" * 40) + addset_sizes = [5000, 10000, 100000, 1000000] + dataset_dims = [128, 256, 1024] + n_train = 10000 + trainVecs = rs.rand(n_train, n_cols).astype('float32') + index = faiss.index_factory( + n_cols, "IVF" + str(args.n_centroids) + ",Flat") + index.train(trainVecs) + for n_rows in addset_sizes: + for n_cols in dataset_dims: + addVecs = rs.rand(n_rows, n_cols).astype('float32') + raft_gpu_add_time = bench_add_milliseconds(index, addVecs, True) + if args.raft_only: + print("Method: IVFFlat, Operation: ADD, dim: %d, n_centroids %d, numAdd: %d, RAFT enabled GPU add time: %.3f milliseconds" % ( + n_train, n_rows, n_cols, args.n_centroids, raft_gpu_add_time)) + else: + classical_gpu_add_time = bench_add_milliseconds( + index, addVecs, False) + print("Method: IVFFlat, Operation: ADD, dim: %d, n_centroids %d, numAdd: %d, classical GPU add time: %.3f milliseconds, RAFT enabled GPU add time: %.3f milliseconds" % ( + n_train, n_rows, n_cols, args.n_centroids, classical_gpu_add_time, raft_gpu_add_time)) + + +def bench_search_milliseconds(index, addVecs, queryVecs, nprobe, k, use_raft): + co = faiss.GpuMultipleClonerOptions() + co.use_raft = use_raft + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + index_gpu.copyFrom(index) + index_gpu.add(addVecs) + index_gpu.nprobe = nprobe + t0 = time.time() + index_gpu.search(queryVecs, k) + return 1000*(time.time() - t0) + + +if args.bm_search: + print("=" * 40) + print("GPU Search Benchmarks") + print("=" * 40) + queryset_sizes = [5000, 10000, 100000, 500000] + n_train = 10000 + n_add = 100000 + search_bm_dims = [8, 16, 32] + for n_cols in search_bm_dims: + index = faiss.index_factory(n_cols, "IVF{},Flat".format(args.n_centroids)) + trainVecs = rs.rand(n_train, n_cols).astype('float32') + index.train(trainVecs) + addVecs = rs.rand(n_add, n_cols).astype('float32') + for n_rows in queryset_sizes: + queryVecs = rs.rand(n_rows, n_cols).astype('float32') + raft_gpu_search_time = bench_search_milliseconds( + index, addVecs, queryVecs, args.nprobe, args.k, True) + if args.raft_only: + print("Method: IVFFlat, Operation: SEARCH, dim: %d, n_centroids: %d, numVecs: %d, numQuery: %d, nprobe: %d, k: %d, RAFT enabled GPU search time: %.3f milliseconds" % ( + n_cols, args.n_centroids, n_add, n_rows, args.nprobe, args.k, raft_gpu_search_time)) + else: + classical_gpu_search_time = bench_search_milliseconds( + index, addVecs, queryVecs, args.nprobe, args.k, False) + print("Method: IVFFlat, Operation: SEARCH, dim: %d, n_centroids: %d, numVecs: %d, numQuery: %d, nprobe: %d, k: %d, classical GPU search time: %.3f milliseconds, RAFT enabled GPU search time: %.3f milliseconds" % ( + n_cols, args.n_centroids, n_add, n_rows, args.nprobe, args.k, classical_gpu_search_time, raft_gpu_search_time)) + + print("=" * 40) + print("Large RAFT Enabled Benchmarks") + print("=" * 40) + # Avoid classical GPU Benchmarks for large datasets because of OOM for more than 500000 queries and/or large dims as well as for large k + queryset_sizes = [100000, 500000, 1000000] + large_search_bm_dims = [128, 256, 1024] + for n_cols in large_search_bm_dims: + trainVecs = rs.rand(n_train, n_cols).astype('float32') + index = faiss.index_factory( + n_cols, "IVF" + str(args.n_centroids) + ",Flat") + index.train(trainVecs) + addVecs = rs.rand(n_add, n_cols).astype('float32') + for n_rows in queryset_sizes: + queryVecs = rs.rand(n_rows, n_cols).astype('float32') + raft_gpu_search_time = bench_search_milliseconds( + index, addVecs, queryVecs, args.nprobe, args.k, True) + print("Method: IVFFlat, Operation: SEARCH, numTrain: %d, dim: %d, n_centroids: %d, numVecs: %d, numQuery: %d, nprobe: %d, k: %d, RAFT enabled GPU search time: %.3f milliseconds" % ( + n_cols, args.n_centroids, n_add, n_rows, args.nprobe, args.k, raft_gpu_search_time)) diff --git a/benchs/bench_ivfpq_raft.py b/benchs/bench_ivfpq_raft.py new file mode 100644 index 0000000000..3494a18741 --- /dev/null +++ b/benchs/bench_ivfpq_raft.py @@ -0,0 +1,168 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# +# Copyright (c) 2023, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import numpy as np +import faiss +import time +import argparse +import rmm + +###################################################### +# Command-line parsing +###################################################### + +parser = argparse.ArgumentParser() + +from datasets import load_sift1M, evaluate + + +print("load data") +xb, xq, xt, gt = load_sift1M() + +def aa(*args, **kwargs): + group.add_argument(*args, **kwargs) + + +group = parser.add_argument_group('benchmarking options') +aa('--raft_only', default=False, action='store_true', + help='whether to only produce RAFT enabled benchmarks') + +group = parser.add_argument_group('IVF options') +aa('--bits_per_code', default=8, type=int, help='bits per code. Note that < 8 is only supported when RAFT is enabled') +aa('--pq_len', default=2, type=int, help='number of vector elements represented by one PQ code') +aa('--use_precomputed', default=True, type=bool, help='use precomputed codes (not with RAFT enabled)') + +group = parser.add_argument_group('searching') +aa('--k', default=10, type=int, help='nb of nearest neighbors') +aa('--nprobe', default=50, type=int, help='nb of IVF lists to probe') + +args = parser.parse_args() + +print("args:", args) + +rs = np.random.RandomState(123) + +res = faiss.StandardGpuResources() + +# Use an RMM pool memory resource for device allocations +mr = rmm.mr.PoolMemoryResource(rmm.mr.CudaMemoryResource()) +rmm.mr.set_current_device_resource(mr) + +# A heuristic to select a suitable number of lists +def compute_nlist(numVecs): + nlist = np.sqrt(numVecs) + if (numVecs / nlist < 1000): + nlist = numVecs / 1000 + return int(nlist) + + +def bench_train_milliseconds(index, trainVecs, use_raft): + co = faiss.GpuMultipleClonerOptions() + # use float 16 lookup tables to save space + co.useFloat16LookupTables = True + co.use_raft = use_raft + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + t0 = time.time() + index_gpu.train(trainVecs) + return 1000*(time.time() - t0) + +n_rows, n_cols = xb.shape +n_train, _ = xt.shape +M = n_cols // args.pq_len +nlist = compute_nlist(n_rows) +index = faiss.index_factory(n_cols, "IVF{},PQ{}x{}np".format(nlist, M, args.bits_per_code)) + +print("=" * 40) +print("GPU Train Benchmarks") +print("=" * 40) +raft_gpu_train_time = bench_train_milliseconds(index, xt, True) +if args.raft_only: + print("Method: IVFPQ, Operation: TRAIN, dim: %d, n_centroids %d, numSubQuantizers %d, bitsPerCode %d, numTrain: %d, RAFT enabled GPU train time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_train, raft_gpu_train_time)) +else: + classical_gpu_train_time = bench_train_milliseconds( + index, xt, False) + print("Method: IVFPQ, Operation: TRAIN, dim: %d, n_centroids %d, numSubQuantizers %d, bitsPerCode %d, numTrain: %d, classical GPU train time: %.3f milliseconds, RAFT enabled GPU train time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_train, classical_gpu_train_time, raft_gpu_train_time)) + + +def bench_add_milliseconds(index, addVecs, use_raft): + co = faiss.GpuMultipleClonerOptions() + # use float 16 lookup tables to save space + co.useFloat16LookupTables = True + co.use_raft = use_raft + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + index_gpu.copyFrom(index) + t0 = time.time() + index_gpu.add(addVecs) + return 1000*(time.time() - t0) + +print("=" * 40) +print("GPU Add Benchmarks") +print("=" * 40) +index.train(xt) +raft_gpu_add_time = bench_add_milliseconds(index, xb, True) +if args.raft_only: + print("Method: IVFPQ, Operation: ADD, dim: %d, n_centroids %d numSubQuantizers %d, bitsPerCode %d, numAdd %d, RAFT enabled GPU add time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_rows, raft_gpu_add_time)) +else: + classical_gpu_add_time = bench_add_milliseconds( + index, xb, False) + print("Method: IVFFPQ, Operation: ADD, dim: %d, n_centroids %d, numSubQuantizers %d, bitsPerCode %d, numAdd %d, classical GPU add time: %.3f milliseconds, RAFT enabled GPU add time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_rows, classical_gpu_add_time, raft_gpu_add_time)) + + +def bench_search_milliseconds(index, addVecs, queryVecs, nprobe, k, use_raft): + co = faiss.GpuMultipleClonerOptions() + co.use_raft = use_raft + co.useFloat16LookupTables = True + index_gpu = faiss.index_cpu_to_gpu(res, 0, index, co) + index_gpu.copyFrom(index) + index_gpu.add(addVecs) + index_gpu.nprobe = nprobe + t0 = time.time() + index_gpu.search(queryVecs, k) + return 1000*(time.time() - t0) + + +if args.bm_search: + print("=" * 40) + print("GPU Search Benchmarks") + print("=" * 40) + queryset_sizes = [1, 10, 100, 1000, 10000] + n_train, n_cols = xt.shape + n_add, _ = xb.shape + print(xq.shape) + M = n_cols // args.pq_len + nlist = compute_nlist(n_add) + index = faiss.index_factory(n_cols, "IVF{},PQ{}x{}np".format(nlist, M, args.bits_per_code)) + index.train(xt) + for n_rows in queryset_sizes: + queryVecs = xq[np.random.choice(xq.shape[0], n_rows, replace=False)] + raft_gpu_search_time = bench_search_milliseconds( + index, xb, queryVecs, args.nprobe, args.k, True) + if args.raft_only: + print("Method: IVFPQ, Operation: SEARCH, dim: %d, n_centroids: %d, numSubQuantizers %d, bitsPerCode %d, numVecs: %d, numQuery: %d, nprobe: %d, k: %d, RAFT enabled GPU search time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_add, n_rows, args.nprobe, args.k, raft_gpu_search_time)) + else: + classical_gpu_search_time = bench_search_milliseconds( + index, xb, queryVecs, args.nprobe, args.k, False) + print("Method: IVFPQ, Operation: SEARCH, dim: %d, n_centroids: %d, numSubQuantizers %d, bitsPerCode %d, numVecs: %d, numQuery: %d, nprobe: %d, k: %d, classical GPU search time: %.3f milliseconds, RAFT enabled GPU search time: %.3f milliseconds" % ( + n_cols, nlist, M, args.bits_per_code, n_add, n_rows, args.nprobe, args.k, classical_gpu_search_time, raft_gpu_search_time)) \ No newline at end of file diff --git a/cmake/thirdparty/fetch_rapids.cmake b/cmake/thirdparty/fetch_rapids.cmake index 32ec15b6a4..3e0f6b6ac4 100644 --- a/cmake/thirdparty/fetch_rapids.cmake +++ b/cmake/thirdparty/fetch_rapids.cmake @@ -15,7 +15,7 @@ # or implied. See the License for the specific language governing permissions and limitations under # the License. # ============================================================================= -set(RAPIDS_VERSION "23.12") +set(RAPIDS_VERSION "24.02") if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/FAISS_RAPIDS.cmake) file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-${RAPIDS_VERSION}/RAPIDS.cmake diff --git a/faiss/gpu/CMakeLists.txt b/faiss/gpu/CMakeLists.txt index 713d3a287c..126cbe5044 100644 --- a/faiss/gpu/CMakeLists.txt +++ b/faiss/gpu/CMakeLists.txt @@ -238,12 +238,15 @@ generate_ivf_interleaved_code() if(FAISS_ENABLE_RAFT) list(APPEND FAISS_GPU_HEADERS - impl/RaftUtils.h + impl/RaftFlatIndex.cuh impl/RaftIVFFlat.cuh - impl/RaftFlatIndex.cuh) + impl/RaftIVFPQ.cuh + utils/RaftUtils.h) list(APPEND FAISS_GPU_SRC impl/RaftFlatIndex.cu - impl/RaftIVFFlat.cu) + impl/RaftIVFFlat.cu + impl/RaftIVFPQ.cu + utils/RaftUtils.cu) endif() add_library(faiss_gpu STATIC ${FAISS_GPU_SRC}) @@ -258,6 +261,28 @@ if(FAISS_ENABLE_RAFT) target_compile_definitions(faiss PUBLIC USE_NVIDIA_RAFT=1) target_compile_definitions(faiss_avx2 PUBLIC USE_NVIDIA_RAFT=1) target_compile_definitions(faiss_avx512 PUBLIC USE_NVIDIA_RAFT=1) + + # Mark all functions as hidden so that we don't generate + # global 'public' functions that also exist in libraft.so + # + # This ensures that faiss functions will call the local version + # inside libfaiss.so . This is needed to ensure that things + # like raft cublas resources are created and used within the same + # dynamic library + CUDA runtime context which are requirements + # for valid execution + # + # To still allow these classes to be used by consumers, the + # respective classes/types in the headers are explicitly marked + # as 'public' so they can be used by consumers + set_source_files_properties( + GpuDistance.cu + StandardGpuResources.cpp + impl/RaftFlatIndex.cu + impl/RaftIVFFlat.cu + impl/RaftIVFPQ.cu + utils/RaftUtils.cu + TARGET_DIRECTORY faiss + PROPERTIES COMPILE_OPTIONS "-fvisibility=hidden") target_compile_definitions(faiss_gpu PUBLIC USE_NVIDIA_RAFT=1) endif() diff --git a/faiss/gpu/GpuCloner.cpp b/faiss/gpu/GpuCloner.cpp index 4dc51f9e83..20583720f3 100644 --- a/faiss/gpu/GpuCloner.cpp +++ b/faiss/gpu/GpuCloner.cpp @@ -152,8 +152,7 @@ Index* ToGpuCloner::clone_Index(const Index* index) { config.device = device; config.indicesOptions = indicesOptions; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; - FAISS_THROW_IF_NOT_MSG( - !use_raft, "this type of index is not implemented for RAFT"); + config.use_raft = use_raft; GpuIndexIVFFlat* res = new GpuIndexIVFFlat( provider, ifl->d, ifl->nlist, ifl->metric_type, config); @@ -204,8 +203,8 @@ Index* ToGpuCloner::clone_Index(const Index* index) { config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; config.useFloat16LookupTables = useFloat16; config.usePrecomputedTables = usePrecomputed; - FAISS_THROW_IF_NOT_MSG( - !use_raft, "this type of index is not implemented for RAFT"); + config.use_raft = use_raft; + config.interleavedLayout = use_raft; GpuIndexIVFPQ* res = new GpuIndexIVFPQ(provider, ipq, config); diff --git a/faiss/gpu/GpuClonerOptions.h b/faiss/gpu/GpuClonerOptions.h index fbde4c4ea4..197e09dc88 100644 --- a/faiss/gpu/GpuClonerOptions.h +++ b/faiss/gpu/GpuClonerOptions.h @@ -38,7 +38,11 @@ struct GpuClonerOptions { bool verbose = false; /// use the RAFT implementation +#if defined USE_NVIDIA_RAFT + bool use_raft = true; +#else bool use_raft = false; +#endif }; struct GpuMultipleClonerOptions : public GpuClonerOptions { diff --git a/faiss/gpu/GpuDistance.cu b/faiss/gpu/GpuDistance.cu index c363aa4bb8..a235404b14 100644 --- a/faiss/gpu/GpuDistance.cu +++ b/faiss/gpu/GpuDistance.cu @@ -31,7 +31,7 @@ #include #if defined USE_NVIDIA_RAFT -#include +#include #include #include #include @@ -51,6 +51,17 @@ using namespace raft::distance; using namespace raft::neighbors; #endif +bool should_use_raft(GpuDistanceParams args) { + cudaDeviceProp prop; + int dev = args.device >= 0 ? args.device : getCurrentDevice(); + cudaGetDeviceProperties(&prop, dev); + + if (prop.major < 7) + return false; + + return args.use_raft; +} + template void bfKnnConvert(GpuResourcesProvider* prov, const GpuDistanceParams& args) { // Validate the input data @@ -228,8 +239,8 @@ void bfKnn(GpuResourcesProvider* prov, const GpuDistanceParams& args) { #if defined USE_NVIDIA_RAFT // Note: For now, RAFT bfknn requires queries and vectors to be same layout - if (args.use_raft && args.queriesRowMajor == args.vectorsRowMajor) { - DistanceType distance = faiss_to_raft(args.metric, false); + if (should_use_raft(args) && args.queriesRowMajor == args.vectorsRowMajor) { + DistanceType distance = metricFaissToRaft(args.metric, false); auto resImpl = prov->getResources(); auto res = resImpl.get(); @@ -349,9 +360,9 @@ void bfKnn(GpuResourcesProvider* prov, const GpuDistanceParams& args) { RAFT_LOG_INFO("All synced."); } else #else - if (args.use_raft) { + if (should_use_raft(args)) { FAISS_THROW_IF_NOT_MSG( - !args.use_raft, + !should_use_raft(args), "RAFT has not been compiled into the current version so it cannot be used."); } else #endif diff --git a/faiss/gpu/GpuDistance.h b/faiss/gpu/GpuDistance.h index c0dde7fd8c..17dbee617b 100644 --- a/faiss/gpu/GpuDistance.h +++ b/faiss/gpu/GpuDistance.h @@ -9,6 +9,7 @@ #include +#pragma GCC visibility push(default) namespace faiss { namespace gpu { @@ -106,9 +107,14 @@ struct GpuDistanceParams { int device = -1; /// Should the index dispatch down to RAFT? + /// TODO: change default to true if RAFT is enabled bool use_raft = false; }; +/// A function that determines whether RAFT should be used based on various +/// conditions (such as unsupported architecture) +bool should_use_raft(GpuDistanceParams args); + /// A wrapper for gpu/impl/Distance.cuh to expose direct brute-force k-nearest /// neighbor searches on an externally-provided region of memory (e.g., from a /// pytorch tensor). @@ -168,3 +174,4 @@ void bruteForceKnn( } // namespace gpu } // namespace faiss +#pragma GCC visibility pop diff --git a/faiss/gpu/GpuIndex.cu b/faiss/gpu/GpuIndex.cu index 89952b1121..d667ae1494 100644 --- a/faiss/gpu/GpuIndex.cu +++ b/faiss/gpu/GpuIndex.cu @@ -42,6 +42,16 @@ constexpr idx_t kAddVecSize = (idx_t)512 * 1024; // FIXME: parameterize based on algorithm need constexpr idx_t kSearchVecSize = (idx_t)32 * 1024; +bool should_use_raft(GpuIndexConfig config_) { + cudaDeviceProp prop; + cudaGetDeviceProperties(&prop, config_.device); + + if (prop.major < 7) + return false; + + return config_.use_raft; +} + GpuIndex::GpuIndex( std::shared_ptr resources, int dims, @@ -64,7 +74,7 @@ GpuIndex::GpuIndex( (config_.memorySpace == MemorySpace::Unified && getFullUnifiedMemSupport(config_.device)), "Device %d does not support full CUDA 8 Unified Memory (CC 6.0+)", - config.device); + config_.device); metric_arg = metricArg; @@ -132,7 +142,8 @@ void GpuIndex::addPaged_(idx_t n, const float* x, const idx_t* ids) { if (n > 0) { idx_t totalSize = n * this->d * sizeof(float); - if (totalSize > kAddPageSize || n > kAddVecSize) { + if (!should_use_raft(config_) && + (totalSize > kAddPageSize || n > kAddVecSize)) { // How many vectors fit into kAddPageSize? idx_t maxNumVecsForPageSize = kAddPageSize / (this->d * sizeof(float)); diff --git a/faiss/gpu/GpuIndex.h b/faiss/gpu/GpuIndex.h index 629a57583d..36de98c098 100644 --- a/faiss/gpu/GpuIndex.h +++ b/faiss/gpu/GpuIndex.h @@ -38,9 +38,17 @@ struct GpuIndexConfig { MemorySpace memorySpace = MemorySpace::Device; /// Should the index dispatch down to RAFT? +#if defined USE_NVIDIA_RAFT + bool use_raft = true; +#else bool use_raft = false; +#endif }; +/// A centralized function that determines whether RAFT should +/// be used based on various conditions (such as unsupported architecture) +bool should_use_raft(GpuIndexConfig config_); + class GpuIndex : public faiss::Index { public: GpuIndex( diff --git a/faiss/gpu/GpuIndexFlat.cu b/faiss/gpu/GpuIndexFlat.cu index ef5757fbbd..d361a7182a 100644 --- a/faiss/gpu/GpuIndexFlat.cu +++ b/faiss/gpu/GpuIndexFlat.cu @@ -6,18 +6,22 @@ */ #include +#include #include #include #include #include #include #include -#include #include #include #include #include +#if defined USE_NVIDIA_RAFT +#include +#endif + namespace faiss { namespace gpu { @@ -91,7 +95,7 @@ GpuIndexFlat::~GpuIndexFlat() {} void GpuIndexFlat::resetIndex_(int dims) { #if defined USE_NVIDIA_RAFT - if (flatConfig_.use_raft) { + if (should_use_raft(config_)) { data_.reset(new RaftFlatIndex( resources_.get(), dims, @@ -99,7 +103,7 @@ void GpuIndexFlat::resetIndex_(int dims) { config_.memorySpace)); } else #else - if (flatConfig_.use_raft) { + if (should_use_raft(config_)) { FAISS_THROW_MSG( "RAFT has not been compiled into the current version so it cannot be used."); } else diff --git a/faiss/gpu/GpuIndexIVF.cu b/faiss/gpu/GpuIndexIVF.cu index c83008307d..0c5b8db686 100644 --- a/faiss/gpu/GpuIndexIVF.cu +++ b/faiss/gpu/GpuIndexIVF.cu @@ -16,11 +16,6 @@ #include #include -#if defined USE_NVIDIA_RAFT -#include -#include -#endif - namespace faiss { namespace gpu { @@ -79,9 +74,9 @@ void GpuIndexIVF::init_() { } // here we set a low # iterations because this is typically used - // for large clusterings - // (copying IndexIVF.cpp's Level1Quantizer + // for large clusterings (copying IndexIVF.cpp's Level1Quantizer cp.niter = 10; + cp.verbose = verbose; if (quantizer) { @@ -96,6 +91,7 @@ void GpuIndexIVF::init_() { GpuIndexFlatConfig config = ivfConfig_.flatConfig; // inherit our same device config.device = config_.device; + config.use_raft = config_.use_raft; if (metric_type == faiss::METRIC_L2) { quantizer = new GpuIndexFlatL2(resources_, d, config); @@ -451,43 +447,12 @@ void GpuIndexIVF::trainQuantizer_(idx_t n, const float* x) { quantizer->reset(); -#if defined USE_NVIDIA_RAFT - - if (config_.use_raft) { - const raft::device_resources& raft_handle = - resources_->getRaftHandleCurrentDevice(); - - raft::neighbors::ivf_flat::index_params raft_idx_params; - raft_idx_params.n_lists = nlist; - raft_idx_params.metric = metric_type == faiss::METRIC_L2 - ? raft::distance::DistanceType::L2Expanded - : raft::distance::DistanceType::InnerProduct; - raft_idx_params.add_data_on_build = false; - raft_idx_params.kmeans_trainset_fraction = 1.0; - raft_idx_params.kmeans_n_iters = cp.niter; - raft_idx_params.adaptive_centers = !cp.frozen_centroids; + // leverage the CPU-side k-means code, which works for the GPU + // flat index as well + Clustering clus(this->d, nlist, this->cp); + clus.verbose = verbose; + clus.train(n, x, *quantizer); - auto raft_index = raft::neighbors::ivf_flat::build( - raft_handle, raft_idx_params, x, n, (idx_t)d); - - raft_handle.sync_stream(); - - quantizer->train(nlist, raft_index.centers().data_handle()); - quantizer->add(nlist, raft_index.centers().data_handle()); - } else -#else - if (config_.use_raft) { - FAISS_THROW_MSG( - "RAFT has not been compiled into the current version so it cannot be used."); - } else -#endif - { - // leverage the CPU-side k-means code, which works for the GPU - // flat index as well - Clustering clus(this->d, nlist, this->cp); - clus.verbose = verbose; - clus.train(n, x, *quantizer); - } quantizer->is_trained = true; FAISS_ASSERT(quantizer->ntotal == nlist); } diff --git a/faiss/gpu/GpuIndexIVFFlat.cu b/faiss/gpu/GpuIndexIVFFlat.cu index 750096e153..440b449a50 100644 --- a/faiss/gpu/GpuIndexIVFFlat.cu +++ b/faiss/gpu/GpuIndexIVFFlat.cu @@ -16,7 +16,9 @@ #include #if defined USE_NVIDIA_RAFT +#include #include +#include #endif #include @@ -70,11 +72,14 @@ GpuIndexIVFFlat::GpuIndexIVFFlat( config), ivfFlatConfig_(config), reserveMemoryVecs_(0) { + FAISS_THROW_IF_NOT_MSG( + !should_use_raft(config), + "GpuIndexIVFFlat: RAFT does not support separate coarseQuantizer"); // We could have been passed an already trained coarse quantizer. There is // no other quantizer that we need to train, so this is sufficient if (this->is_trained) { FAISS_ASSERT(this->quantizer); - set_index_( + setIndex_( resources_.get(), this->d, this->nlist, @@ -92,56 +97,13 @@ GpuIndexIVFFlat::GpuIndexIVFFlat( GpuIndexIVFFlat::~GpuIndexIVFFlat() {} -void GpuIndexIVFFlat::set_index_( - GpuResources* resources, - int dim, - int nlist, - faiss::MetricType metric, - float metricArg, - bool useResidual, - /// Optional ScalarQuantizer - faiss::ScalarQuantizer* scalarQ, - bool interleavedLayout, - IndicesOptions indicesOptions, - MemorySpace space) { -#if defined USE_NVIDIA_RAFT +void GpuIndexIVFFlat::reserveMemory(size_t numVecs) { + DeviceScope scope(config_.device); - if (config_.use_raft) { - index_.reset(new RaftIVFFlat( - resources, - dim, - nlist, - metric, - metricArg, - useResidual, - scalarQ, - interleavedLayout, - indicesOptions, - space)); - } else -#else - if (config_.use_raft) { + if (should_use_raft(config_)) { FAISS_THROW_MSG( - "RAFT has not been compiled into the current version so it cannot be used."); - } else -#endif - { - index_.reset(new IVFFlat( - resources, - dim, - nlist, - metric, - metricArg, - useResidual, - scalarQ, - interleavedLayout, - indicesOptions, - space)); + "Pre-allocation of IVF lists is not supported with RAFT enabled."); } -} - -void GpuIndexIVFFlat::reserveMemory(size_t numVecs) { - DeviceScope scope(config_.device); reserveMemoryVecs_ = numVecs; if (index_) { @@ -157,7 +119,11 @@ void GpuIndexIVFFlat::copyFrom(const faiss::IndexIVFFlat* index) { // Clear out our old data index_.reset(); - baseIndex_.reset(); + + // skip base class allocations if RAFT is enabled + if (!should_use_raft(config_)) { + baseIndex_.reset(); + } // The other index might not be trained if (!index->is_trained) { @@ -169,7 +135,7 @@ void GpuIndexIVFFlat::copyFrom(const faiss::IndexIVFFlat* index) { FAISS_ASSERT(is_trained); // Copy our lists as well - set_index_( + setIndex_( resources_.get(), d, nlist, @@ -247,23 +213,61 @@ void GpuIndexIVFFlat::train(idx_t n, const float* x) { if (this->is_trained) { FAISS_ASSERT(index_); + if (should_use_raft(config_)) { + // if RAFT is enabled, copy the IVF centroids to the RAFT index in + // case it has been reset. This is because reset clears the RAFT + // index and its centroids. + // TODO: change this once the coarse quantizer is separated from + // RAFT index + updateQuantizer(); + }; return; } FAISS_ASSERT(!index_); + if (should_use_raft(config_)) { #if defined USE_NVIDIA_RAFT - if (config_.use_raft) { - // No need to copy the data to host - trainQuantizer_(n, x); - } else + setIndex_( + resources_.get(), + this->d, + this->nlist, + this->metric_type, + this->metric_arg, + false, // no residual + nullptr, // no scalar quantizer + ivfFlatConfig_.interleavedLayout, + ivfFlatConfig_.indicesOptions, + config_.memorySpace); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + raft::neighbors::ivf_flat::index_params raft_idx_params; + raft_idx_params.n_lists = nlist; + raft_idx_params.metric = metricFaissToRaft(metric_type, false); + raft_idx_params.add_data_on_build = false; + raft_idx_params.kmeans_trainset_fraction = + static_cast(cp.max_points_per_centroid * nlist) / + static_cast(n); + raft_idx_params.kmeans_n_iters = cp.niter; + + auto raftIndex_ = + std::static_pointer_cast(index_); + + raft::neighbors::ivf_flat::index raft_ivfflat_index = + raft::neighbors::ivf_flat::build( + raft_handle, raft_idx_params, x, n, (idx_t)d); + + quantizer->train(nlist, raft_ivfflat_index.centers().data_handle()); + quantizer->add(nlist, raft_ivfflat_index.centers().data_handle()); + raft_handle.sync_stream(); + + raftIndex_->setRaftIndex(std::move(raft_ivfflat_index)); #else - if (config_.use_raft) { FAISS_THROW_MSG( "RAFT has not been compiled into the current version so it cannot be used."); - } else #endif - { + } else { // FIXME: GPUize more of this // First, make sure that the data is resident on the CPU, if it is not // on the CPU, as we depend upon parts of the CPU code @@ -272,29 +276,85 @@ void GpuIndexIVFFlat::train(idx_t n, const float* x) { resources_->getDefaultStream(config_.device), {n, this->d}); trainQuantizer_(n, hostData.data()); + + setIndex_( + resources_.get(), + this->d, + this->nlist, + this->metric_type, + this->metric_arg, + false, // no residual + nullptr, // no scalar quantizer + ivfFlatConfig_.interleavedLayout, + ivfFlatConfig_.indicesOptions, + config_.memorySpace); + updateQuantizer(); } // The quantizer is now trained; construct the IVF index - set_index_( - resources_.get(), - this->d, - this->nlist, - this->metric_type, - this->metric_arg, - false, // no residual - nullptr, // no scalar quantizer - ivfFlatConfig_.interleavedLayout, - ivfFlatConfig_.indicesOptions, - config_.memorySpace); baseIndex_ = std::static_pointer_cast(index_); - updateQuantizer(); if (reserveMemoryVecs_) { - index_->reserveMemory(reserveMemoryVecs_); + if (should_use_raft(config_)) { + FAISS_THROW_MSG( + "Pre-allocation of IVF lists is not supported with RAFT enabled."); + } else + index_->reserveMemory(reserveMemoryVecs_); } this->is_trained = true; } +void GpuIndexIVFFlat::setIndex_( + GpuResources* resources, + int dim, + int nlist, + faiss::MetricType metric, + float metricArg, + bool useResidual, + /// Optional ScalarQuantizer + faiss::ScalarQuantizer* scalarQ, + bool interleavedLayout, + IndicesOptions indicesOptions, + MemorySpace space) { + if (should_use_raft(config_)) { +#if defined USE_NVIDIA_RAFT + FAISS_THROW_IF_NOT_MSG( + ivfFlatConfig_.indicesOptions == INDICES_64_BIT, + "RAFT only supports INDICES_64_BIT"); + if (!ivfFlatConfig_.interleavedLayout) { + fprintf(stderr, + "WARN: interleavedLayout is set to False with RAFT enabled. This will be ignored.\n"); + } + index_.reset(new RaftIVFFlat( + resources, + dim, + nlist, + metric, + metricArg, + useResidual, + scalarQ, + interleavedLayout, + indicesOptions, + space)); +#else + FAISS_THROW_MSG( + "RAFT has not been compiled into the current version so it cannot be used."); +#endif + } else { + index_.reset(new IVFFlat( + resources, + dim, + nlist, + metric, + metricArg, + useResidual, + scalarQ, + interleavedLayout, + indicesOptions, + space)); + } +} + } // namespace gpu } // namespace faiss diff --git a/faiss/gpu/GpuIndexIVFFlat.h b/faiss/gpu/GpuIndexIVFFlat.h index d7508feef4..678bf8e7f4 100644 --- a/faiss/gpu/GpuIndexIVFFlat.h +++ b/faiss/gpu/GpuIndexIVFFlat.h @@ -88,7 +88,8 @@ class GpuIndexIVFFlat : public GpuIndexIVF { void train(idx_t n, const float* x) override; protected: - void set_index_( + /// Initialize appropriate index + void setIndex_( GpuResources* resources, int dim, int nlist, @@ -101,6 +102,7 @@ class GpuIndexIVFFlat : public GpuIndexIVF { IndicesOptions indicesOptions, MemorySpace space); + protected: /// Our configuration options const GpuIndexIVFFlatConfig ivfFlatConfig_; diff --git a/faiss/gpu/GpuIndexIVFPQ.cu b/faiss/gpu/GpuIndexIVFPQ.cu index 69c4cf0556..d39f036b89 100644 --- a/faiss/gpu/GpuIndexIVFPQ.cu +++ b/faiss/gpu/GpuIndexIVFPQ.cu @@ -15,6 +15,13 @@ #include #include +#if defined USE_NVIDIA_RAFT +#include +#include +#include +#include +#endif + #include namespace faiss { @@ -87,6 +94,10 @@ GpuIndexIVFPQ::GpuIndexIVFPQ( // instance this->is_trained = false; + FAISS_THROW_IF_NOT_MSG( + !config.use_raft, + "GpuIndexIVFPQ: RAFT does not support separate coarseQuantizer"); + verifyPQSettings_(); } @@ -100,7 +111,11 @@ void GpuIndexIVFPQ::copyFrom(const faiss::IndexIVFPQ* index) { // Clear out our old data index_.reset(); - baseIndex_.reset(); + + // skip base class allocations if RAFT is enabled + if (!should_use_raft(config_)) { + baseIndex_.reset(); + } pq = index->pq; subQuantizers_ = index->pq.M; @@ -127,7 +142,7 @@ void GpuIndexIVFPQ::copyFrom(const faiss::IndexIVFPQ* index) { // Copy our lists as well // The product quantizer must have data in it FAISS_ASSERT(index->pq.centroids.size() > 0); - index_.reset(new IVFPQ( + setIndex_( resources_.get(), this->d, this->nlist, @@ -140,7 +155,7 @@ void GpuIndexIVFPQ::copyFrom(const faiss::IndexIVFPQ* index) { ivfpqConfig_.interleavedLayout, (float*)index->pq.centroids.data(), ivfpqConfig_.indicesOptions, - config_.memorySpace)); + config_.memorySpace); baseIndex_ = std::static_pointer_cast(index_); // Doesn't make sense to reserve memory here @@ -169,7 +184,7 @@ void GpuIndexIVFPQ::copyTo(faiss::IndexIVFPQ* index) const { // index->by_residual = true; index->use_precomputed_table = 0; - index->code_size = subQuantizers_; + index->code_size = utils::divUp(subQuantizers_ * bitsPerCode_, 8); index->pq = faiss::ProductQuantizer(this->d, subQuantizers_, bitsPerCode_); index->do_polysemous_training = false; @@ -308,6 +323,7 @@ void GpuIndexIVFPQ::trainResidualQuantizer_(idx_t n, const float* x) { try { GpuIndexFlatConfig config; config.device = ivfpqConfig_.device; + config.use_raft = false; GpuIndexFlatL2 pqIndex(resources_, pq.dsub, config); pq.assign_index = &pqIndex; @@ -322,29 +338,6 @@ void GpuIndexIVFPQ::trainResidualQuantizer_(idx_t n, const float* x) { // use the currently assigned clustering index pq.train(n, residuals.data()); } - - index_.reset(new IVFPQ( - resources_.get(), - this->d, - this->nlist, - metric_type, - metric_arg, - subQuantizers_, - bitsPerCode_, - ivfpqConfig_.useFloat16LookupTables, - ivfpqConfig_.useMMCodeDistance, - ivfpqConfig_.interleavedLayout, - pq.centroids.data(), - ivfpqConfig_.indicesOptions, - config_.memorySpace)); - baseIndex_ = std::static_pointer_cast(index_); - updateQuantizer(); - - if (reserveMemoryVecs_) { - index_->reserveMemory(reserveMemoryVecs_); - } - - index_->setPrecomputedCodes(quantizer, usePrecomputedTables_); } void GpuIndexIVFPQ::train(idx_t n, const float* x) { @@ -356,27 +349,179 @@ void GpuIndexIVFPQ::train(idx_t n, const float* x) { if (this->is_trained) { FAISS_ASSERT(index_); + if (should_use_raft(config_)) { + // if RAFT is enabled, copy the IVF centroids to the RAFT index in + // case it has been reset. This is because reset clears the RAFT + // index and its centroids. + // TODO: change this once the coarse quantizer is separated from + // RAFT index + updateQuantizer(); + }; return; } FAISS_ASSERT(!index_); - // FIXME: GPUize more of this - // First, make sure that the data is resident on the CPU, if it is not on - // the CPU, as we depend upon parts of the CPU code - auto hostData = toHost( - (float*)x, - resources_->getDefaultStream(config_.device), - {n, this->d}); + // RAFT does not support using an external index for assignment. Fall back + // to the classical GPU impl + if (should_use_raft(config_)) { +#if defined USE_NVIDIA_RAFT + if (pq.assign_index) { + fprintf(stderr, + "WARN: The Product Quantizer's assign_index will be ignored with RAFT enabled.\n"); + } + // first initialize the index. The PQ centroids will be updated + // retroactively. + setIndex_( + resources_.get(), + this->d, + this->nlist, + metric_type, + metric_arg, + subQuantizers_, + bitsPerCode_, + ivfpqConfig_.useFloat16LookupTables, + ivfpqConfig_.useMMCodeDistance, + ivfpqConfig_.interleavedLayout, + pq.centroids.data(), + ivfpqConfig_.indicesOptions, + config_.memorySpace); + // No need to copy the data to host + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + raft::neighbors::ivf_pq::index_params raft_idx_params; + raft_idx_params.n_lists = nlist; + raft_idx_params.metric = metricFaissToRaft(metric_type, false); + raft_idx_params.kmeans_trainset_fraction = + static_cast(cp.max_points_per_centroid * nlist) / + static_cast(n); + raft_idx_params.kmeans_n_iters = cp.niter; + raft_idx_params.pq_bits = bitsPerCode_; + raft_idx_params.pq_dim = subQuantizers_; + raft_idx_params.conservative_memory_allocation = false; + raft_idx_params.add_data_on_build = false; + + auto raftIndex_ = std::static_pointer_cast(index_); + + raft::neighbors::ivf_pq::index raft_ivfpq_index = + raft::neighbors::ivf_pq::build( + raft_handle, raft_idx_params, x, n, (idx_t)d); + + auto raft_centers = raft::make_device_matrix( + raft_handle, + raft_ivfpq_index.n_lists(), + raft_ivfpq_index.dim()); + raft::neighbors::ivf_pq::helpers::extract_centers( + raft_handle, raft_ivfpq_index, raft_centers.view()); + + quantizer->train(nlist, raft_centers.data_handle()); + quantizer->add(nlist, raft_centers.data_handle()); + + raft::copy( + pq.get_centroids(0, 0), + raft_ivfpq_index.pq_centers().data_handle(), + raft_ivfpq_index.pq_centers().size(), + raft_handle.get_stream()); + raft_handle.sync_stream(); + raftIndex_->setRaftIndex(std::move(raft_ivfpq_index)); +#else + FAISS_THROW_MSG( + "RAFT has not been compiled into the current version so it cannot be used."); +#endif + } else { + // FIXME: GPUize more of this + // First, make sure that the data is resident on the CPU, if it is not + // on the CPU, as we depend upon parts of the CPU code + auto hostData = toHost( + (float*)x, + resources_->getDefaultStream(config_.device), + {n, this->d}); + + trainQuantizer_(n, hostData.data()); + trainResidualQuantizer_(n, hostData.data()); + + setIndex_( + resources_.get(), + this->d, + this->nlist, + metric_type, + metric_arg, + subQuantizers_, + bitsPerCode_, + ivfpqConfig_.useFloat16LookupTables, + ivfpqConfig_.useMMCodeDistance, + ivfpqConfig_.interleavedLayout, + pq.centroids.data(), + ivfpqConfig_.indicesOptions, + config_.memorySpace); + updateQuantizer(); + } + baseIndex_ = std::static_pointer_cast(index_); - trainQuantizer_(n, hostData.data()); - trainResidualQuantizer_(n, hostData.data()); + if (reserveMemoryVecs_) { + index_->reserveMemory(reserveMemoryVecs_); + } + + index_->setPrecomputedCodes(quantizer, usePrecomputedTables_); FAISS_ASSERT(index_); this->is_trained = true; } +void GpuIndexIVFPQ::setIndex_( + GpuResources* resources, + int dim, + idx_t nlist, + faiss::MetricType metric, + float metricArg, + int numSubQuantizers, + int bitsPerSubQuantizer, + bool useFloat16LookupTables, + bool useMMCodeDistance, + bool interleavedLayout, + float* pqCentroidData, + IndicesOptions indicesOptions, + MemorySpace space) { + if (should_use_raft(config_)) { +#if defined USE_NVIDIA_RAFT + index_.reset(new RaftIVFPQ( + resources, + dim, + nlist, + metric, + metricArg, + numSubQuantizers, + bitsPerSubQuantizer, + useFloat16LookupTables, + useMMCodeDistance, + interleavedLayout, + pqCentroidData, + indicesOptions, + space)); +#else + FAISS_THROW_MSG( + "RAFT has not been compiled into the current version so it cannot be used."); +#endif + } else { + index_.reset(new IVFPQ( + resources, + dim, + nlist, + metric, + metricArg, + numSubQuantizers, + bitsPerSubQuantizer, + useFloat16LookupTables, + useMMCodeDistance, + interleavedLayout, + pqCentroidData, + indicesOptions, + space)); + } +} + void GpuIndexIVFPQ::verifyPQSettings_() const { // Our implementation has these restrictions: @@ -384,28 +529,36 @@ void GpuIndexIVFPQ::verifyPQSettings_() const { FAISS_THROW_IF_NOT_MSG(nlist > 0, "nlist must be >0"); // up to a single byte per code - if (ivfpqConfig_.interleavedLayout) { + if (should_use_raft(config_)) { + if (!ivfpqConfig_.interleavedLayout) { + fprintf(stderr, + "WARN: interleavedLayout is set to False with RAFT enabled. This will be ignored.\n"); + } FAISS_THROW_IF_NOT_FMT( - bitsPerCode_ == 4 || bitsPerCode_ == 5 || bitsPerCode_ == 6 || - bitsPerCode_ == 8, - "Bits per code must be between 4, 5, 6 or 8 (passed %d)", + bitsPerCode_ >= 4 && bitsPerCode_ <= 8, + "Bits per code must be within closed range [4,8] (passed %d)", bitsPerCode_); - - } else { FAISS_THROW_IF_NOT_FMT( - bitsPerCode_ == 8, - "Bits per code must be 8 (passed %d)", - bitsPerCode_); + (bitsPerCode_ * subQuantizers_) % 8 == 0, + "`Bits per code * number of sub-quantizers must be a multiple of 8, (passed %u * %u = %u).", + bitsPerCode_, + subQuantizers_, + bitsPerCode_ * subQuantizers_); + } else { + if (ivfpqConfig_.interleavedLayout) { + FAISS_THROW_IF_NOT_FMT( + bitsPerCode_ == 4 || bitsPerCode_ == 5 || + bitsPerCode_ == 6 || bitsPerCode_ == 8, + "Bits per code must be between 4, 5, 6 or 8 (passed %d)", + bitsPerCode_); + } else { + FAISS_THROW_IF_NOT_FMT( + bitsPerCode_ == 8, + "Bits per code must be 8 (passed %d)", + bitsPerCode_); + } } - // Sub-quantizers must evenly divide dimensions available - FAISS_THROW_IF_NOT_FMT( - this->d % subQuantizers_ == 0, - "Number of sub-quantizers (%d) must be an " - "even divisor of the number of dimensions (%d)", - subQuantizers_, - this->d); - // The number of bytes per encoded vector must be one we support FAISS_THROW_IF_NOT_FMT( ivfpqConfig_.interleavedLayout || @@ -414,30 +567,40 @@ void GpuIndexIVFPQ::verifyPQSettings_() const { "is not supported", subQuantizers_); - // We must have enough shared memory on the current device to store - // our lookup distances - int lookupTableSize = sizeof(float); - if (ivfpqConfig_.useFloat16LookupTables) { - lookupTableSize = sizeof(half); - } + if (!should_use_raft(config_)) { + // Sub-quantizers must evenly divide dimensions available + FAISS_THROW_IF_NOT_FMT( + this->d % subQuantizers_ == 0, + "Number of sub-quantizers (%d) must be an " + "even divisor of the number of dimensions (%d)", + subQuantizers_, + this->d); + + // We must have enough shared memory on the current device to store + // our lookup distances + int lookupTableSize = sizeof(float); + if (ivfpqConfig_.useFloat16LookupTables) { + lookupTableSize = sizeof(half); + } - // 64 bytes per code is only supported with usage of float16, at 2^8 - // codes per subquantizer - size_t requiredSmemSize = - lookupTableSize * subQuantizers_ * utils::pow2(bitsPerCode_); - size_t smemPerBlock = getMaxSharedMemPerBlock(config_.device); + // 64 bytes per code is only supported with usage of float16, at 2^8 + // codes per subquantizer + size_t requiredSmemSize = + lookupTableSize * subQuantizers_ * utils::pow2(bitsPerCode_); + size_t smemPerBlock = getMaxSharedMemPerBlock(config_.device); - FAISS_THROW_IF_NOT_FMT( - requiredSmemSize <= getMaxSharedMemPerBlock(config_.device), - "Device %d has %zu bytes of shared memory, while " - "%d bits per code and %d sub-quantizers requires %zu " - "bytes. Consider useFloat16LookupTables and/or " - "reduce parameters", - config_.device, - smemPerBlock, - bitsPerCode_, - subQuantizers_, - requiredSmemSize); + FAISS_THROW_IF_NOT_FMT( + requiredSmemSize <= getMaxSharedMemPerBlock(config_.device), + "Device %d has %zu bytes of shared memory, while " + "%d bits per code and %d sub-quantizers requires %zu " + "bytes. Consider useFloat16LookupTables and/or " + "reduce parameters", + config_.device, + smemPerBlock, + bitsPerCode_, + subQuantizers_, + requiredSmemSize); + } } } // namespace gpu diff --git a/faiss/gpu/GpuIndexIVFPQ.h b/faiss/gpu/GpuIndexIVFPQ.h index 22e9961675..1084d4d0d2 100644 --- a/faiss/gpu/GpuIndexIVFPQ.h +++ b/faiss/gpu/GpuIndexIVFPQ.h @@ -33,7 +33,8 @@ struct GpuIndexIVFPQConfig : public GpuIndexIVFConfig { bool usePrecomputedTables = false; /// Use the alternative memory layout for the IVF lists - /// WARNING: this is a feature under development, do not use! + /// WARNING: this is a feature under development, and is only supported with + /// RAFT enabled for the index. Do not use if RAFT is not enabled. bool interleavedLayout = false; /// Use GEMM-backed computation of PQ code distances for the no precomputed @@ -133,6 +134,22 @@ class GpuIndexIVFPQ : public GpuIndexIVF { ProductQuantizer pq; protected: + /// Initialize appropriate index + void setIndex_( + GpuResources* resources, + int dim, + idx_t nlist, + faiss::MetricType metric, + float metricArg, + int numSubQuantizers, + int bitsPerSubQuantizer, + bool useFloat16LookupTables, + bool useMMCodeDistance, + bool interleavedLayout, + float* pqCentroidData, + IndicesOptions indicesOptions, + MemorySpace space); + /// Throws errors if configuration settings are improper void verifyPQSettings_() const; diff --git a/faiss/gpu/GpuResources.h b/faiss/gpu/GpuResources.h index 7d0459955b..fc6dd591b4 100644 --- a/faiss/gpu/GpuResources.h +++ b/faiss/gpu/GpuResources.h @@ -32,6 +32,7 @@ #if defined USE_NVIDIA_RAFT #include +#include #endif namespace faiss { @@ -159,6 +160,10 @@ struct AllocRequest : public AllocInfo { /// The size in bytes of the allocation size_t size = 0; + +#if defined USE_NVIDIA_RAFT + rmm::mr::device_memory_resource* mr = nullptr; +#endif }; /// A RAII object that manages a temporary memory request diff --git a/faiss/gpu/StandardGpuResources.cpp b/faiss/gpu/StandardGpuResources.cpp index 754025d049..004f80a27e 100644 --- a/faiss/gpu/StandardGpuResources.cpp +++ b/faiss/gpu/StandardGpuResources.cpp @@ -22,11 +22,10 @@ #if defined USE_NVIDIA_RAFT #include -#include #include +#include #include #include - #endif #include @@ -92,9 +91,8 @@ std::string allocsToString(const std::unordered_map& map) { StandardGpuResourcesImpl::StandardGpuResourcesImpl() : #if defined USE_NVIDIA_RAFT - cmr(new rmm::mr::cuda_memory_resource), - mmr(new rmm::mr::managed_memory_resource), - pmr(new rmm::mr::pinned_memory_resource), + mmr_(new rmm::mr::managed_memory_resource), + pmr_(new rmm::mr::pinned_memory_resource), #endif pinnedMemAlloc_(nullptr), pinnedMemAllocSize_(0), @@ -161,7 +159,7 @@ StandardGpuResourcesImpl::~StandardGpuResourcesImpl() { if (pinnedMemAlloc_) { #if defined USE_NVIDIA_RAFT - pmr->deallocate(pinnedMemAlloc_, pinnedMemAllocSize_); + pmr_->deallocate(pinnedMemAlloc_, pinnedMemAllocSize_); #else auto err = cudaFreeHost(pinnedMemAlloc_); FAISS_ASSERT_FMT( @@ -314,7 +312,7 @@ void StandardGpuResourcesImpl::initializeForDevice(int device) { // pinned memory allocation if (defaultStreams_.empty() && pinnedMemSize_ > 0) { try { - pinnedMemAlloc_ = pmr->allocate(pinnedMemSize_); + pinnedMemAlloc_ = pmr_->allocate(pinnedMemSize_); } catch (const std::bad_alloc& rmm_ex) { FAISS_THROW_MSG("CUDA memory allocation error"); } @@ -478,8 +476,6 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) { void* p = nullptr; if (adjReq.space == MemorySpace::Temporary) { - // If we don't have enough space in our temporary memory manager, we - // need to allocate this request separately auto& tempMem = tempMemory_[adjReq.device]; if (adjReq.size > tempMem->getSizeAvailable()) { @@ -500,11 +496,14 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) { // Otherwise, we can handle this locally p = tempMemory_[adjReq.device]->allocMemory(adjReq.stream, adjReq.size); - } else if (adjReq.space == MemorySpace::Device) { #if defined USE_NVIDIA_RAFT try { - p = cmr->allocate(adjReq.size, adjReq.stream); + rmm::mr::device_memory_resource* current_mr = + rmm::mr::get_per_device_resource( + rmm::cuda_device_id{adjReq.device}); + p = current_mr->allocate_async(adjReq.size, adjReq.stream); + adjReq.mr = current_mr; } catch (const std::bad_alloc& rmm_ex) { FAISS_THROW_MSG("CUDA memory allocation error"); } @@ -514,8 +513,8 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) { // Throw if we fail to allocate if (err != cudaSuccess) { // FIXME: as of CUDA 11, a memory allocation error appears to be - // presented via cudaGetLastError as well, and needs to be cleared. - // Just call the function to clear it + // presented via cudaGetLastError as well, and needs to be + // cleared. Just call the function to clear it cudaGetLastError(); std::stringstream ss; @@ -534,7 +533,12 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) { } else if (adjReq.space == MemorySpace::Unified) { #if defined USE_NVIDIA_RAFT try { - p = mmr->allocate(adjReq.size, adjReq.stream); + // for now, use our own managed MR to do Unified Memory allocations. + // TODO: change this to use the current device resource once RMM has + // a way to retrieve a "guaranteed" managed memory resource for a + // device. + p = mmr_->allocate_async(adjReq.size, adjReq.stream); + adjReq.mr = mmr_.get(); } catch (const std::bad_alloc& rmm_ex) { FAISS_THROW_MSG("CUDA memory allocation error"); } @@ -593,16 +597,11 @@ void StandardGpuResourcesImpl::deallocMemory(int device, void* p) { if (req.space == MemorySpace::Temporary) { tempMemory_[device]->deallocMemory(device, req.stream, req.size, p); - } else if ( req.space == MemorySpace::Device || req.space == MemorySpace::Unified) { #if defined USE_NVIDIA_RAFT - if (req.space == MemorySpace::Device) { - cmr->deallocate(p, req.size, req.stream); - } else if (req.space == MemorySpace::Unified) { - mmr->deallocate(p, req.size, req.stream); - } + req.mr->deallocate_async(p, req.size, req.stream); #else auto err = cudaFree(p); FAISS_ASSERT_FMT( diff --git a/faiss/gpu/StandardGpuResources.h b/faiss/gpu/StandardGpuResources.h index 9113de573c..661c784aee 100644 --- a/faiss/gpu/StandardGpuResources.h +++ b/faiss/gpu/StandardGpuResources.h @@ -24,8 +24,6 @@ #if defined USE_NVIDIA_RAFT #include -#include -#include #include #endif @@ -37,6 +35,7 @@ #include #include +#pragma GCC visibility push(default) namespace faiss { namespace gpu { @@ -166,14 +165,11 @@ class StandardGpuResourcesImpl : public GpuResources { * to create a subclass only for the RMM memory resources. */ - // cuda_memory_resource - std::unique_ptr cmr; - // managed_memory_resource - std::unique_ptr mmr; + std::unique_ptr mmr_; // pinned_memory_resource - std::unique_ptr pmr; + std::unique_ptr pmr_; #endif /// Pinned memory allocation for use with this GPU @@ -260,3 +256,4 @@ class StandardGpuResources : public GpuResourcesProvider { } // namespace gpu } // namespace faiss +#pragma GCC visibility pop diff --git a/faiss/gpu/impl/IVFBase.cuh b/faiss/gpu/impl/IVFBase.cuh index 2bb319d002..6b1f2ac394 100644 --- a/faiss/gpu/impl/IVFBase.cuh +++ b/faiss/gpu/impl/IVFBase.cuh @@ -41,7 +41,7 @@ class IVFBase { virtual ~IVFBase(); /// Reserve GPU memory in our inverted lists for this number of vectors - void reserveMemory(idx_t numVecs); + virtual void reserveMemory(idx_t numVecs); /// Clear out all inverted lists, but retain the coarse quantizer /// and the product quantizer info @@ -52,7 +52,7 @@ class IVFBase { /// After adding vectors, one can call this to reclaim device memory /// to exactly the amount needed. Returns space reclaimed in bytes - size_t reclaimMemory(); + virtual size_t reclaimMemory(); /// Returns the number of inverted lists idx_t getNumLists() const; diff --git a/faiss/gpu/impl/IVFPQ.cuh b/faiss/gpu/impl/IVFPQ.cuh index 3670e58edf..0d17b02c9b 100644 --- a/faiss/gpu/impl/IVFPQ.cuh +++ b/faiss/gpu/impl/IVFPQ.cuh @@ -39,7 +39,7 @@ class IVFPQ : public IVFBase { /// Enable or disable pre-computed codes. The quantizer is needed to gather /// the IVF centroids for use - void setPrecomputedCodes(Index* coarseQuantizer, bool enable); + virtual void setPrecomputedCodes(Index* coarseQuantizer, bool enable); /// Returns our set of sub-quantizers of the form /// (sub q)(code id)(sub dim) @@ -134,7 +134,7 @@ class IVFPQ : public IVFBase { Tensor& outDistances, Tensor& outIndices); - private: + protected: /// Number of sub-quantizers per vector const int numSubQuantizers_; diff --git a/faiss/gpu/impl/RaftFlatIndex.cu b/faiss/gpu/impl/RaftFlatIndex.cu index 8f5c491163..24a6d39604 100644 --- a/faiss/gpu/impl/RaftFlatIndex.cu +++ b/faiss/gpu/impl/RaftFlatIndex.cu @@ -20,7 +20,7 @@ * limitations under the License. */ -#include +#include #include #include @@ -91,7 +91,7 @@ void RaftFlatIndex::query( outDistances.getSize(0), outDistances.getSize(1)); - DistanceType distance = faiss_to_raft(metric, exactDistance); + DistanceType distance = metricFaissToRaft(metric, exactDistance); std::optional> norms_view = raft::make_device_vector_view( diff --git a/faiss/gpu/impl/RaftFlatIndex.cuh b/faiss/gpu/impl/RaftFlatIndex.cuh index 010c5aebce..d3823bbf58 100644 --- a/faiss/gpu/impl/RaftFlatIndex.cuh +++ b/faiss/gpu/impl/RaftFlatIndex.cuh @@ -28,6 +28,7 @@ #include #include +#pragma GCC visibility push(default) namespace faiss { namespace gpu { @@ -67,3 +68,4 @@ class RaftFlatIndex : public FlatIndex { } // namespace gpu } // namespace faiss +#pragma GCC visibility pop diff --git a/faiss/gpu/impl/RaftIVFFlat.cu b/faiss/gpu/impl/RaftIVFFlat.cu index 2c6afb795c..1e310723d0 100644 --- a/faiss/gpu/impl/RaftIVFFlat.cu +++ b/faiss/gpu/impl/RaftIVFFlat.cu @@ -23,31 +23,19 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include #include -#include -#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include #include #include +#include + +#include +#include namespace faiss { namespace gpu { @@ -71,18 +59,31 @@ RaftIVFFlat::RaftIVFFlat( useResidual, scalarQ, interleavedLayout, + // skip ptr allocations in base class (handled by RAFT + // internally) indicesOptions, space) { FAISS_THROW_IF_NOT_MSG( indicesOptions == INDICES_64_BIT, "only INDICES_64_BIT is supported for RAFT index"); - reset(); } RaftIVFFlat::~RaftIVFFlat() {} -/// Find the approximate k nearest neighbors for `queries` against -/// our database +void RaftIVFFlat::reserveMemory(idx_t numVecs) { + fprintf(stderr, + "WARN: reserveMemory is NOP. Pre-allocation of IVF lists is not supported with RAFT enabled.\n"); +} + +void RaftIVFFlat::reset() { + raft_knn_index.reset(); +} + +void RaftIVFFlat::setRaftIndex( + raft::neighbors::ivf_flat::index&& idx) { + raft_knn_index.emplace(std::move(idx)); +} + void RaftIVFFlat::search( Index* coarseQuantizer, Tensor& queries, @@ -90,7 +91,9 @@ void RaftIVFFlat::search( int k, Tensor& outDistances, Tensor& outIndices) { - // TODO: We probably don't want to ignore the coarse quantizer here... + /// NB: The coarse quantizer is ignored here. The user is assumed to have + /// called updateQuantizer() to modify the RAFT index if the quantizer was + /// modified externally uint32_t numQueries = queries.getSize(0); uint32_t cols = queries.getSize(1); @@ -125,7 +128,7 @@ void RaftIVFFlat::search( /// Identify NaN rows and mask their nearest neighbors auto nan_flag = raft::make_device_vector(raft_handle, numQueries); - validRowIndices_(queries, nan_flag.data_handle()); + validRowIndices(resources_, queries, nan_flag.data_handle()); raft::linalg::map_offset( raft_handle, @@ -154,65 +157,22 @@ void RaftIVFFlat::search( }); } -/// Classify and encode/add vectors to our IVF lists. -/// The input data must be on our current device. -/// Returns the number of vectors successfully added. Vectors may -/// not be able to be added because they contain NaNs. idx_t RaftIVFFlat::addVectors( Index* coarseQuantizer, Tensor& vecs, Tensor& indices) { - /// TODO: We probably don't want to ignore the coarse quantizer here + /// NB: The coarse quantizer is ignored here. The user is assumed to have + /// called updateQuantizer() to update the RAFT index if the quantizer was + /// modified externally - idx_t n_rows = vecs.getSize(0); + FAISS_ASSERT(raft_knn_index.has_value()); const raft::device_resources& raft_handle = resources_->getRaftHandleCurrentDevice(); - /// Remove NaN values - auto nan_flag = raft::make_device_vector(raft_handle, n_rows); - - validRowIndices_(vecs, nan_flag.data_handle()); - - idx_t n_rows_valid = thrust::reduce( - raft_handle.get_thrust_policy(), - nan_flag.data_handle(), - nan_flag.data_handle() + n_rows, - 0); - - if (n_rows_valid < n_rows) { - auto gather_indices = raft::make_device_vector( - raft_handle, n_rows_valid); - - auto count = thrust::make_counting_iterator(0); + /// Remove rows containing NaNs + idx_t n_rows_valid = inplaceGatherFilteredRows(resources_, vecs, indices); - thrust::copy_if( - raft_handle.get_thrust_policy(), - count, - count + n_rows, - gather_indices.data_handle(), - [nan_flag = nan_flag.data_handle()] __device__(auto i) { - return nan_flag[i]; - }); - - raft::matrix::gather( - raft_handle, - raft::make_device_matrix_view( - vecs.data(), n_rows, dim_), - raft::make_const_mdspan(gather_indices.view()), - (idx_t)16); - - auto valid_indices = raft::make_device_vector( - raft_handle, n_rows_valid); - - raft::matrix::gather( - raft_handle, - raft::make_device_matrix_view( - indices.data(), n_rows, (idx_t)1), - raft::make_const_mdspan(gather_indices.view())); - } - - FAISS_ASSERT(raft_knn_index.has_value()); raft_knn_index.emplace(raft::neighbors::ivf_flat::extend( raft_handle, raft::make_device_matrix_view( @@ -225,10 +185,6 @@ idx_t RaftIVFFlat::addVectors( return n_rows_valid; } -void RaftIVFFlat::reset() { - raft_knn_index.reset(); -} - idx_t RaftIVFFlat::getListLength(idx_t listId) const { FAISS_ASSERT(raft_knn_index.has_value()); const raft::device_resources& raft_handle = @@ -259,10 +215,11 @@ std::vector RaftIVFFlat::getListIndices(idx_t listId) const { // fetch the list indices ptr on host idx_t* list_indices_ptr; - // fetch the list indices ptr on host raft::update_host( &list_indices_ptr, - raft_knn_index.value().inds_ptrs().data_handle() + listId, + const_cast( + raft_knn_index.value().inds_ptrs().data_handle()) + + listId, 1, stream); raft_handle.sync_stream(); @@ -278,7 +235,7 @@ std::vector RaftIVFFlat::getListVectorData( idx_t listId, bool gpuFormat) const { if (gpuFormat) { - FAISS_THROW_MSG("gpuFormat is not suppported for raft indices"); + FAISS_THROW_MSG("gpuFormat should be false for RAFT indices"); } FAISS_ASSERT(raft_knn_index.has_value()); @@ -334,59 +291,71 @@ void RaftIVFFlat::searchPreassigned( } void RaftIVFFlat::updateQuantizer(Index* quantizer) { - idx_t quantizer_ntotal = quantizer->ntotal; + FAISS_THROW_IF_NOT(quantizer->is_trained); - const raft::device_resources& raft_handle = - resources_->getRaftHandleCurrentDevice(); - auto stream = raft_handle.get_stream(); + // Must match our basic IVF parameters + FAISS_THROW_IF_NOT(quantizer->d == getDim()); + FAISS_THROW_IF_NOT(quantizer->ntotal == getNumLists()); - auto total_elems = size_t(quantizer_ntotal) * size_t(quantizer->d); + size_t total_elems = quantizer->ntotal * quantizer->d; - raft::logger::get().set_level(RAFT_LEVEL_TRACE); + auto stream = resources_->getDefaultStreamCurrentDevice(); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); raft::neighbors::ivf_flat::index_params pams; pams.add_data_on_build = false; - - pams.n_lists = this->numLists_; - - switch (this->metric_) { - case faiss::METRIC_L2: - pams.metric = raft::distance::DistanceType::L2Expanded; - break; - case faiss::METRIC_INNER_PRODUCT: - pams.metric = raft::distance::DistanceType::InnerProduct; - break; - default: - FAISS_THROW_MSG("Metric is not supported."); + pams.metric = metricFaissToRaft(metric_, false); + pams.n_lists = numLists_; + raft_knn_index.emplace(raft_handle, pams, static_cast(dim_)); + + raft::neighbors::ivf_flat::helpers::reset_index( + raft_handle, &raft_knn_index.value()); + + // If the index instance is a GpuIndexFlat, then we can use direct access to + // the centroids within. + auto gpuQ = dynamic_cast(quantizer); + if (gpuQ) { + auto gpuData = gpuQ->getGpuData(); + + if (gpuData->getUseFloat16()) { + // The FlatIndex keeps its data in float16; we need to reconstruct + // as float32 and store locally + DeviceTensor centroids( + resources_, + makeSpaceAlloc(AllocType::FlatData, space_, stream), + {getNumLists(), getDim()}); + + gpuData->reconstruct(0, gpuData->getSize(), centroids); + + raft::update_device( + raft_knn_index.value().centers().data_handle(), + centroids.data(), + total_elems, + stream); + } else { + /// No reconstruct needed since the centers are already in float32 + auto centroids = gpuData->getVectorsFloat32Ref(); + + raft::update_device( + raft_knn_index.value().centers().data_handle(), + centroids.data(), + total_elems, + stream); + } + } else { + // Otherwise, we need to reconstruct all vectors from the index and copy + // them to the GPU, in order to have access as needed for residual + // computation + auto vecs = std::vector(getNumLists() * getDim()); + quantizer->reconstruct_n(0, quantizer->ntotal, vecs.data()); + + raft::update_device( + raft_knn_index.value().centers().data_handle(), + vecs.data(), + total_elems, + stream); } - - raft_knn_index.emplace(raft_handle, pams, (uint32_t)this->dim_); - - cudaMemsetAsync( - raft_knn_index.value().list_sizes().data_handle(), - 0, - raft_knn_index.value().list_sizes().size() * sizeof(uint32_t), - stream); - cudaMemsetAsync( - raft_knn_index.value().data_ptrs().data_handle(), - 0, - raft_knn_index.value().data_ptrs().size() * sizeof(float*), - stream); - cudaMemsetAsync( - raft_knn_index.value().inds_ptrs().data_handle(), - 0, - raft_knn_index.value().inds_ptrs().size() * sizeof(idx_t*), - stream); - - /// Copy (reconstructed) centroids over, rather than re-training - std::vector buf_host(total_elems); - quantizer->reconstruct_n(0, quantizer_ntotal, buf_host.data()); - - raft::update_device( - raft_knn_index.value().centers().data_handle(), - buf_host.data(), - total_elems, - stream); } void RaftIVFFlat::copyInvertedListsFrom(const InvertedLists* ivf) { @@ -422,6 +391,9 @@ void RaftIVFFlat::copyInvertedListsFrom(const InvertedLists* ivf) { // store the list size list_sizes_[i] = static_cast(listSize); + // This RAFT list must currently be empty + FAISS_ASSERT(getListLength(i) == 0); + raft::neighbors::ivf::resize_list( raft_handle, raft_lists[i], @@ -483,12 +455,6 @@ void RaftIVFFlat::addEncodedVectorsToList_( idx_t numVecs) { auto stream = resources_->getDefaultStreamCurrentDevice(); - // This list must already exist - FAISS_ASSERT(raft_knn_index.has_value()); - - // This list must currently be empty - FAISS_ASSERT(getListLength(listId) == 0); - // If there's nothing to add, then there's nothing we have to do if (numVecs == 0) { return; @@ -496,7 +462,6 @@ void RaftIVFFlat::addEncodedVectorsToList_( // The GPU might have a different layout of the memory auto gpuListSizeInBytes = getGpuVectorsEncodingSize_(numVecs); - auto cpuListSizeInBytes = getCpuVectorsEncodingSize_(numVecs); // We only have int32 length representations on the GPU per each // list; the length is in sizeof(char) @@ -541,27 +506,6 @@ void RaftIVFFlat::addEncodedVectorsToList_( raft::update_device(list_indices_ptr, indices, numVecs, stream); } -void RaftIVFFlat::validRowIndices_( - Tensor& vecs, - bool* nan_flag) { - raft::device_resources& raft_handle = - resources_->getRaftHandleCurrentDevice(); - idx_t n_rows = vecs.getSize(0); - - thrust::fill_n(raft_handle.get_thrust_policy(), nan_flag, n_rows, true); - raft::linalg::map_offset( - raft_handle, - raft::make_device_vector_view(nan_flag, n_rows), - [vecs = vecs.data(), dim_ = this->dim_] __device__(idx_t i) { - for (idx_t col = 0; col < dim_; col++) { - if (!isfinite(vecs[i * dim_ + col])) { - return false; - } - } - return true; - }); -} - RaftIVFFlatCodePackerInterleaved::RaftIVFFlatCodePackerInterleaved( size_t list_size, uint32_t dim, diff --git a/faiss/gpu/impl/RaftIVFFlat.cuh b/faiss/gpu/impl/RaftIVFFlat.cuh index 3aba501c9f..4f8c89ecb0 100644 --- a/faiss/gpu/impl/RaftIVFFlat.cuh +++ b/faiss/gpu/impl/RaftIVFFlat.cuh @@ -22,16 +22,15 @@ #pragma once +#include #include -#include #include -#include - #include #include +#pragma GCC visibility push(default) namespace faiss { namespace gpu { @@ -52,6 +51,9 @@ class RaftIVFFlat : public IVFFlat { ~RaftIVFFlat() override; + /// Reserve GPU memory in our inverted lists for this number of vectors + void reserveMemory(idx_t numVecs) override; + /// Find the approximate k nearest neigbors for `queries` against /// our database void search( @@ -83,11 +85,7 @@ class RaftIVFFlat : public IVFFlat { Tensor& vecs, Tensor& indices) override; - /// Reserve GPU memory in our inverted lists for this number of vectors - // void reserveMemory(idx_t numVecs) override; - - /// Clear out all inverted lists, but retain the coarse quantizer - /// and the product quantizer info + /// Clear out the Raft index void reset() override; /// For debugging purposes, return the list length of a particular @@ -101,15 +99,17 @@ class RaftIVFFlat : public IVFFlat { std::vector getListVectorData(idx_t listId, bool gpuFormat) const override; + /// Update our Raft index with this quantizer instance; may be a CPU + /// or GPU quantizer void updateQuantizer(Index* quantizer) override; /// Copy all inverted lists from a CPU representation to ourselves void copyInvertedListsFrom(const InvertedLists* ivf) override; - /// Filter out matrix rows containing NaN values - void validRowIndices_(Tensor& vecs, bool* nan_flag); + /// Replace the Raft index + void setRaftIndex(raft::neighbors::ivf_flat::index&& idx); - protected: + private: /// Adds a set of codes and indices to a list, with the representation /// coming from the CPU equivalent void addEncodedVectorsToList_( @@ -147,3 +147,4 @@ struct RaftIVFFlatCodePackerInterleaved : CodePacker { } // namespace gpu } // namespace faiss +#pragma GCC visibility pop diff --git a/faiss/gpu/impl/RaftIVFPQ.cu b/faiss/gpu/impl/RaftIVFPQ.cu new file mode 100644 index 0000000000..b26025dd47 --- /dev/null +++ b/faiss/gpu/impl/RaftIVFPQ.cu @@ -0,0 +1,546 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace faiss { +namespace gpu { + +RaftIVFPQ::RaftIVFPQ( + GpuResources* resources, + int dim, + idx_t nlist, + faiss::MetricType metric, + float metricArg, + int numSubQuantizers, + int bitsPerSubQuantizer, + bool useFloat16LookupTables, + bool useMMCodeDistance, + bool interleavedLayout, + float* pqCentroidData, + IndicesOptions indicesOptions, + MemorySpace space) + : IVFPQ(resources, + dim, + nlist, + metric, + metricArg, + numSubQuantizers, + bitsPerSubQuantizer, + useFloat16LookupTables, + useMMCodeDistance, + interleavedLayout, + // skip ptr allocations in base class (handled by RAFT + // internally) false, + pqCentroidData, + indicesOptions, + space) { + FAISS_THROW_IF_NOT_MSG( + indicesOptions == INDICES_64_BIT, + "only INDICES_64_BIT is supported for RAFT index"); +} + +RaftIVFPQ::~RaftIVFPQ() {} + +void RaftIVFPQ::reserveMemory(idx_t numVecs) { + fprintf(stderr, + "WARN: reserveMemory is NOP. Pre-allocation of IVF lists is not supported with RAFT enabled.\n"); +} + +void RaftIVFPQ::reset() { + raft_knn_index.reset(); +} + +size_t RaftIVFPQ::reclaimMemory() { + fprintf(stderr, + "WARN: reclaimMemory is NOP. reclaimMemory is not supported with RAFT enabled.\n"); + return 0; +} + +void RaftIVFPQ::setPrecomputedCodes(Index* quantizer, bool enable) {} + +idx_t RaftIVFPQ::getListLength(idx_t listId) const { + FAISS_ASSERT(raft_knn_index.has_value()); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + uint32_t size; + raft::update_host( + &size, + raft_knn_index.value().list_sizes().data_handle() + listId, + 1, + raft_handle.get_stream()); + raft_handle.sync_stream(); + + return static_cast(size); +} + +void RaftIVFPQ::updateQuantizer(Index* quantizer) { + FAISS_THROW_IF_NOT(quantizer->is_trained); + + // Must match our basic IVF parameters + FAISS_THROW_IF_NOT(quantizer->d == getDim()); + FAISS_THROW_IF_NOT(quantizer->ntotal == getNumLists()); + + auto stream = resources_->getDefaultStreamCurrentDevice(); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + raft::neighbors::ivf_pq::index_params pams; + pams.metric = metricFaissToRaft(metric_, false); + pams.codebook_kind = raft::neighbors::ivf_pq::codebook_gen::PER_SUBSPACE; + pams.n_lists = numLists_; + pams.pq_bits = bitsPerSubQuantizer_; + pams.pq_dim = numSubQuantizers_; + raft_knn_index.emplace(raft_handle, pams, static_cast(dim_)); + + raft::neighbors::ivf_pq::helpers::reset_index( + raft_handle, &raft_knn_index.value()); + raft::neighbors::ivf_pq::helpers::make_rotation_matrix( + raft_handle, &(raft_knn_index.value()), false); + + // If the index instance is a GpuIndexFlat, then we can use direct access to + // the centroids within. + auto gpuQ = dynamic_cast(quantizer); + + if (gpuQ) { + auto gpuData = gpuQ->getGpuData(); + + if (gpuData->getUseFloat16()) { + DeviceTensor centroids( + resources_, + makeSpaceAlloc(AllocType::FlatData, space_, stream), + {getNumLists(), getDim()}); + + // The FlatIndex keeps its data in float16; we need to reconstruct + // as float32 and store locally + gpuData->reconstruct(0, gpuData->getSize(), centroids); + + raft::neighbors::ivf_pq::helpers::set_centers( + raft_handle, + &(raft_knn_index.value()), + raft::make_device_matrix_view( + centroids.data(), numLists_, dim_)); + } else { + /// No reconstruct needed since the centers are already in float32 + // The FlatIndex keeps its data in float32, so we can merely + // reference it + auto centroids = gpuData->getVectorsFloat32Ref(); + + raft::neighbors::ivf_pq::helpers::set_centers( + raft_handle, + &(raft_knn_index.value()), + raft::make_device_matrix_view( + centroids.data(), numLists_, dim_)); + } + } else { + DeviceTensor centroids( + resources_, + makeSpaceAlloc(AllocType::FlatData, space_, stream), + {getNumLists(), getDim()}); + + // Otherwise, we need to reconstruct all vectors from the index and copy + // them to the GPU, in order to have access as needed for residual + // computation + auto vecs = std::vector(getNumLists() * getDim()); + quantizer->reconstruct_n(0, quantizer->ntotal, vecs.data()); + + centroids.copyFrom(vecs, stream); + + raft::neighbors::ivf_pq::helpers::set_centers( + raft_handle, + &(raft_knn_index.value()), + raft::make_device_matrix_view( + centroids.data(), numLists_, dim_)); + } + + setPQCentroids_(); +} + +/// Return the list indices of a particular list back to the CPU +std::vector RaftIVFPQ::getListIndices(idx_t listId) const { + FAISS_ASSERT(raft_knn_index.has_value()); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + auto stream = raft_handle.get_stream(); + + idx_t listSize = getListLength(listId); + + std::vector vec(listSize); + + // fetch the list indices ptr on host + idx_t* list_indices_ptr; + + raft::update_host( + &list_indices_ptr, + const_cast( + raft_knn_index.value().inds_ptrs().data_handle()) + + listId, + 1, + stream); + raft_handle.sync_stream(); + + raft::update_host(vec.data(), list_indices_ptr, listSize, stream); + raft_handle.sync_stream(); + + return vec; +} + +/// Performs search when we are already given the IVF cells to look at +/// (GpuIndexIVF::search_preassigned implementation) +void RaftIVFPQ::searchPreassigned( + Index* coarseQuantizer, + Tensor& vecs, + Tensor& ivfDistances, + Tensor& ivfAssignments, + int k, + Tensor& outDistances, + Tensor& outIndices, + bool storePairs) { + // TODO: Fill this in! +} + +size_t RaftIVFPQ::getGpuListEncodingSize_(idx_t listId) { + return static_cast( + raft_knn_index.value().get_list_size_in_bytes(listId)); +} + +/// Return the encoded vectors of a particular list back to the CPU +std::vector RaftIVFPQ::getListVectorData(idx_t listId, bool gpuFormat) + const { + if (gpuFormat) { + FAISS_THROW_MSG( + "gpuFormat should be false for RAFT indices. Unpacked codes are flat."); + } + FAISS_ASSERT(raft_knn_index.has_value()); + + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + auto stream = raft_handle.get_stream(); + + idx_t listSize = getListLength(listId); + + auto cpuListSizeInBytes = getCpuVectorsEncodingSize_(listSize); + + std::vector flat_codes( + cpuListSizeInBytes, static_cast(0)); + + idx_t maxBatchSize = 65536; + for (idx_t offset_b = 0; offset_b < listSize; offset_b += maxBatchSize) { + uint32_t batchSize = min(maxBatchSize, listSize - offset_b); + uint32_t bufferSize = getCpuVectorsEncodingSize_(batchSize); + uint32_t codesOffset = getCpuVectorsEncodingSize_(offset_b); + + // Fetch flat PQ codes for the current batch + auto codes_d = raft::make_device_vector( + raft_handle, static_cast(bufferSize)); + + raft::neighbors::ivf_pq::helpers::unpack_contiguous_list_data( + raft_handle, + raft_knn_index.value(), + codes_d.data_handle(), + batchSize, + listId, + offset_b); + + // Copy the flat PQ codes to host + raft::update_host( + flat_codes.data() + codesOffset, + codes_d.data_handle(), + bufferSize, + stream); + raft_handle.sync_stream(); + } + + return flat_codes; +} + +/// Find the approximate k nearest neighbors for `queries` against +/// our database +void RaftIVFPQ::search( + Index* coarseQuantizer, + Tensor& queries, + int nprobe, + int k, + Tensor& outDistances, + Tensor& outIndices) { + uint32_t numQueries = queries.getSize(0); + uint32_t cols = queries.getSize(1); + idx_t k_ = std::min(static_cast(k), raft_knn_index.value().size()); + + // Device is already set in GpuIndex::search + FAISS_ASSERT(raft_knn_index.has_value()); + FAISS_ASSERT(numQueries > 0); + FAISS_ASSERT(cols == dim_); + FAISS_THROW_IF_NOT(nprobe > 0 && nprobe <= numLists_); + + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + raft::neighbors::ivf_pq::search_params pams; + pams.n_probes = nprobe; + pams.lut_dtype = useFloat16LookupTables_ ? CUDA_R_16F : CUDA_R_32F; + + auto queries_view = raft::make_device_matrix_view( + queries.data(), (idx_t)numQueries, (idx_t)cols); + auto out_inds_view = raft::make_device_matrix_view( + outIndices.data(), (idx_t)numQueries, (idx_t)k_); + auto out_dists_view = raft::make_device_matrix_view( + outDistances.data(), (idx_t)numQueries, (idx_t)k_); + + raft::neighbors::ivf_pq::search( + raft_handle, + pams, + raft_knn_index.value(), + queries_view, + out_inds_view, + out_dists_view); + + /// Identify NaN rows and mask their nearest neighbors + auto nan_flag = raft::make_device_vector(raft_handle, numQueries); + + validRowIndices(resources_, queries, nan_flag.data_handle()); + + raft::linalg::map_offset( + raft_handle, + raft::make_device_vector_view(outIndices.data(), numQueries * k_), + [nan_flag = nan_flag.data_handle(), + out_inds = outIndices.data(), + k_] __device__(uint32_t i) { + uint32_t row = i / k_; + if (!nan_flag[row]) + return idx_t(-1); + return out_inds[i]; + }); + + float max_val = std::numeric_limits::max(); + raft::linalg::map_offset( + raft_handle, + raft::make_device_vector_view(outDistances.data(), numQueries * k_), + [nan_flag = nan_flag.data_handle(), + out_dists = outDistances.data(), + max_val, + k_] __device__(uint32_t i) { + uint32_t row = i / k_; + if (!nan_flag[row]) + return max_val; + return out_dists[i]; + }); + raft_handle.sync_stream(); +} + +idx_t RaftIVFPQ::addVectors( + Index* coarseQuantizer, + Tensor& vecs, + Tensor& indices) { + /// NB: The coarse quantizer is ignored here. The user is assumed to have + /// called updateQuantizer() to update the RAFT index if the quantizer was + /// modified externally + + FAISS_ASSERT(raft_knn_index.has_value()); + + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + /// Remove rows containing NaNs + idx_t n_rows_valid = inplaceGatherFilteredRows(resources_, vecs, indices); + + raft_knn_index.emplace(raft::neighbors::ivf_pq::extend( + raft_handle, + raft::make_device_matrix_view( + vecs.data(), n_rows_valid, dim_), + std::make_optional>( + raft::make_device_vector_view( + indices.data(), n_rows_valid)), + raft_knn_index.value())); + + return n_rows_valid; +} + +void RaftIVFPQ::copyInvertedListsFrom(const InvertedLists* ivf) { + size_t nlist = ivf ? ivf->nlist : 0; + size_t ntotal = ivf ? ivf->compute_ntotal() : 0; + + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + std::vector list_sizes_(nlist); + std::vector indices_(ntotal); + + // the index must already exist + FAISS_ASSERT(raft_knn_index.has_value()); + + auto& raft_lists = raft_knn_index.value().lists(); + + // conservative memory alloc for cloning cpu inverted lists + raft::neighbors::ivf_pq::list_spec raft_list_spec{ + static_cast(bitsPerSubQuantizer_), + static_cast(numSubQuantizers_), + true}; + + for (size_t i = 0; i < nlist; ++i) { + size_t listSize = ivf->list_size(i); + + // GPU index can only support max int entries per list + FAISS_THROW_IF_NOT_FMT( + listSize <= (size_t)std::numeric_limits::max(), + "GPU inverted list can only support " + "%zu entries; %zu found", + (size_t)std::numeric_limits::max(), + listSize); + + // store the list size + list_sizes_[i] = static_cast(listSize); + + // This RAFT list must currently be empty + FAISS_ASSERT(getListLength(i) == 0); + + raft::neighbors::ivf::resize_list( + raft_handle, + raft_lists[i], + raft_list_spec, + static_cast(listSize), + static_cast(0)); + } + + raft::update_device( + raft_knn_index.value().list_sizes().data_handle(), + list_sizes_.data(), + nlist, + raft_handle.get_stream()); + + // Update the pointers and the sizes + raft::neighbors::ivf_pq::helpers::recompute_internal_state( + raft_handle, &(raft_knn_index.value())); + + for (size_t i = 0; i < nlist; ++i) { + size_t listSize = ivf->list_size(i); + addEncodedVectorsToList_( + i, ivf->get_codes(i), ivf->get_ids(i), listSize); + } +} + +void RaftIVFPQ::setRaftIndex(raft::neighbors::ivf_pq::index&& idx) { + raft_knn_index.emplace(std::move(idx)); + setBasePQCentroids_(); +} + +void RaftIVFPQ::addEncodedVectorsToList_( + idx_t listId, + const void* codes, + const idx_t* indices, + idx_t numVecs) { + auto stream = resources_->getDefaultStreamCurrentDevice(); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + // If there's nothing to add, then there's nothing we have to do + if (numVecs == 0) { + return; + } + + // The GPU might have a different layout of the memory + auto gpuListSizeInBytes = getGpuListEncodingSize_(listId); + + // We only have int32 length representations on the GPU per each + // list; the length is in sizeof(char) + FAISS_ASSERT(gpuListSizeInBytes <= (size_t)std::numeric_limits::max()); + + idx_t maxBatchSize = 4096; + for (idx_t offset_b = 0; offset_b < numVecs; offset_b += maxBatchSize) { + uint32_t batchSize = min(maxBatchSize, numVecs - offset_b); + uint32_t bufferSize = getCpuVectorsEncodingSize_(batchSize); + uint32_t codesOffset = getCpuVectorsEncodingSize_(offset_b); + + // Translate the codes as needed to our preferred form + auto codes_d = raft::make_device_vector( + raft_handle, static_cast(bufferSize)); + raft::update_device( + codes_d.data_handle(), + static_cast(codes) + codesOffset, + bufferSize, + stream); + + raft::neighbors::ivf_pq::helpers::pack_contiguous_list_data( + raft_handle, + &(raft_knn_index.value()), + codes_d.data_handle(), + batchSize, + listId, + offset_b); + } + + /// Handle the indices as well + idx_t* list_indices_ptr; + + // fetch the list indices ptr on host + raft::update_host( + &list_indices_ptr, + raft_knn_index.value().inds_ptrs().data_handle() + listId, + 1, + stream); + raft_handle.sync_stream(); + + raft::update_device(list_indices_ptr, indices, numVecs, stream); +} + +void RaftIVFPQ::setPQCentroids_() { + auto stream = resources_->getDefaultStreamCurrentDevice(); + + raft::copy( + raft_knn_index.value().pq_centers().data_handle(), + pqCentroidsInnermostCode_.data(), + pqCentroidsInnermostCode_.numElements(), + stream); +} + +void RaftIVFPQ::setBasePQCentroids_() { + auto stream = resources_->getDefaultStreamCurrentDevice(); + + raft::copy( + pqCentroidsInnermostCode_.data(), + raft_knn_index.value().pq_centers().data_handle(), + raft_knn_index.value().pq_centers().size(), + stream); + + DeviceTensor pqCentroidsMiddleCode( + resources_, + makeDevAlloc(AllocType::Quantizer, stream), + {numSubQuantizers_, numSubQuantizerCodes_, dimPerSubQuantizer_}); + + runTransposeAny( + pqCentroidsInnermostCode_, 1, 2, pqCentroidsMiddleCode, stream); + + pqCentroidsMiddleCode_ = std::move(pqCentroidsMiddleCode); +} + +} // namespace gpu +} // namespace faiss \ No newline at end of file diff --git a/faiss/gpu/impl/RaftIVFPQ.cuh b/faiss/gpu/impl/RaftIVFPQ.cuh new file mode 100644 index 0000000000..a79db3c40d --- /dev/null +++ b/faiss/gpu/impl/RaftIVFPQ.cuh @@ -0,0 +1,150 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +#include + +#pragma GCC visibility push(default) +namespace faiss { +namespace gpu { +/// Implementing class for IVFPQ on the GPU +class RaftIVFPQ : public IVFPQ { + public: + RaftIVFPQ( + GpuResources* resources, + int dim, + idx_t nlist, + faiss::MetricType metric, + float metricArg, + int numSubQuantizers, + int bitsPerSubQuantizer, + bool useFloat16LookupTables, + bool useMMCodeDistance, + bool interleavedLayout, + float* pqCentroidData, + IndicesOptions indicesOptions, + MemorySpace space); + + ~RaftIVFPQ() override; + + /// Reserve GPU memory in our inverted lists for this number of vectors + void reserveMemory(idx_t numVecs) override; + + /// Clear out the RAFT index + void reset() override; + + /// After adding vectors, one can call this to reclaim device memory + /// to exactly the amount needed. Returns space reclaimed in bytes + size_t reclaimMemory() override; + + /// Enable or disable pre-computed codes. The quantizer is needed to gather + /// the IVF centroids for use + void setPrecomputedCodes(Index* coarseQuantizer, bool enable) override; + + /// Find the approximate k nearest neigbors for `queries` against + /// our database + void search( + Index* coarseQuantizer, + Tensor& queries, + int nprobe, + int k, + Tensor& outDistances, + Tensor& outIndices) override; + + /// Performs search when we are already given the IVF cells to look at + /// (GpuIndexIVF::search_preassigned implementation) + void searchPreassigned( + Index* coarseQuantizer, + Tensor& vecs, + Tensor& ivfDistances, + Tensor& ivfAssignments, + int k, + Tensor& outDistances, + Tensor& outIndices, + bool storePairs) override; + + /// Return the encoded vectors of a particular list back to the CPU + std::vector getListVectorData(idx_t listId, bool gpuFormat) + const override; + + /// Update our Raft index with this quantizer instance; may be a CPU + /// or GPU quantizer + void updateQuantizer(Index* quantizer) override; + + /// Copy all inverted lists from a CPU representation to ourselves + void copyInvertedListsFrom(const InvertedLists* ivf) override; + + /// Replace the Raft index + void setRaftIndex(raft::neighbors::ivf_pq::index&& idx); + + /// Classify and encode/add vectors to our IVF lists. + /// The input data must be on our current device. + /// Returns the number of vectors successfully added. Vectors may + /// not be able to be added because they contain NaNs. + idx_t addVectors( + Index* coarseQuantizer, + Tensor& vecs, + Tensor& indices) override; + + /// For debugging purposes, return the list length of a particular + /// list + idx_t getListLength(idx_t listId) const override; + + /// Return the list indices of a particular list back to the CPU + std::vector getListIndices(idx_t listId) const override; + + private: + /// Adds a set of codes and indices to a list, with the representation + /// coming from the CPU equivalent + void addEncodedVectorsToList_( + idx_t listId, + // resident on the host + const void* codes, + // resident on the host + const idx_t* indices, + idx_t numVecs) override; + + /// Returns the encoding size for a PQ-encoded IVF list + size_t getGpuListEncodingSize_(idx_t listId); + + /// Copy the PQ centroids to the Raft index. The data is already in the + /// preferred format with the transpose performed by the IVFPQ class helper. + void setPQCentroids_(); + + /// Update the product quantizer centroids buffer held in the IVFPQ class. + /// Used when the RAFT index was updated externally. + void setBasePQCentroids_(); + + /// optional around the Raft IVF-PQ index + std::optional> raft_knn_index{ + std::nullopt}; +}; + +} // namespace gpu +} // namespace faiss +#pragma GCC visibility pop diff --git a/faiss/gpu/test/TestGpuIndexFlat.cpp b/faiss/gpu/test/TestGpuIndexFlat.cpp index 6d9c83e547..d7a7b45ec0 100644 --- a/faiss/gpu/test/TestGpuIndexFlat.cpp +++ b/faiss/gpu/test/TestGpuIndexFlat.cpp @@ -268,6 +268,7 @@ TEST(TestGpuIndexFlat, QueryEmpty) { faiss::gpu::GpuIndexFlatConfig config; config.device = 0; config.useFloat16 = false; + config.use_raft = false; int dim = 128; faiss::gpu::GpuIndexFlatL2 gpuIndex(&res, dim, config); diff --git a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp index 9fb88e2687..a90825bffb 100644 --- a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +++ b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -30,7 +31,6 @@ #include #include #include -#include "faiss/gpu/GpuIndicesOptions.h" // FIXME: figure out a better way to test fp16 constexpr float kF16MaxRelErr = 0.3f; @@ -57,7 +57,7 @@ struct Options { device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1); - use_raft = false; + useRaft = false; } std::string toString() const { @@ -65,7 +65,7 @@ struct Options { str << "IVFFlat device " << device << " numVecs " << numAdd << " dim " << dim << " numCentroids " << numCentroids << " nprobe " << nprobe << " numQuery " << numQuery << " k " << k << " indicesOpt " - << indicesOpt << " use_raft " << use_raft; + << indicesOpt << " useRaft " << useRaft; return str.str(); } @@ -79,7 +79,7 @@ struct Options { int k; int device; faiss::gpu::IndicesOptions indicesOpt; - bool use_raft; + bool useRaft; }; void queryTest( @@ -110,7 +110,7 @@ void queryTest( config.device = opt.device; config.indicesOptions = opt.indicesOpt; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; - config.use_raft = opt.use_raft; + config.use_raft = opt.useRaft; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, cpuIndex.d, cpuIndex.nlist, cpuIndex.metric_type, config); @@ -137,7 +137,7 @@ void queryTest( void addTest( faiss::MetricType metricType, bool useFloat16CoarseQuantizer, - bool use_raft) { + bool useRaft) { for (int tries = 0; tries < 2; ++tries) { Options opt; @@ -162,9 +162,9 @@ void addTest( faiss::gpu::GpuIndexIVFFlatConfig config; config.device = opt.device; config.indicesOptions = - use_raft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; + useRaft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; - config.use_raft = use_raft; + config.use_raft = useRaft; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, cpuIndex.d, cpuIndex.nlist, cpuIndex.metric_type, config); @@ -188,7 +188,7 @@ void addTest( } } -void copyToTest(bool useFloat16CoarseQuantizer, bool use_raft) { +void copyToTest(bool useFloat16CoarseQuantizer, bool useRaft) { Options opt; std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); @@ -199,9 +199,9 @@ void copyToTest(bool useFloat16CoarseQuantizer, bool use_raft) { faiss::gpu::GpuIndexIVFFlatConfig config; config.device = opt.device; config.indicesOptions = - use_raft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; + useRaft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; - config.use_raft = use_raft; + config.use_raft = useRaft; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); @@ -241,7 +241,7 @@ void copyToTest(bool useFloat16CoarseQuantizer, bool use_raft) { compFloat16 ? 0.30f : 0.015f); } -void copyFromTest(bool useFloat16CoarseQuantizer, bool use_raft) { +void copyFromTest(bool useFloat16CoarseQuantizer, bool useRaft) { Options opt; std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); @@ -260,9 +260,9 @@ void copyFromTest(bool useFloat16CoarseQuantizer, bool use_raft) { faiss::gpu::GpuIndexIVFFlatConfig config; config.device = opt.device; config.indicesOptions = - use_raft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; + useRaft ? faiss::gpu::INDICES_64_BIT : opt.indicesOpt; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; - config.use_raft = use_raft; + config.use_raft = useRaft; faiss::gpu::GpuIndexIVFFlat gpuIndex(&res, 1, 1, faiss::METRIC_L2, config); gpuIndex.nprobe = 1; @@ -334,7 +334,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_L2) { queryTest(opt, faiss::METRIC_L2, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_L2, false); #endif @@ -345,7 +345,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_IP) { queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #endif @@ -358,7 +358,7 @@ TEST(TestGpuIndexIVFFlat, LargeBatch) { queryTest(opt, faiss::METRIC_L2, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_L2, false); #endif @@ -371,7 +371,7 @@ TEST(TestGpuIndexIVFFlat, Float16_32_Query_L2) { queryTest(opt, faiss::METRIC_L2, true); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_L2, true); #endif @@ -382,7 +382,7 @@ TEST(TestGpuIndexIVFFlat, Float16_32_Query_IP) { queryTest(opt, faiss::METRIC_INNER_PRODUCT, true); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_INNER_PRODUCT, true); #endif @@ -399,7 +399,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_L2_64) { queryTest(opt, faiss::METRIC_L2, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_L2, false); #endif @@ -411,7 +411,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_IP_64) { queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #endif @@ -423,7 +423,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_L2_128) { queryTest(opt, faiss::METRIC_L2, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_L2, false); #endif @@ -435,7 +435,7 @@ TEST(TestGpuIndexIVFFlat, Float32_Query_IP_128) { queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #if defined USE_NVIDIA_RAFT - opt.use_raft = true; + opt.useRaft = true; opt.indicesOpt = faiss::gpu::INDICES_64_BIT; queryTest(opt, faiss::METRIC_INNER_PRODUCT, false); #endif @@ -499,6 +499,7 @@ TEST(TestGpuIndexIVFFlat, Float32_negative) { faiss::gpu::GpuIndexIVFFlatConfig config; config.device = opt.device; config.indicesOptions = opt.indicesOpt; + config.use_raft = false; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, cpuIndex.d, cpuIndex.nlist, cpuIndex.metric_type, config); @@ -571,6 +572,7 @@ TEST(TestGpuIndexIVFFlat, QueryNaN) { config.device = opt.device; config.indicesOptions = opt.indicesOpt; config.flatConfig.useFloat16 = faiss::gpu::randBool(); + config.use_raft = false; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); @@ -639,6 +641,7 @@ TEST(TestGpuIndexIVFFlat, AddNaN) { config.device = opt.device; config.indicesOptions = opt.indicesOpt; config.flatConfig.useFloat16 = faiss::gpu::randBool(); + config.use_raft = false; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); gpuIndex.nprobe = opt.nprobe; @@ -720,6 +723,7 @@ TEST(TestGpuIndexIVFFlat, UnifiedMemory) { faiss::gpu::GpuIndexIVFFlatConfig config; config.device = device; config.memorySpace = faiss::gpu::MemorySpace::Unified; + config.use_raft = false; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, dim, numCentroids, faiss::METRIC_L2, config); @@ -797,6 +801,7 @@ TEST(TestGpuIndexIVFFlat, LongIVFList) { faiss::gpu::GpuIndexIVFFlatConfig config; config.device = device; + config.use_raft = false; faiss::gpu::GpuIndexIVFFlat gpuIndex( &res, dim, numCentroids, faiss::METRIC_L2, config); diff --git a/faiss/gpu/test/TestGpuIndexIVFPQ.cpp b/faiss/gpu/test/TestGpuIndexIVFPQ.cpp index 1bdef31914..9cc52bc788 100644 --- a/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +++ b/faiss/gpu/test/TestGpuIndexIVFPQ.cpp @@ -35,6 +35,22 @@ void pickEncoding(int& codes, int& dim) { } } +void pickRaftEncoding(int& codes, int& dim, int bitsPerCode) { + // Above 32 doesn't work with no precomputed codes + std::vector dimSizes{4, 8, 10, 12, 16, 20, 24, 28, 32}; + + while (true) { + codes = faiss::gpu::randVal(0, 96); + dim = codes * dimSizes[faiss::gpu::randVal(0, dimSizes.size() - 1)]; + + // for such a small test, super-low or high dim is more likely to + // generate comparison errors + if (dim < 256 && dim >= 64 && (codes * bitsPerCode) % 8 == 0) { + return; + } + } +} + struct Options { Options() { numAdd = faiss::gpu::randVal(2000, 5000); @@ -43,9 +59,10 @@ struct Options { pickEncoding(codes, dim); - // TODO: Change back to `faiss::gpu::randVal(3, 7)` when we officially - // support non-multiple of 8 subcodes for IVFPQ. + // TODO: Change back to `faiss::gpu::randVal(3, 7)` when we + // officially support non-multiple of 8 subcodes for IVFPQ. bitsPerCode = 8; + nprobe = std::min(faiss::gpu::randVal(40, 1000), numCentroids); numQuery = faiss::gpu::randVal(4, 8); @@ -66,6 +83,9 @@ struct Options { } device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1); + + interleavedLayout = false; + useRaft = false; } std::string toString() const { @@ -105,50 +125,66 @@ struct Options { faiss::gpu::IndicesOptions indicesOpt; bool useFloat16; int device; + bool interleavedLayout; + bool useRaft; }; -TEST(TestGpuIndexIVFPQ, Query_L2) { - for (int tries = 0; tries < 2; ++tries) { - Options opt; +void queryTest(Options opt, faiss::MetricType metricType) { + std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); + std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); - std::vector trainVecs = - faiss::gpu::randVecs(opt.numTrain, opt.dim); - std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); + faiss::IndexFlatL2 coarseQuantizerL2(opt.dim); + faiss::IndexFlatIP coarseQuantizerIP(opt.dim); + faiss::Index* quantizer = metricType == faiss::METRIC_L2 + ? (faiss::Index*)&coarseQuantizerL2 + : (faiss::Index*)&coarseQuantizerIP; - faiss::IndexFlatL2 coarseQuantizer(opt.dim); - faiss::IndexIVFPQ cpuIndex( - &coarseQuantizer, - opt.dim, - opt.numCentroids, - opt.codes, - opt.bitsPerCode); - cpuIndex.nprobe = opt.nprobe; - cpuIndex.train(opt.numTrain, trainVecs.data()); - cpuIndex.add(opt.numAdd, addVecs.data()); + faiss::IndexIVFPQ cpuIndex( + quantizer, opt.dim, opt.numCentroids, opt.codes, opt.bitsPerCode); + cpuIndex.metric_type = metricType; + cpuIndex.nprobe = opt.nprobe; + cpuIndex.train(opt.numTrain, trainVecs.data()); + cpuIndex.add(opt.numAdd, addVecs.data()); - // Use the default temporary memory management to test the memory - // manager - faiss::gpu::StandardGpuResources res; + // Use the default temporary memory management to test the memory + // manager + faiss::gpu::StandardGpuResources res; - faiss::gpu::GpuIndexIVFPQConfig config; - config.device = opt.device; - config.usePrecomputedTables = (tries % 2 == 0); - config.indicesOptions = opt.indicesOpt; - config.useFloat16LookupTables = opt.useFloat16; + faiss::gpu::GpuIndexIVFPQConfig config; + config.device = opt.device; + config.usePrecomputedTables = opt.usePrecomputed; + config.indicesOptions = opt.indicesOpt; + config.useFloat16LookupTables = opt.useFloat16; + config.interleavedLayout = opt.interleavedLayout; + config.use_raft = opt.useRaft; - faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); - gpuIndex.nprobe = opt.nprobe; + faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); + gpuIndex.nprobe = opt.nprobe; - faiss::gpu::compareIndices( - cpuIndex, - gpuIndex, - opt.numQuery, - opt.dim, - opt.k, - opt.toString(), - opt.getCompareEpsilon(), - opt.getPctMaxDiff1(), - opt.getPctMaxDiffN()); + faiss::gpu::compareIndices( + cpuIndex, + gpuIndex, + opt.numQuery, + opt.dim, + opt.k, + opt.toString(), + opt.getCompareEpsilon(), + opt.getPctMaxDiff1(), + opt.getPctMaxDiffN()); +} + +TEST(TestGpuIndexIVFPQ, Query_L2) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + opt.usePrecomputed = (tries % 2 == 0); + queryTest(opt, faiss::MetricType::METRIC_L2); + } +} + +TEST(TestGpuIndexIVFPQ, Query_IP) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + queryTest(opt, faiss::MetricType::METRIC_INNER_PRODUCT); } } @@ -161,45 +197,10 @@ TEST(TestGpuIndexIVFPQ, LargeBatch) { opt.dim = 4; opt.numQuery = 100000; opt.codes = 2; + opt.usePrecomputed = usePrecomputed; + opt.useFloat16 = false; - std::vector trainVecs = - faiss::gpu::randVecs(opt.numTrain, opt.dim); - std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); - - faiss::IndexFlatL2 coarseQuantizer(opt.dim); - faiss::IndexIVFPQ cpuIndex( - &coarseQuantizer, - opt.dim, - opt.numCentroids, - opt.codes, - opt.bitsPerCode); - cpuIndex.nprobe = opt.nprobe; - cpuIndex.train(opt.numTrain, trainVecs.data()); - cpuIndex.add(opt.numAdd, addVecs.data()); - - // Use the default temporary memory management to test the memory - // manager - faiss::gpu::StandardGpuResources res; - - faiss::gpu::GpuIndexIVFPQConfig config; - config.device = opt.device; - config.usePrecomputedTables = usePrecomputed; - config.indicesOptions = opt.indicesOpt; - config.useFloat16LookupTables = false; - - faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); - gpuIndex.nprobe = opt.nprobe; - - faiss::gpu::compareIndices( - cpuIndex, - gpuIndex, - opt.numQuery, - opt.dim, - opt.k, - opt.toString(), - opt.getCompareEpsilon(), - opt.getPctMaxDiff1(), - opt.getPctMaxDiffN()); + queryTest(opt, faiss::MetricType::METRIC_L2); } } @@ -234,6 +235,7 @@ void testMMCodeDistance(faiss::MetricType mt) { config.usePrecomputedTables = false; config.useMMCodeDistance = true; config.indicesOptions = opt.indicesOpt; + config.use_raft = false; // Make sure that the float16 version works as well config.useFloat16LookupTables = (tries % 2 == 0); @@ -284,6 +286,7 @@ void testMMCodeDistance(faiss::MetricType mt) { config.device = opt.device; config.usePrecomputedTables = false; config.indicesOptions = opt.indicesOpt; + config.use_raft = false; // Make sure that the float16 version works as well config.useFloat16LookupTables = (dimPerSubQ == 7); @@ -312,53 +315,6 @@ TEST(TestGpuIndexIVFPQ, Query_IP_MMCodeDistance) { testMMCodeDistance(faiss::MetricType::METRIC_INNER_PRODUCT); } -TEST(TestGpuIndexIVFPQ, Query_IP) { - for (int tries = 0; tries < 2; ++tries) { - Options opt; - - std::vector trainVecs = - faiss::gpu::randVecs(opt.numTrain, opt.dim); - std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); - - faiss::IndexFlatIP coarseQuantizer(opt.dim); - faiss::IndexIVFPQ cpuIndex( - &coarseQuantizer, - opt.dim, - opt.numCentroids, - opt.codes, - opt.bitsPerCode); - cpuIndex.metric_type = faiss::MetricType::METRIC_INNER_PRODUCT; - - cpuIndex.nprobe = opt.nprobe; - cpuIndex.train(opt.numTrain, trainVecs.data()); - cpuIndex.add(opt.numAdd, addVecs.data()); - - // Use the default temporary memory management to test the memory - // manager - faiss::gpu::StandardGpuResources res; - - faiss::gpu::GpuIndexIVFPQConfig config; - config.device = opt.device; - config.usePrecomputedTables = false; // not supported/required for IP - config.indicesOptions = opt.indicesOpt; - config.useFloat16LookupTables = opt.useFloat16; - - faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); - gpuIndex.nprobe = opt.nprobe; - - faiss::gpu::compareIndices( - cpuIndex, - gpuIndex, - opt.numQuery, - opt.dim, - opt.k, - opt.toString(), - opt.getCompareEpsilon(), - opt.getPctMaxDiff1(), - opt.getPctMaxDiffN()); - } -} - TEST(TestGpuIndexIVFPQ, Float16Coarse) { Options opt; @@ -384,6 +340,7 @@ TEST(TestGpuIndexIVFPQ, Float16Coarse) { config.usePrecomputedTables = opt.usePrecomputed; config.indicesOptions = opt.indicesOpt; config.useFloat16LookupTables = opt.useFloat16; + config.use_raft = false; faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); gpuIndex.nprobe = opt.nprobe; @@ -403,104 +360,68 @@ TEST(TestGpuIndexIVFPQ, Float16Coarse) { opt.getPctMaxDiffN()); } -TEST(TestGpuIndexIVFPQ, Add_L2) { - for (int tries = 0; tries < 2; ++tries) { - Options opt; +void addTest(Options opt, faiss::MetricType metricType) { + std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); + std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); - std::vector trainVecs = - faiss::gpu::randVecs(opt.numTrain, opt.dim); - std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); + faiss::IndexFlatL2 coarseQuantizerL2(opt.dim); + faiss::IndexFlatIP coarseQuantizerIP(opt.dim); + faiss::Index* quantizer = metricType == faiss::METRIC_L2 + ? (faiss::Index*)&coarseQuantizerL2 + : (faiss::Index*)&coarseQuantizerIP; - faiss::IndexFlatL2 coarseQuantizer(opt.dim); - faiss::IndexIVFPQ cpuIndex( - &coarseQuantizer, - opt.dim, - opt.numCentroids, - opt.codes, - opt.bitsPerCode); - cpuIndex.nprobe = opt.nprobe; - cpuIndex.train(opt.numTrain, trainVecs.data()); + faiss::IndexIVFPQ cpuIndex( + quantizer, opt.dim, opt.numCentroids, opt.codes, opt.bitsPerCode); + cpuIndex.nprobe = opt.nprobe; + cpuIndex.metric_type = metricType; + cpuIndex.train(opt.numTrain, trainVecs.data()); - // Use the default temporary memory management to test the memory - // manager - faiss::gpu::StandardGpuResources res; + // Use the default temporary memory management to test the memory + // manager + faiss::gpu::StandardGpuResources res; - faiss::gpu::GpuIndexIVFPQConfig config; - config.device = opt.device; - config.usePrecomputedTables = opt.usePrecomputed; - config.indicesOptions = opt.indicesOpt; - config.useFloat16LookupTables = opt.useFloat16; + faiss::gpu::GpuIndexIVFPQConfig config; + config.device = opt.device; + config.usePrecomputedTables = opt.usePrecomputed; + config.indicesOptions = opt.indicesOpt; + config.useFloat16LookupTables = opt.useFloat16; + config.interleavedLayout = opt.interleavedLayout; + config.use_raft = opt.useRaft; - faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); - gpuIndex.nprobe = opt.nprobe; + faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); + gpuIndex.nprobe = opt.nprobe; - gpuIndex.add(opt.numAdd, addVecs.data()); - cpuIndex.add(opt.numAdd, addVecs.data()); + gpuIndex.add(opt.numAdd, addVecs.data()); + cpuIndex.add(opt.numAdd, addVecs.data()); - faiss::gpu::compareIndices( - cpuIndex, - gpuIndex, - opt.numQuery, - opt.dim, - opt.k, - opt.toString(), - opt.getCompareEpsilon(), - opt.getPctMaxDiff1(), - opt.getPctMaxDiffN()); + faiss::gpu::compareIndices( + cpuIndex, + gpuIndex, + opt.numQuery, + opt.dim, + opt.k, + opt.toString(), + opt.getCompareEpsilon(), + opt.getPctMaxDiff1(), + opt.getPctMaxDiffN()); +} + +TEST(TestGpuIndexIVFPQ, Add_L2) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + addTest(opt, faiss::METRIC_L2); } } TEST(TestGpuIndexIVFPQ, Add_IP) { for (int tries = 0; tries < 2; ++tries) { Options opt; - - std::vector trainVecs = - faiss::gpu::randVecs(opt.numTrain, opt.dim); - std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); - - faiss::IndexFlatIP coarseQuantizer(opt.dim); - faiss::IndexIVFPQ cpuIndex( - &coarseQuantizer, - opt.dim, - opt.numCentroids, - opt.codes, - opt.bitsPerCode); - cpuIndex.metric_type = faiss::MetricType::METRIC_INNER_PRODUCT; - cpuIndex.nprobe = opt.nprobe; - cpuIndex.train(opt.numTrain, trainVecs.data()); - - // Use the default temporary memory management to test the memory - // manager - faiss::gpu::StandardGpuResources res; - - faiss::gpu::GpuIndexIVFPQConfig config; - config.device = opt.device; - config.usePrecomputedTables = opt.usePrecomputed; - config.indicesOptions = opt.indicesOpt; - config.useFloat16LookupTables = opt.useFloat16; - - faiss::gpu::GpuIndexIVFPQ gpuIndex(&res, &cpuIndex, config); - gpuIndex.nprobe = opt.nprobe; - - gpuIndex.add(opt.numAdd, addVecs.data()); - cpuIndex.add(opt.numAdd, addVecs.data()); - - faiss::gpu::compareIndices( - cpuIndex, - gpuIndex, - opt.numQuery, - opt.dim, - opt.k, - opt.toString(), - opt.getCompareEpsilon(), - opt.getPctMaxDiff1(), - opt.getPctMaxDiffN()); + addTest(opt, faiss::METRIC_INNER_PRODUCT); } } -TEST(TestGpuIndexIVFPQ, CopyTo) { +void copyToTest(Options opt) { for (int tries = 0; tries < 2; ++tries) { - Options opt; std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); @@ -511,9 +432,11 @@ TEST(TestGpuIndexIVFPQ, CopyTo) { faiss::gpu::GpuIndexIVFPQConfig config; config.device = opt.device; - config.usePrecomputedTables = (tries % 2 == 0); + config.usePrecomputedTables = false; config.indicesOptions = opt.indicesOpt; config.useFloat16LookupTables = opt.useFloat16; + config.interleavedLayout = opt.interleavedLayout; + config.use_raft = opt.useRaft; faiss::gpu::GpuIndexIVFPQ gpuIndex( &res, @@ -561,8 +484,12 @@ TEST(TestGpuIndexIVFPQ, CopyTo) { } } -TEST(TestGpuIndexIVFPQ, CopyFrom) { +TEST(TestGpuIndexIVFPQ, CopyTo) { Options opt; + copyToTest(opt); +} + +void copyFromTest(Options opt) { std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); @@ -585,6 +512,8 @@ TEST(TestGpuIndexIVFPQ, CopyFrom) { config.usePrecomputedTables = opt.usePrecomputed; config.indicesOptions = opt.indicesOpt; config.useFloat16LookupTables = opt.useFloat16; + config.interleavedLayout = opt.interleavedLayout; + config.use_raft = opt.useRaft; // Use garbage values to see if we overwrite them faiss::gpu::GpuIndexIVFPQ gpuIndex( @@ -621,9 +550,12 @@ TEST(TestGpuIndexIVFPQ, CopyFrom) { opt.getPctMaxDiffN()); } -TEST(TestGpuIndexIVFPQ, QueryNaN) { +TEST(TestGpuIndexIVFPQ, CopyFrom) { Options opt; + copyFromTest(opt); +} +void queryNaNTest(Options opt) { std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); @@ -635,6 +567,8 @@ TEST(TestGpuIndexIVFPQ, QueryNaN) { config.usePrecomputedTables = opt.usePrecomputed; config.indicesOptions = opt.indicesOpt; config.useFloat16LookupTables = opt.useFloat16; + config.use_raft = opt.useRaft; + config.interleavedLayout = opt.useRaft ? true : opt.interleavedLayout; faiss::gpu::GpuIndexIVFPQ gpuIndex( &res, @@ -670,9 +604,13 @@ TEST(TestGpuIndexIVFPQ, QueryNaN) { } } -TEST(TestGpuIndexIVFPQ, AddNaN) { +TEST(TestGpuIndexIVFPQ, QueryNaN) { Options opt; + opt.useRaft = false; + queryNaNTest(opt); +} +void addNaNTest(Options opt) { // Use the default temporary memory management to test the memory manager faiss::gpu::StandardGpuResources res; @@ -681,6 +619,8 @@ TEST(TestGpuIndexIVFPQ, AddNaN) { config.usePrecomputedTables = opt.usePrecomputed; config.indicesOptions = opt.indicesOpt; config.useFloat16LookupTables = opt.useFloat16; + config.interleavedLayout = opt.interleavedLayout; + config.use_raft = opt.useRaft; faiss::gpu::GpuIndexIVFPQ gpuIndex( &res, @@ -722,6 +662,128 @@ TEST(TestGpuIndexIVFPQ, AddNaN) { indices.data()); } +TEST(TestGpuIndexIVFPQ, AddNaN) { + Options opt; + opt.useRaft = false; + addNaNTest(opt); +} + +#if defined USE_NVIDIA_RAFT +TEST(TestGpuIndexIVFPQ, Query_L2_Raft) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.useRaft = true; + opt.interleavedLayout = true; + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + queryTest(opt, faiss::MetricType::METRIC_L2); + } +} + +TEST(TestGpuIndexIVFPQ, Query_IP_Raft) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.useRaft = true; + opt.interleavedLayout = true; + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + queryTest(opt, faiss::MetricType::METRIC_INNER_PRODUCT); + } +} + +// Large batch sizes (>= 65536) should also work +TEST(TestGpuIndexIVFPQ, LargeBatch_Raft) { + Options opt; + + // override for large sizes + opt.dim = 4; + opt.numQuery = 100000; + opt.codes = 2; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.usePrecomputed = false; + opt.useFloat16 = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + opt.bitsPerCode = 8; + + queryTest(opt, faiss::MetricType::METRIC_L2); +} + +TEST(TestGpuIndexIVFPQ, CopyFrom_Raft) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + copyFromTest(opt); +} + +TEST(TestGpuIndexIVFPQ, Add_L2_Raft) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + addTest(opt, faiss::METRIC_L2); + } +} + +TEST(TestGpuIndexIVFPQ, Add_IP_Raft) { + for (int tries = 0; tries < 2; ++tries) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + addTest(opt, faiss::METRIC_INNER_PRODUCT); + } +} + +TEST(TestGpuIndexIVFPQ, QueryNaN_Raft) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + queryNaNTest(opt); +} + +TEST(TestGpuIndexIVFPQ, AddNaN_Raft) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + addNaNTest(opt); +} + +TEST(TestGpuIndexIVFPQ, CopyTo_Raft) { + Options opt; + opt.useRaft = true; + opt.interleavedLayout = true; + opt.bitsPerCode = faiss::gpu::randVal(4, 8); + opt.usePrecomputed = false; + opt.indicesOpt = faiss::gpu::INDICES_64_BIT; + pickRaftEncoding(opt.codes, opt.dim, opt.bitsPerCode); + copyToTest(opt); +} +#endif + TEST(TestGpuIndexIVFPQ, UnifiedMemory) { // Construct on a random device to test multi-device, if we have // multiple devices @@ -762,6 +824,7 @@ TEST(TestGpuIndexIVFPQ, UnifiedMemory) { faiss::gpu::GpuIndexIVFPQConfig config; config.device = device; config.memorySpace = faiss::gpu::MemorySpace::Unified; + config.use_raft = false; faiss::gpu::GpuIndexIVFPQ gpuIndex( &res, @@ -784,6 +847,34 @@ TEST(TestGpuIndexIVFPQ, UnifiedMemory) { 0.015f, 0.1f, 0.015f); + +#if defined USE_NVIDIA_RAFT + config.interleavedLayout = true; + config.use_raft = true; + config.indicesOptions = faiss::gpu::INDICES_64_BIT; + + faiss::gpu::GpuIndexIVFPQ raftGpuIndex( + &res, + dim, + numCentroids, + codes, + bitsPerCode, + faiss::METRIC_L2, + config); + raftGpuIndex.copyFrom(&cpuIndex); + raftGpuIndex.nprobe = nprobe; + + faiss::gpu::compareIndices( + cpuIndex, + raftGpuIndex, + numQuery, + dim, + k, + "Unified Memory", + 0.015f, + 0.1f, + 0.015f); +#endif } int main(int argc, char** argv) { diff --git a/faiss/gpu/test/TestGpuMemoryException.cpp b/faiss/gpu/test/TestGpuMemoryException.cpp index c6f6e9bdeb..ff4be0893e 100644 --- a/faiss/gpu/test/TestGpuMemoryException.cpp +++ b/faiss/gpu/test/TestGpuMemoryException.cpp @@ -31,6 +31,7 @@ TEST(TestGpuMemoryException, AddException) { faiss::gpu::GpuIndexFlatConfig config; config.device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1); + config.use_raft = false; faiss::gpu::GpuIndexFlatL2 gpuIndexL2Broken( &res, (int)brokenAddDims, config); diff --git a/faiss/gpu/test/test_gpu_index.py b/faiss/gpu/test/test_gpu_index.py index 36a1f8a64b..620bfea198 100755 --- a/faiss/gpu/test/test_gpu_index.py +++ b/faiss/gpu/test/test_gpu_index.py @@ -24,7 +24,9 @@ def test_ivfflat_search_preassigned(self): nprobe = 10 k = 50 - idx_gpu = faiss.GpuIndexIVFFlat(res, d, nlist) + config = faiss.GpuIndexIVFFlatConfig() + config.use_raft = False + idx_gpu = faiss.GpuIndexIVFFlat(res, d, nlist, faiss.METRIC_L2, config) idx_gpu.nprobe = nprobe rs = np.random.RandomState(567) @@ -56,7 +58,9 @@ def test_ivfpq_search_preassigned(self): nprobe = 5 k = 50 - idx_gpu = faiss.GpuIndexIVFPQ(res, d, nlist, 4, 8) + config = faiss.GpuIndexIVFPQConfig() + config.use_raft = False + idx_gpu = faiss.GpuIndexIVFPQ(res, d, nlist, 4, 8, faiss.METRIC_L2, config) idx_gpu.nprobe = nprobe rs = np.random.RandomState(567) @@ -136,7 +140,9 @@ def test_ivfflat_cpu_coarse(self): # construct a GPU index using the same trained coarse quantizer # from the CPU index - idx_gpu = faiss.GpuIndexIVFFlat(res, q, d, nlist, faiss.METRIC_L2) + config = faiss.GpuIndexIVFFlatConfig() + config.use_raft = False + idx_gpu = faiss.GpuIndexIVFFlat(res, q, d, nlist, faiss.METRIC_L2, config) assert(idx_gpu.is_trained) idx_gpu.add(xb) @@ -150,7 +156,7 @@ def test_ivfflat_cpu_coarse(self): self.assertGreaterEqual((i_g == i_c).sum(), i_g.size * 0.9) self.assertTrue(np.allclose(d_g, d_c, rtol=5e-5, atol=5e-5)) - def test_ivfsq_cpu_coarse(self): + def test_ivfsq_pu_coarse(self): res = faiss.StandardGpuResources() d = 128 nb = 5000 @@ -226,8 +232,10 @@ def test_ivfpq_cpu_coarse(self): # construct a GPU index using the same trained coarse quantizer # from the CPU index + config = faiss.GpuIndexIVFPQConfig() + config.use_raft = False idx_gpu = faiss.GpuIndexIVFPQ( - res, idx_coarse_cpu, d, nlist_lvl_2, 4, 8) + res, idx_coarse_cpu, d, nlist_lvl_2, 4, 8, faiss.METRIC_L2, config) assert(not idx_gpu.is_trained) idx_gpu.train(xb) @@ -406,6 +414,7 @@ def test_indices_ivfflat(self): # Store values using 32-bit indices instead config.indicesOptions = faiss.INDICES_32_BIT + config.use_raft = False idx = faiss.GpuIndexIVFFlat(res, d, nlist, faiss.METRIC_L2, config) idx.train(xb) idx.add_with_ids(xb, xb_indices) @@ -430,6 +439,7 @@ def test_indices_ivfpq(self): xb_indices = (xb_indices_base + 4294967296).astype('int64') config = faiss.GpuIndexIVFPQConfig() + config.use_raft = False idx = faiss.GpuIndexIVFPQ(res, d, nlist, M, nbits, faiss.METRIC_L2, config) idx.train(xb) @@ -490,7 +500,9 @@ def test_sq_cpu_to_gpu(self): res = faiss.StandardGpuResources() index = faiss.index_factory(32, "SQfp16") index.add(np.random.rand(1000, 32).astype(np.float32)) - gpu_index = faiss.index_cpu_to_gpu(res, 0, index) + config = faiss.GpuClonerOptions() + config.use_raft = False + gpu_index = faiss.index_cpu_to_gpu(res, 0, index, config) self.assertIsInstance(gpu_index, faiss.GpuIndexFlat) diff --git a/faiss/gpu/test/test_gpu_index_ivfsq.py b/faiss/gpu/test/test_gpu_index_ivfsq.py index af56316509..09dcdae079 100755 --- a/faiss/gpu/test/test_gpu_index_ivfsq.py +++ b/faiss/gpu/test/test_gpu_index_ivfsq.py @@ -27,7 +27,9 @@ def make_indices_copy_from_cpu(nlist, d, qtype, by_residual, metric, clamp): res = faiss.StandardGpuResources() res.noTempMemory() - idx_gpu = faiss.GpuIndexIVFScalarQuantizer(res, idx_cpu) + config = faiss.GpuIndexIVFScalarQuantizerConfig() + config.use_raft = False + idx_gpu = faiss.GpuIndexIVFScalarQuantizer(res, idx_cpu, config) return idx_cpu, idx_gpu @@ -37,8 +39,10 @@ def make_indices_copy_from_gpu(nlist, d, qtype, by_residual, metric, clamp): res = faiss.StandardGpuResources() res.noTempMemory() + config = faiss.GpuIndexIVFScalarQuantizerConfig() + config.use_raft = False idx_gpu = faiss.GpuIndexIVFScalarQuantizer(res, d, nlist, - qtype, metric, by_residual) + qtype, metric, by_residual, config) idx_gpu.train(to_train) idx_gpu.add(to_train) @@ -63,8 +67,10 @@ def make_indices_train(nlist, d, qtype, by_residual, metric, clamp): res = faiss.StandardGpuResources() res.noTempMemory() + config = faiss.GpuIndexIVFScalarQuantizerConfig() + config.use_raft = False idx_gpu = faiss.GpuIndexIVFScalarQuantizer(res, d, nlist, - qtype, metric, by_residual) + qtype, metric, by_residual, config) assert(by_residual == idx_gpu.by_residual) idx_gpu.train(to_train) diff --git a/faiss/gpu/test/test_gpu_index_serialize.py b/faiss/gpu/test/test_gpu_index_serialize.py index 82cbe577c8..49e51af8b4 100644 --- a/faiss/gpu/test/test_gpu_index_serialize.py +++ b/faiss/gpu/test/test_gpu_index_serialize.py @@ -34,7 +34,9 @@ def test_serialize(self): indexes.append(faiss.GpuIndexIVFFlat(res, d, nlist, faiss.METRIC_L2)) # IVFSQ - indexes.append(faiss.GpuIndexIVFScalarQuantizer(res, d, nlist, faiss.ScalarQuantizer.QT_fp16)) + config = faiss.GpuIndexIVFScalarQuantizerConfig() + config.use_raft = False + indexes.append(faiss.GpuIndexIVFScalarQuantizer(res, d, nlist, faiss.ScalarQuantizer.QT_fp16, faiss.METRIC_L2, True, config)) # IVFPQ indexes.append(faiss.GpuIndexIVFPQ(res, d, nlist, 4, 8, faiss.METRIC_L2)) @@ -47,8 +49,11 @@ def test_serialize(self): ser = faiss.serialize_index(faiss.index_gpu_to_cpu(index)) cpu_index = faiss.deserialize_index(ser) - - gpu_index_restore = faiss.index_cpu_to_gpu(res, 0, cpu_index) + + gpu_cloner_options = faiss.GpuClonerOptions() + if isinstance(index, faiss.GpuIndexIVFScalarQuantizer): + gpu_cloner_options.use_raft = False + gpu_index_restore = faiss.index_cpu_to_gpu(res, 0, cpu_index, gpu_cloner_options) restore_d, restore_i = gpu_index_restore.search(query, k) diff --git a/faiss/gpu/test/test_multi_gpu.py b/faiss/gpu/test/test_multi_gpu.py index 4a63025969..e341f5715a 100644 --- a/faiss/gpu/test/test_multi_gpu.py +++ b/faiss/gpu/test/test_multi_gpu.py @@ -29,6 +29,7 @@ def test_sharded(self): co = faiss.GpuMultipleClonerOptions() co.shard = True + co.use_raft = False index = faiss.index_cpu_to_all_gpus(index_cpu, co, ngpu=2) index.add(xb) @@ -71,6 +72,7 @@ def do_test_sharded_ivf(self, index_key): co = faiss.GpuMultipleClonerOptions() co.shard = True co.common_ivf_quantizer = True + co.use_raft = False index = faiss.index_cpu_to_all_gpus(index, co, ngpu=2) index.quantizer # make sure there is indeed a quantizer @@ -111,6 +113,7 @@ def test_binary_clone(self, ngpu=1, shard=False): co = faiss.GpuMultipleClonerOptions() co.shard = shard + co.use_raft = False # index2 = faiss.index_cpu_to_all_gpus(index, ngpu=ngpu) res = faiss.StandardGpuResources() @@ -188,7 +191,9 @@ def do_cpu_to_gpu(self, index_key): ts.append(time.time()) res = faiss.StandardGpuResources() - gpu_index = faiss.index_cpu_to_gpu(res, 0, index) + co = faiss.GpuClonerOptions() + co.use_raft = False + gpu_index = faiss.index_cpu_to_gpu(res, 0, index, co) ts.append(time.time()) # Validate the layout of the memory info @@ -217,6 +222,7 @@ def do_cpu_to_gpu(self, index_key): res = [faiss.StandardGpuResources() for i in range(2)] co = faiss.GpuMultipleClonerOptions() co.shard = shard + co.use_raft = False gpu_index = faiss.index_cpu_to_gpu_multiple_py(res, index, co) diff --git a/faiss/gpu/utils/CopyUtils.cuh b/faiss/gpu/utils/CopyUtils.cuh index 637a46cbee..8ff600a049 100644 --- a/faiss/gpu/utils/CopyUtils.cuh +++ b/faiss/gpu/utils/CopyUtils.cuh @@ -119,6 +119,7 @@ inline void fromDevice(T* src, T* dst, size_t num, cudaStream_t stream) { if (dev == -1) { CUDA_VERIFY(cudaMemcpyAsync( dst, src, num * sizeof(T), cudaMemcpyDeviceToHost, stream)); + cudaStreamSynchronize(stream); } else { CUDA_VERIFY(cudaMemcpyAsync( dst, src, num * sizeof(T), cudaMemcpyDeviceToDevice, stream)); diff --git a/faiss/gpu/utils/RaftUtils.cu b/faiss/gpu/utils/RaftUtils.cu new file mode 100644 index 0000000000..ba40c54c26 --- /dev/null +++ b/faiss/gpu/utils/RaftUtils.cu @@ -0,0 +1,117 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace faiss { +namespace gpu { + +void validRowIndices( + GpuResources* res, + Tensor& vecs, + bool* validRows) { + idx_t n_rows = vecs.getSize(0); + idx_t dim = vecs.getSize(1); + + raft::linalg::coalescedReduction( + validRows, + vecs.data(), + dim, + n_rows, + true, + res->getDefaultStreamCurrentDevice(), + false, + [] __device__(float v, idx_t i) { return isfinite(v); }, + raft::mul_op()); +} + +idx_t inplaceGatherFilteredRows( + GpuResources* res, + Tensor& vecs, + Tensor& indices) { + raft::device_resources& raft_handle = res->getRaftHandleCurrentDevice(); + idx_t n_rows = vecs.getSize(0); + idx_t dim = vecs.getSize(1); + + auto valid_rows = + raft::make_device_vector(raft_handle, n_rows); + + validRowIndices(res, vecs, valid_rows.data_handle()); + + idx_t n_rows_valid = thrust::reduce( + raft_handle.get_thrust_policy(), + valid_rows.data_handle(), + valid_rows.data_handle() + n_rows, + 0); + + if (n_rows_valid < n_rows) { + auto gather_indices = raft::make_device_vector( + raft_handle, n_rows_valid); + + auto count = thrust::make_counting_iterator(0); + + thrust::copy_if( + raft_handle.get_thrust_policy(), + count, + count + n_rows, + gather_indices.data_handle(), + [valid_rows = valid_rows.data_handle()] __device__(auto i) { + return valid_rows[i]; + }); + + raft::matrix::gather( + raft_handle, + raft::make_device_matrix_view( + vecs.data(), n_rows, dim), + raft::make_const_mdspan(gather_indices.view()), + (idx_t)16); + + auto validIndices = raft::make_device_vector( + raft_handle, n_rows_valid); + + thrust::gather( + raft_handle.get_thrust_policy(), + gather_indices.data_handle(), + gather_indices.data_handle() + gather_indices.size(), + indices.data(), + validIndices.data_handle()); + thrust::copy( + raft_handle.get_thrust_policy(), + validIndices.data_handle(), + validIndices.data_handle() + n_rows_valid, + indices.data()); + } + return n_rows_valid; +} + +} // namespace gpu +} // namespace faiss diff --git a/faiss/gpu/impl/RaftUtils.h b/faiss/gpu/utils/RaftUtils.h similarity index 73% rename from faiss/gpu/impl/RaftUtils.h rename to faiss/gpu/utils/RaftUtils.h index f1ea19ed33..4dfafa4ec5 100644 --- a/faiss/gpu/impl/RaftUtils.h +++ b/faiss/gpu/utils/RaftUtils.h @@ -23,13 +23,16 @@ #pragma once #include -#include +#include +#include + #include +#pragma GCC visibility push(default) namespace faiss { namespace gpu { -inline raft::distance::DistanceType faiss_to_raft( +inline raft::distance::DistanceType metricFaissToRaft( MetricType metric, bool exactDistance) { switch (metric) { @@ -53,5 +56,20 @@ inline raft::distance::DistanceType faiss_to_raft( RAFT_FAIL("Distance type not supported"); } } + +/// Identify matrix rows containing non NaN values. validRows[i] is false if row +/// i contains a NaN value and true otherwise. +void validRowIndices( + GpuResources* res, + Tensor& vecs, + bool* validRows); + +/// Filter out matrix rows containing NaN values. The vectors and indices are +/// updated in-place. +idx_t inplaceGatherFilteredRows( + GpuResources* res, + Tensor& vecs, + Tensor& indices); } // namespace gpu } // namespace faiss +#pragma GCC visibility pop diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8522fa613d..10243b9a9c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -70,6 +70,7 @@ find_package(OpenMP REQUIRED) target_link_libraries(faiss_test PRIVATE OpenMP::OpenMP_CXX gtest_main + $<$:raft::raft> ) # Defines `gtest_discover_tests()`. From b8d91d8cf864220e6d757948fb09c2ea0e22fb66 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Wed, 21 Feb 2024 06:41:08 -0800 Subject: [PATCH 089/206] fixes for D51074065 Summary: to get past CI Reviewed By: junjieqi Differential Revision: D53956063 fbshipit-source-id: 260fdabff2aada511d775f54270974f1b629e9eb --- faiss/gpu/impl/RaftIVFPQ.cu | 2 +- faiss/gpu/test/TestGpuIndexFlat.cpp | 2 +- faiss/gpu/test/TestGpuIndexIVFFlat.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/faiss/gpu/impl/RaftIVFPQ.cu b/faiss/gpu/impl/RaftIVFPQ.cu index b26025dd47..3a2a0a4218 100644 --- a/faiss/gpu/impl/RaftIVFPQ.cu +++ b/faiss/gpu/impl/RaftIVFPQ.cu @@ -543,4 +543,4 @@ void RaftIVFPQ::setBasePQCentroids_() { } } // namespace gpu -} // namespace faiss \ No newline at end of file +} // namespace faiss diff --git a/faiss/gpu/test/TestGpuIndexFlat.cpp b/faiss/gpu/test/TestGpuIndexFlat.cpp index d7a7b45ec0..06b860ded4 100644 --- a/faiss/gpu/test/TestGpuIndexFlat.cpp +++ b/faiss/gpu/test/TestGpuIndexFlat.cpp @@ -767,4 +767,4 @@ int main(int argc, char** argv) { faiss::gpu::setTestSeed(100); return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp index a90825bffb..6e423e582e 100644 --- a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +++ b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp @@ -849,4 +849,4 @@ int main(int argc, char** argv) { faiss::gpu::setTestSeed(100); return RUN_ALL_TESTS(); -} \ No newline at end of file +} From abff75ef078aa7b2258c5ea965f2353691c71b42 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Wed, 21 Feb 2024 11:38:57 -0800 Subject: [PATCH 090/206] faiss gpu: fix DeviceVector reallocations (#3256) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3256 Per https://github.com/facebookresearch/faiss/issues/3251 there are two problems with DeviceVector resizing and capacity growth. The first is that if you resize a vector with enough capacity available for the new size, it will go ahead and re-allocate memory anyways. The second is that the calculation that was supposed to produce x + 0.25 * x was actually producing x + 4 * x for determining the new size of the allocated memory for a vector. This is also fixed. Reviewed By: mdouze Differential Revision: D53813207 fbshipit-source-id: 5aa67bc0a87c171a070645bdcc6bc5d22ba6b36b --- faiss/gpu/utils/DeviceVector.cuh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faiss/gpu/utils/DeviceVector.cuh b/faiss/gpu/utils/DeviceVector.cuh index fff5a79086..0517d06c32 100644 --- a/faiss/gpu/utils/DeviceVector.cuh +++ b/faiss/gpu/utils/DeviceVector.cuh @@ -132,7 +132,7 @@ class DeviceVector { bool resize(size_t newSize, cudaStream_t stream) { bool mem = false; - if (num_ < newSize) { + if (newSize > capacity_) { mem = reserve(getNewCapacity_(newSize), stream); } @@ -249,7 +249,7 @@ class DeviceVector { if (preferredSize <= kDeviceVector_2x_Limit) { return utils::nextHighestPowerOf2(preferredSize); } else if (preferredSize <= kDeviceVector_1_25x_Limit) { - return preferredSize + (preferredSize << 2); + return preferredSize + (preferredSize >> 2); } else { return preferredSize; } From 943d08bdad7946b22f56d040756669ee444dd681 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Thu, 29 Feb 2024 13:24:50 -0800 Subject: [PATCH 091/206] Prepare for v.1.8.0 release (#3265) Summary: Prepare for v1.8.0 release Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3265 Reviewed By: mdouze Differential Revision: D54232846 Pulled By: junjieqi fbshipit-source-id: f92efc93e340507262321c5033bab7fede7d7f40 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++-- CMakeLists.txt | 2 +- faiss/Index.h | 4 ++-- faiss/python/setup.py | 2 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae418b09b4..e61bd997ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,34 @@ We try to indicate most contributions here with the contributor names who are no the Facebook Faiss team. Feel free to add entries here if you submit a PR. ## [Unreleased] -- Support for range search in HNSW and Fast scan IVF. + +## [1.8.0] - 2024-02-27 +### Added +- Added a new conda package faiss-gpu-raft alongside faiss-cpu and faiss-gpu +- Integrated IVF-Flat and IVF-PQ implementations in faiss-gpu-raft from RAFT by Nvidia [thanks Corey Nolet and Tarang Jain] +- Added a context parameter to InvertedLists and InvertedListsIterator +- Added Faiss on Rocksdb demo to showing how inverted lists can be persisted in a key-value store +- Introduced Offline IVF framework powered by Faiss big batch search +- Added SIMD NEON Optimization for QT_FP16 in Scalar Quantizer. [thanks Naveen Tatikonda] +- Generalized ResultHandler and supported range search for HNSW and FastScan +- Introduced avx512 optimization mode and FAISS_OPT_LEVEL env variable [thanks Alexandr Ghuzva] +- Added search parameters for IndexRefine::search() and IndexRefineFlat::search() +- Supported large two-level clustering +- Added support for Python 3.11 and 3.12 +- Added support for CUDA 12 + +### Changed +- Used the benchmark to find Pareto optimal indices. Intentionally limited to IVF(Flat|HNSW),PQ|SQ indices +- Splitted off RQ encoding steps to another file +- Supported better NaN handling +- HNSW speedup + Distance 4 points [thanks Alexandr Ghuzva] + +### Fixed +- Fixed DeviceVector reallocations in Faiss GPU +- Used efSearch from params if provided in HNSW search +- Fixed warp synchronous behavior in Faiss GPU CUDA 12 + + ## [1.7.4] - 2023-04-12 ### Added - Added big batch IVF search for conducting efficient search with big batches of queries @@ -259,7 +286,8 @@ by conda install -c pytorch faiss-gpu cudatoolkit=10.0. - C bindings. - Extended tutorial to GPU indices. -[Unreleased]: https://github.com/facebookresearch/faiss/compare/v1.7.4...HEAD +[Unreleased]: https://github.com/facebookresearch/faiss/compare/v1.8.0...HEAD +[1.8.0]: https://github.com/facebookresearch/faiss/compare/v1.7.4...v1.8.0 [1.7.4]: https://github.com/facebookresearch/faiss/compare/v1.7.3...v1.7.4 [1.7.3]: https://github.com/facebookresearch/faiss/compare/v1.7.2...v1.7.3 [1.7.2]: https://github.com/facebookresearch/faiss/compare/v1.7.1...v1.7.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 445b39d59e..6cdc37c46f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ rapids_cuda_init_architectures(faiss_c_library) endif() project(faiss - VERSION 1.7.4 + VERSION 1.8.0 DESCRIPTION "A library for efficient similarity search and clustering of dense vectors." HOMEPAGE_URL "https://github.com/facebookresearch/faiss" LANGUAGES ${FAISS_LANGUAGES}) diff --git a/faiss/Index.h b/faiss/Index.h index 4b4b302b47..3d1bdb996a 100644 --- a/faiss/Index.h +++ b/faiss/Index.h @@ -17,8 +17,8 @@ #include #define FAISS_VERSION_MAJOR 1 -#define FAISS_VERSION_MINOR 7 -#define FAISS_VERSION_PATCH 4 +#define FAISS_VERSION_MINOR 8 +#define FAISS_VERSION_PATCH 0 /** * @namespace faiss diff --git a/faiss/python/setup.py b/faiss/python/setup.py index 3b4f2e9c83..939aeeffbe 100644 --- a/faiss/python/setup.py +++ b/faiss/python/setup.py @@ -60,7 +60,7 @@ """ setup( name='faiss', - version='1.7.4', + version='1.8.0', description='A library for efficient similarity search and clustering of dense vectors', long_description=long_description, url='https://github.com/facebookresearch/faiss', From 12b92e9fa5d8e8fb3da53c57af9ff007c826b1ee Mon Sep 17 00:00:00 2001 From: John Mazanec Date: Fri, 1 Mar 2024 04:27:49 -0800 Subject: [PATCH 092/206] Skip HNSWPQ sdc init with new io flag (#3250) Summary: ## Description Related issue: https://github.com/facebookresearch/faiss/issues/3246 When reading HNSWPQ from disk, if index ~read only~ new `IO_FLAG_PQ_SKIP_SDC_TABLE` flag is set, skip initializing the sdc_table. In addition, adds cpp test case verifying functionality and build test util header file to share creation of temporary files amongst tests. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3250 Test Plan: buck test //faiss/tests/:test_disable_pq_sdc_tables Reviewed By: junjieqi Differential Revision: D53844075 Pulled By: mdouze fbshipit-source-id: e9a83c0e5243867edbca8f80e3b1242b38ef6a42 --- faiss/impl/index_read.cpp | 2 +- faiss/index_io.h | 6 +++ tests/CMakeLists.txt | 1 + tests/test_disable_pq_sdc_tables.cpp | 61 ++++++++++++++++++++++++++++ tests/test_merge.cpp | 35 +++------------- tests/test_util.h | 39 ++++++++++++++++++ 6 files changed, 113 insertions(+), 31 deletions(-) create mode 100644 tests/test_disable_pq_sdc_tables.cpp create mode 100644 tests/test_util.h diff --git a/faiss/impl/index_read.cpp b/faiss/impl/index_read.cpp index ac62e0269e..8d80329bf9 100644 --- a/faiss/impl/index_read.cpp +++ b/faiss/impl/index_read.cpp @@ -962,7 +962,7 @@ Index* read_index(IOReader* f, int io_flags) { read_HNSW(&idxhnsw->hnsw, f); idxhnsw->storage = read_index(f, io_flags); idxhnsw->own_fields = true; - if (h == fourcc("IHNp")) { + if (h == fourcc("IHNp") && !(io_flags & IO_FLAG_PQ_SKIP_SDC_TABLE)) { dynamic_cast(idxhnsw->storage)->pq.compute_sdc_table(); } idx = idxhnsw; diff --git a/faiss/index_io.h b/faiss/index_io.h index 8d52ee1afd..f73cd073b7 100644 --- a/faiss/index_io.h +++ b/faiss/index_io.h @@ -52,6 +52,12 @@ const int IO_FLAG_ONDISK_SAME_DIR = 4; const int IO_FLAG_SKIP_IVF_DATA = 8; // don't initialize precomputed table after loading const int IO_FLAG_SKIP_PRECOMPUTE_TABLE = 16; +// don't compute the sdc table for PQ-based indices +// this will prevent distances from being computed +// between elements in the index. For indices like HNSWPQ, +// this will prevent graph building because sdc +// computations are required to construct the graph +const int IO_FLAG_PQ_SKIP_SDC_TABLE = 32; // try to memmap data (useful to load an ArrayInvertedLists as an // OnDiskInvertedLists) const int IO_FLAG_MMAP = IO_FLAG_SKIP_IVF_DATA | 0x646f0000; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 10243b9a9c..9017edc586 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,6 +32,7 @@ set(FAISS_TEST_SRC test_hnsw.cpp test_partitioning.cpp test_fastscan_perf.cpp + test_disable_pq_sdc_tables.cpp ) add_executable(faiss_test ${FAISS_TEST_SRC}) diff --git a/tests/test_disable_pq_sdc_tables.cpp b/tests/test_disable_pq_sdc_tables.cpp new file mode 100644 index 0000000000..b211a5c451 --- /dev/null +++ b/tests/test_disable_pq_sdc_tables.cpp @@ -0,0 +1,61 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include + +#include "faiss/Index.h" +#include "faiss/IndexHNSW.h" +#include "faiss/index_factory.h" +#include "faiss/index_io.h" +#include "test_util.h" + +pthread_mutex_t temp_file_mutex = PTHREAD_MUTEX_INITIALIZER; + +TEST(IO, TestReadHNSWPQ_whenSDCDisabledFlagPassed_thenDisableSDCTable) { + Tempfilename index_filename(&temp_file_mutex, "/tmp/faiss_TestReadHNSWPQ"); + int d = 32, n = 256; + std::default_random_engine rng(123); + std::uniform_real_distribution u(0, 100); + std::vector vectors(n * d); + for (size_t i = 0; i < n * d; i++) { + vectors[i] = u(rng); + } + + // Build the index and write it to the temp file + { + std::unique_ptr index_writer( + faiss::index_factory(d, "HNSW8,PQ4np", faiss::METRIC_L2)); + index_writer->train(n, vectors.data()); + index_writer->add(n, vectors.data()); + + faiss::write_index(index_writer.get(), index_filename.c_str()); + } + + // Load index from disk. Confirm that the sdc table is equal to 0 when + // disable sdc is set + { + std::unique_ptr index_reader_read_write( + dynamic_cast( + faiss::read_index(index_filename.c_str()))); + std::unique_ptr index_reader_sdc_disabled( + dynamic_cast(faiss::read_index( + index_filename.c_str(), + faiss::IO_FLAG_PQ_SKIP_SDC_TABLE))); + + ASSERT_NE( + dynamic_cast(index_reader_read_write->storage) + ->pq.sdc_table.size(), + 0); + ASSERT_EQ( + dynamic_cast( + index_reader_sdc_disabled->storage) + ->pq.sdc_table.size(), + 0); + } +} diff --git a/tests/test_merge.cpp b/tests/test_merge.cpp index 7e23f15f72..5a1d08cfba 100644 --- a/tests/test_merge.cpp +++ b/tests/test_merge.cpp @@ -6,47 +6,22 @@ */ #include -#include #include -#include - #include #include #include #include -#include #include #include #include -namespace { - -struct Tempfilename { - static pthread_mutex_t mutex; - - std::string filename = "/tmp/faiss_tmp_XXXXXX"; - - Tempfilename() { - pthread_mutex_lock(&mutex); - int fd = mkstemp(&filename[0]); - close(fd); - pthread_mutex_unlock(&mutex); - } - - ~Tempfilename() { - if (access(filename.c_str(), F_OK)) { - unlink(filename.c_str()); - } - } +#include "test_util.h" - const char* c_str() { - return filename.c_str(); - } -}; +namespace { -pthread_mutex_t Tempfilename::mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t temp_file_mutex = PTHREAD_MUTEX_INITIALIZER; typedef faiss::idx_t idx_t; @@ -95,7 +70,7 @@ int compare_merged( std::vector refD(k * nq); index_shards->search(nq, cd.queries.data(), k, refD.data(), refI.data()); - Tempfilename filename; + Tempfilename filename(&temp_file_mutex, "/tmp/faiss_tmp_XXXXXX"); std::vector newI(k * nq); std::vector newD(k * nq); @@ -212,7 +187,7 @@ TEST(MERGE, merge_flat_vt) { TEST(MERGE, merge_flat_ondisk) { faiss::IndexShards index_shards(d, false, false); index_shards.own_indices = true; - Tempfilename filename; + Tempfilename filename(&temp_file_mutex, "/tmp/faiss_tmp_XXXXXX"); for (int i = 0; i < nindex; i++) { auto ivf = new faiss::IndexIVFFlat(&cd.quantizer, d, nlist); diff --git a/tests/test_util.h b/tests/test_util.h new file mode 100644 index 0000000000..3be0e35cff --- /dev/null +++ b/tests/test_util.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#ifndef FAISS_TEST_UTIL_H +#define FAISS_TEST_UTIL_H + +#include +#include +#include + +struct Tempfilename { + pthread_mutex_t* mutex; + std::string filename; + + Tempfilename(pthread_mutex_t* mutex, std::string filename) { + this->mutex = mutex; + this->filename = filename; + pthread_mutex_lock(mutex); + int fd = mkstemp(&filename[0]); + close(fd); + pthread_mutex_unlock(mutex); + } + + ~Tempfilename() { + if (access(filename.c_str(), F_OK)) { + unlink(filename.c_str()); + } + } + + const char* c_str() { + return filename.c_str(); + } +}; + +#endif // FAISS_TEST_UTIL_H From dafdff110489db7587b169a0afee8470f220d295 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Mon, 4 Mar 2024 03:07:49 -0800 Subject: [PATCH 093/206] Change intall.md to reflect faiss 1.8.0 Summary: Same as title Reviewed By: algoriddle Differential Revision: D54399993 fbshipit-source-id: a0b05aabc2a0b70ae64843ca2ef2f4faaa123cdd --- INSTALL.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index ee08d8d2cf..45e2c9341b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -4,44 +4,47 @@ The supported way to install Faiss is through [conda](https://docs.conda.io). Stable releases are pushed regularly to the pytorch conda channel, as well as pre-release nightly builds. -The CPU-only `faiss-cpu` conda package is currently available on Linux, OSX, and -Windows. The `faiss-gpu`, containing both CPU and GPU indices, is available on -Linux systems, for CUDA 11.4. Packages are built for Python versions 3.8-3.10. +- The CPU-only faiss-cpu conda package is currently available on Linux (x86_64 and arm64), OSX (arm64 only), and Windows (x86_64) +- faiss-gpu, containing both CPU and GPU indices, is available on Linux (x86_64 only) for CUDA 11.4 and 12.1 +- NEW: faiss-gpu-raft containing both CPU and GPU indices provided by NVIDIA RAFT, is available on Linux (x86_64 only) for CUDA 11.8 and 12.1. To install the latest stable release: ``` shell # CPU-only version -$ conda install -c pytorch faiss-cpu=1.7.4 mkl=2021 blas=1.0=mkl +$ conda install -c pytorch faiss-cpu=1.8.0 # GPU(+CPU) version -$ conda install -c pytorch -c nvidia faiss-gpu=1.7.4 mkl=2021 blas=1.0=mkl +$ conda install -c pytorch -c nvidia faiss-gpu=1.8.0 + +# GPU(+CPU) version with NVIDIA RAFT +$ conda install -c pytorch -c nvidia -c rapidsai -c conda-forge faiss-gpu-raft=1.8.0 ``` -For faiss-gpu, the nvidia channel is required for cudatoolkit=11.4, which is not +For faiss-gpu, the nvidia channel is required for CUDA, which is not published in the main anaconda channel. -NOTE: due to a bug in the latest 1.7.4 release, Intel MKL 2021 needs to be installed -separately where applicable. Remove the MKL reference when installing on -non-Intel platforms. +For faiss-gpu-raft, the nvidia, rapidsai and conda-forge channels are required. -Nightly pre-release packages can be installed as follows. There is no need to -install MKL separately, the correct package is automatically installed as a -dependency where necessary: +Nightly pre-release packages can be installed as follows: ``` shell # CPU-only version $ conda install -c pytorch/label/nightly faiss-cpu # GPU(+CPU) version -$ conda install -c pytorch/label/nightly -c nvidia faiss-gpu=1.7.4 +$ conda install -c pytorch/label/nightly -c nvidia faiss-gpu=1.8.0 + +# GPU(+CPU) version with NVIDIA RAFT +conda install -c pytorch -c nvidia -c rapidsai -c conda-forge faiss-gpu-raft=1.8.0 pytorch pytorch-cuda numpy ``` +In the above commands, pytorch-cuda=11 or pytorch-cuda=12 would select a specific CUDA version, if it’s required. -A combination of versions that installs GPU Faiss with CUDA 11.4 and Pytorch (as of 2023-06-19): +A combination of versions that installs GPU Faiss with CUDA and Pytorch (as of 2024-03-01): ``` -conda create --name faiss_1.7.4 python=3.10 -conda activate faiss_1.7.4 -conda install faiss-gpu=1.7.4 mkl=2021 pytorch pytorch-cuda numpy -c pytorch -c nvidia +conda create --name faiss_1.8.0 +conda activate faiss_1.8.0 +conda install -c pytorch -c nvidia faiss-gpu=1.8.0 pytorch pytorch-cuda numpy ``` ## Installing from conda-forge From e99ad124cbc40c03f72a37032ec25fcabf1479cf Mon Sep 17 00:00:00 2001 From: ranjitsastra Date: Fri, 15 Mar 2024 05:19:05 -0700 Subject: [PATCH 094/206] AIX compilation fix for io classes (#3275) Summary: in AIX OS ,as fileno is defined as C macro, we get the compilation error during preprocessing step. In file included from /ranjit/Faiss/faiss/faiss/invlists/InvertedListsIOHook.h:10: /ranjit/Faiss/faiss/faiss/impl/io.h:35:17: error: expected member name or ';' after declaration specifiers 35 | virtual int fileno(); | ~~~~~~~~~~~ ^ /usr/include/stdio.h:517:30: note: expanded from macro 'fileno' 517 | #define fileno(__p) ((__p)->_file) Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3275 Reviewed By: algoriddle Differential Revision: D54944388 Pulled By: mdouze fbshipit-source-id: 40c4314de93547778ac274281245ff59e3a18b6d --- faiss/impl/io.cpp | 16 ++++++++++++---- faiss/impl/io.h | 8 ++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/faiss/impl/io.cpp b/faiss/impl/io.cpp index 5d24e58591..3d3af95036 100644 --- a/faiss/impl/io.cpp +++ b/faiss/impl/io.cpp @@ -20,11 +20,11 @@ namespace faiss { * IO functions ***********************************************************************/ -int IOReader::fileno() { +int IOReader::filedescriptor() { FAISS_THROW_MSG("IOReader does not support memory mapping"); } -int IOWriter::fileno() { +int IOWriter::filedescriptor() { FAISS_THROW_MSG("IOWriter does not support memory mapping"); } @@ -85,8 +85,12 @@ size_t FileIOReader::operator()(void* ptr, size_t size, size_t nitems) { return fread(ptr, size, nitems, f); } -int FileIOReader::fileno() { +int FileIOReader::filedescriptor() { +#ifdef _AIX + return fileno(f); +#else return ::fileno(f); +#endif } FileIOWriter::FileIOWriter(FILE* wf) : f(wf) {} @@ -116,8 +120,12 @@ size_t FileIOWriter::operator()(const void* ptr, size_t size, size_t nitems) { return fwrite(ptr, size, nitems, f); } -int FileIOWriter::fileno() { +int FileIOWriter::filedescriptor() { +#ifdef _AIX + return fileno(f); +#else return ::fileno(f); +#endif } /*********************************************************************** diff --git a/faiss/impl/io.h b/faiss/impl/io.h index 8d0605a5a6..59c2e31539 100644 --- a/faiss/impl/io.h +++ b/faiss/impl/io.h @@ -32,7 +32,7 @@ struct IOReader { virtual size_t operator()(void* ptr, size_t size, size_t nitems) = 0; // return a file number that can be memory-mapped - virtual int fileno(); + virtual int filedescriptor(); virtual ~IOReader() {} }; @@ -45,7 +45,7 @@ struct IOWriter { virtual size_t operator()(const void* ptr, size_t size, size_t nitems) = 0; // return a file number that can be memory-mapped - virtual int fileno(); + virtual int filedescriptor(); virtual ~IOWriter() noexcept(false) {} }; @@ -73,7 +73,7 @@ struct FileIOReader : IOReader { size_t operator()(void* ptr, size_t size, size_t nitems) override; - int fileno() override; + int filedescriptor() override; }; struct FileIOWriter : IOWriter { @@ -88,7 +88,7 @@ struct FileIOWriter : IOWriter { size_t operator()(const void* ptr, size_t size, size_t nitems) override; - int fileno() override; + int filedescriptor() override; }; /******************************************************* From d5e4c798f3586a7d5e97665698c25f58dc7f0e9d Mon Sep 17 00:00:00 2001 From: Maria Date: Mon, 18 Mar 2024 11:16:56 -0700 Subject: [PATCH 095/206] Removed index_shard_and_quantize OIVFBBS (#3291) Summary: This PR removes the unused method `index_shard_and_quantize` in OIVFBBS. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3291 Reviewed By: algoriddle, junjieqi Differential Revision: D54901824 Pulled By: mlomeli1 fbshipit-source-id: f723aa386b91417f697b24b620618b864329ef6d --- demos/offline_ivf/offline_ivf.py | 58 -------------------------------- 1 file changed, 58 deletions(-) diff --git a/demos/offline_ivf/offline_ivf.py b/demos/offline_ivf/offline_ivf.py index 5c316178cb..458c1a991c 100644 --- a/demos/offline_ivf/offline_ivf.py +++ b/demos/offline_ivf/offline_ivf.py @@ -227,64 +227,6 @@ def _iterate_transformed(self, ds, start, batch_size, dt): for buffer in ds.iterate(start, batch_size, dt): yield buffer - def index_shard_and_quantize(self): - assert os.path.exists(self.index_template_file) - index = faiss.read_index(self.index_template_file) - index_ivf = faiss.downcast_index(faiss.extract_index_ivf(index)) - assert self.nprobe <= index_ivf.quantizer.ntotal, ( - f"the number of vectors {index_ivf.quantizer.ntotal} is not enough" - f" to retrieve {self.nprobe} neighbours, check." - ) - - if is_pretransform_index(index): - d = index.chain.at(0).d_out - else: - d = self.input_d - for i in range(0, self.nshards): - sfn = f"{self.index_shard_prefix}{i}" - cqfn = f"{self.coarse_quantization_prefix}{i}" # fixme - if os.path.exists(sfn) or os.path.exists(cqfn): - logging.info(f"skipping shard: {i}") - continue - try: - with open(cqfn, "xb") as cqf: - index.reset() - start = i * self.shard_size - j = 0 - quantizer = faiss.index_cpu_to_all_gpus( - index_ivf.quantizer - ) - for xb_j in tqdm( - self._iterate_transformed( - self.xb_ds, - start, - EMBEDDINGS_BATCH_SIZE, - np.float32, - ), - file=sys.stdout, - ): - assert xb_j.shape[1] == d - _, I = quantizer.search(xb_j, self.nprobe) - assert np.amin(I) >= 0, f"{I}" - assert np.amax(I) < index_ivf.nlist - cqf.write(I) - self._index_add_core_wrapper( # fixme - index_ivf, - xb_j, - np.arange(start + j, start + j + xb_j.shape[0]), - I[:, 0], - ) - j += xb_j.shape[0] - assert j <= self.shard_size - if j == self.shard_size: - break - logging.info(f"writing {sfn}...") - faiss.write_index(index, sfn) - except FileExistsError: - logging.info(f"skipping shard: {i}") - continue - logging.info("done") - def index_shard(self): assert os.path.exists(self.index_template_file) index = faiss.read_index(self.index_template_file) From 7d21c92fc1db52a5ab7a033d756b55198a950f95 Mon Sep 17 00:00:00 2001 From: Maria Date: Mon, 18 Mar 2024 11:59:21 -0700 Subject: [PATCH 096/206] Dim reduction support in OIVFBBS (#3290) Summary: This PR adds support for dimensionality reduction in OIVFBBS. I tested the code with an index `OPQ64_128,IVF4096,PQ64` using the ssnpp embeddings - this index string is added to the config_ssnpp.yaml to showcase this functionality. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3290 Reviewed By: junjieqi Differential Revision: D54878345 Pulled By: mlomeli1 fbshipit-source-id: 98ecdeb2224ce0325e37720cc113d82f9c6c75d6 --- demos/offline_ivf/config_ssnpp.yaml | 1 + demos/offline_ivf/offline_ivf.py | 30 +++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/demos/offline_ivf/config_ssnpp.yaml b/demos/offline_ivf/config_ssnpp.yaml index 690f0de156..88e0394155 100644 --- a/demos/offline_ivf/config_ssnpp.yaml +++ b/demos/offline_ivf/config_ssnpp.yaml @@ -6,6 +6,7 @@ index: non-prod: - 'IVF16384,PQ128' - 'IVF32768,PQ128' + - 'OPQ64_128,IVF4096,PQ64' nprobe: prod: - 512 diff --git a/demos/offline_ivf/offline_ivf.py b/demos/offline_ivf/offline_ivf.py index 458c1a991c..eccd2b95cb 100644 --- a/demos/offline_ivf/offline_ivf.py +++ b/demos/offline_ivf/offline_ivf.py @@ -178,7 +178,7 @@ def dedupe(self): idxs.append(np.empty((0,), dtype=np.uint32)) bs = 1_000_000 i = 0 - for buffer in tqdm(self.xb_ds.iterate(0, bs, np.float32)): + for buffer in tqdm(self._iterate_transformed(self.xb_ds, 0, bs, np.float32)): for j in range(len(codecs)): codec, codeset, idx = codecs[j], codesets[j], idxs[j] uniq = codeset.insert(codec.sa_encode(buffer)) @@ -267,11 +267,18 @@ def index_shard(self): ), file=sys.stdout, ): - assert xb_j.shape[1] == index.d - index.add_with_ids( - xb_j, - np.arange(start + jj, start + jj + xb_j.shape[0]), - ) + if is_pretransform_index(index): + assert xb_j.shape[1] == index.chain.at(0).d_out + index_ivf.add_with_ids( + xb_j, + np.arange(start + jj, start + jj + xb_j.shape[0]), + ) + else: + assert xb_j.shape[1] == index.d + index.add_with_ids( + xb_j, + np.arange(start + jj, start + jj + xb_j.shape[0]), + ) jj += xb_j.shape[0] logging.info(jj) assert ( @@ -670,10 +677,14 @@ def search(self): os.remove(Ifn) os.remove(Dfn) - try: # TODO: modify shape for pretransform case + try: + if is_pretransform_index(index): + d = index.chain.at(0).d_out + else: + d = self.input_d with open(Ifn, "xb") as f, open(Dfn, "xb") as g: xq_i = np.empty( - shape=(self.xq_bs, self.input_d), dtype=np.float16 + shape=(self.xq_bs, d), dtype=np.float16 ) q_assign = np.empty( (self.xq_bs, self.nprobe), dtype=np.int32 @@ -835,8 +846,7 @@ def consistency_check(self): for j in range(SMALL_DATA_SAMPLE): assert np.where(I[j] == j + r)[0].size > 0, ( f"I[j]: {I[j]}, j: {j}, i: {i}, shard_size:" - f" {self.shard_size}" - ) + f" {self.shard_size}") logging.info("search results...") index_ivf.nprobe = self.nprobe From f7fe62e801ebcd01e792680ee3ed8328d7e0a786 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Tue, 19 Mar 2024 10:46:30 -0700 Subject: [PATCH 097/206] Remove swig version and always rely on the latest version (#3295) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3295 In the past, we had build failure due to the latest swig version in conda-forge so we had to specify the version of swig. In this diff, we are going to change it to be the latest version always because the issue has gone. Reviewed By: algoriddle Differential Revision: D54975271 fbshipit-source-id: 7ca59fb58390edb0cc5ed52f6fd416f633dd7938 --- .circleci/config.yml | 4 ++-- conda/faiss-gpu-raft/meta.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 94aad3b11e..a5429bc1e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -224,7 +224,7 @@ jobs: - run: name: Install env using main channel command: | - conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 -c conda-forge - when: condition: equal: [ "ON", << parameters.raft >> ] @@ -232,7 +232,7 @@ jobs: - run: name: Install env using conda-forge channel command: | - conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - when: condition: and: diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index b365571777..ab605f8dde 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -84,7 +84,7 @@ outputs: build: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - - swig =4.0.2 + - swig - cmake >=3.23.1 - make # [not win] host: From cf364ec606322318ff9409ccb0f904890e38e023 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Tue, 19 Mar 2024 11:32:29 -0700 Subject: [PATCH 098/206] Remove unused fallthrough (#3296) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3296 same as title Reviewed By: algoriddle Differential Revision: D54973709 fbshipit-source-id: 545118e30773c6a4ea3f544a3a20c5ba8c394f69 --- faiss/utils/hamming_distance/generic-inl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/faiss/utils/hamming_distance/generic-inl.h b/faiss/utils/hamming_distance/generic-inl.h index e0907a1586..3565a97c6b 100644 --- a/faiss/utils/hamming_distance/generic-inl.h +++ b/faiss/utils/hamming_distance/generic-inl.h @@ -275,7 +275,6 @@ struct HammingComputerDefault { len -= 8; accu += popcount64(a64[i] ^ b64[i]); i++; - [[fallthrough]]; case 7: accu += popcount64(a64[i] ^ b64[i]); i++; @@ -309,7 +308,6 @@ struct HammingComputerDefault { const uint8_t* a = a8 + 8 * quotient8; const uint8_t* b = b8 + 8 * quotient8; switch (remainder8) { - [[fallthrough]]; case 7: accu += hamdis_tab_ham_bytes[a[6] ^ b[6]]; [[fallthrough]]; From 0e06a28094b160aee238bddb93c1967517da3af7 Mon Sep 17 00:00:00 2001 From: Jason Sylka Date: Tue, 19 Mar 2024 13:21:00 -0700 Subject: [PATCH 099/206] Revert D54973709: Remove unused fallthrough Differential Revision: D54973709 Original commit changeset: 545118e30773 Original Phabricator Diff: D54973709 fbshipit-source-id: d975b59d071deda5d8eaa2583a8f7c6f1562b9ba --- faiss/utils/hamming_distance/generic-inl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/faiss/utils/hamming_distance/generic-inl.h b/faiss/utils/hamming_distance/generic-inl.h index 3565a97c6b..e0907a1586 100644 --- a/faiss/utils/hamming_distance/generic-inl.h +++ b/faiss/utils/hamming_distance/generic-inl.h @@ -275,6 +275,7 @@ struct HammingComputerDefault { len -= 8; accu += popcount64(a64[i] ^ b64[i]); i++; + [[fallthrough]]; case 7: accu += popcount64(a64[i] ^ b64[i]); i++; @@ -308,6 +309,7 @@ struct HammingComputerDefault { const uint8_t* a = a8 + 8 * quotient8; const uint8_t* b = b8 + 8 * quotient8; switch (remainder8) { + [[fallthrough]]; case 7: accu += hamdis_tab_ham_bytes[a[6] ^ b[6]]; [[fallthrough]]; From 6f3843e14f5bde264aa3aecc71a79480d8ccdb7e Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Tue, 19 Mar 2024 16:31:48 -0700 Subject: [PATCH 100/206] Back out "Remove swig version and always rely on the latest version" (#3297) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3297 Original commit changeset: 7ca59fb58390 Original Phabricator Diff: D54975271 Differential Revision: D55102226 fbshipit-source-id: 2a2828b4e74b16ee25b090ae4b844dab4f1d72a6 --- .circleci/config.yml | 4 ++-- conda/faiss-gpu-raft/meta.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a5429bc1e7..94aad3b11e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -224,7 +224,7 @@ jobs: - run: name: Install env using main channel command: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 -c conda-forge + conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 - when: condition: equal: [ "ON", << parameters.raft >> ] @@ -232,7 +232,7 @@ jobs: - run: name: Install env using conda-forge channel command: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - when: condition: and: diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index ab605f8dde..b365571777 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -84,7 +84,7 @@ outputs: build: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - - swig + - swig =4.0.2 - cmake >=3.23.1 - make # [not win] host: From 5483f210d2c7aa858c473e601e2e387ea275f91b Mon Sep 17 00:00:00 2001 From: Yuri Victorovich Date: Wed, 20 Mar 2024 09:52:12 -0700 Subject: [PATCH 101/206] Use cmake's find_package to link to GTest (#3278) Summary: Otherwise the gtest transitive dependency isn't linked properly when GoogleTest is built to have shared libraries. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3278 Reviewed By: junjieqi Differential Revision: D55134304 Pulled By: algoriddle fbshipit-source-id: 01e7b11f28c27f837afee36350fbf9543e301a31 --- tests/CMakeLists.txt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9017edc586..0cb8219096 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,18 +59,12 @@ if(FAISS_OPT_LEVEL STREQUAL "avx512") target_link_libraries(faiss_test PRIVATE faiss_avx512) endif() -include(FetchContent) -FetchContent_Declare(googletest - URL "https://github.com/google/googletest/archive/release-1.12.1.tar.gz") -set(BUILD_GMOCK CACHE BOOL OFF) -set(INSTALL_GTEST CACHE BOOL OFF) -FetchContent_MakeAvailable(googletest) - find_package(OpenMP REQUIRED) +find_package(GTest CONFIG REQUIRED) target_link_libraries(faiss_test PRIVATE OpenMP::OpenMP_CXX - gtest_main + GTest::gtest_main $<$:raft::raft> ) From 9c79e3d5b1e0bd81c37e6a006a5b2340139d41b1 Mon Sep 17 00:00:00 2001 From: divyegala Date: Wed, 20 Mar 2024 14:28:42 -0700 Subject: [PATCH 102/206] RAFT 24.04 API changes (#3282) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3282 Reviewed By: junjieqi Differential Revision: D55153617 Pulled By: algoriddle fbshipit-source-id: 7b1ab24a6b0fbe002a0d8358078d014b1556044a --- faiss/gpu/impl/RaftIVFFlat.cu | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/faiss/gpu/impl/RaftIVFFlat.cu b/faiss/gpu/impl/RaftIVFFlat.cu index 1e310723d0..0906a60f46 100644 --- a/faiss/gpu/impl/RaftIVFFlat.cu +++ b/faiss/gpu/impl/RaftIVFFlat.cu @@ -403,7 +403,8 @@ void RaftIVFFlat::copyInvertedListsFrom(const InvertedLists* ivf) { } // Update the pointers and the sizes - raft_knn_index.value().recompute_internal_state(raft_handle); + raft::neighbors::ivf_flat::helpers::recompute_internal_state( + raft_handle, &(raft_knn_index.value())); for (size_t i = 0; i < nlist; ++i) { size_t listSize = ivf->list_size(i); From 8274c38f2737f83ecc80655afb595b942779e0ea Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 21 Mar 2024 10:30:44 -0700 Subject: [PATCH 103/206] Remove TypedStorage usage when working with torch_utils (#3301) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3301 In `torch_utils.py`, changed `storage()' references to `untyped_storage()`. Reviewed By: junjieqi Differential Revision: D55167842 fbshipit-source-id: 911eda1c22f10595663fb4416ab992903390d457 --- contrib/torch_utils.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/torch_utils.py b/contrib/torch_utils.py index 790c295e48..e371932c9f 100644 --- a/contrib/torch_utils.py +++ b/contrib/torch_utils.py @@ -33,7 +33,7 @@ def swig_ptr_from_UInt8Tensor(x): assert x.is_contiguous() assert x.dtype == torch.uint8 return faiss.cast_integer_to_uint8_ptr( - x.storage().data_ptr() + x.storage_offset()) + x.untyped_storage().data_ptr() + x.storage_offset()) def swig_ptr_from_HalfTensor(x): """ gets a Faiss SWIG pointer from a pytorch tensor (on CPU or GPU) """ @@ -41,28 +41,28 @@ def swig_ptr_from_HalfTensor(x): assert x.dtype == torch.float16 # no canonical half type in C/C++ return faiss.cast_integer_to_void_ptr( - x.storage().data_ptr() + x.storage_offset() * 2) + x.untyped_storage().data_ptr() + x.storage_offset() * 2) def swig_ptr_from_FloatTensor(x): """ gets a Faiss SWIG pointer from a pytorch tensor (on CPU or GPU) """ assert x.is_contiguous() assert x.dtype == torch.float32 return faiss.cast_integer_to_float_ptr( - x.storage().data_ptr() + x.storage_offset() * 4) + x.untyped_storage().data_ptr() + x.storage_offset() * 4) def swig_ptr_from_IntTensor(x): """ gets a Faiss SWIG pointer from a pytorch tensor (on CPU or GPU) """ assert x.is_contiguous() assert x.dtype == torch.int32, 'dtype=%s' % x.dtype return faiss.cast_integer_to_int_ptr( - x.storage().data_ptr() + x.storage_offset() * 4) + x.untyped_storage().data_ptr() + x.storage_offset() * 4) def swig_ptr_from_IndicesTensor(x): """ gets a Faiss SWIG pointer from a pytorch tensor (on CPU or GPU) """ assert x.is_contiguous() assert x.dtype == torch.int64, 'dtype=%s' % x.dtype return faiss.cast_integer_to_idx_t_ptr( - x.storage().data_ptr() + x.storage_offset() * 8) + x.untyped_storage().data_ptr() + x.storage_offset() * 8) @contextlib.contextmanager def using_stream(res, pytorch_stream=None): From b77061ff5eb2d5dc3b1fc25b240578c2d686a646 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 21 Mar 2024 11:18:02 -0700 Subject: [PATCH 104/206] move to raft 24.04 (#3302) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3302 Reviewed By: junjieqi Differential Revision: D55173776 fbshipit-source-id: 5de2225638e2d997fbfa4e28b924d5e4633ee27f --- conda/faiss-gpu-raft/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index b365571777..12dfc889b1 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -55,14 +55,14 @@ outputs: host: - mkl =2023 # [x86_64] - openblas # [not x86_64] - - libraft =24.02 + - libraft =24.04 - cuda-version {{ cuda_constraints }} run: - mkl =2023 # [x86_64] - openblas # [not x86_64] - cuda-cudart {{ cuda_constraints }} - libcublas {{ libcublas_constraints }} - - libraft =24.02 + - libraft =24.04 - cuda-version {{ cuda_constraints }} test: requires: From fa1f39ec9fc9a7fd5afa3be79e1e214317cfc21b Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Fri, 22 Mar 2024 12:55:30 -0700 Subject: [PATCH 105/206] Fix HNSW stats (#3309) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3309 Make sure that the HNSW search stats work, remove stats for deprecated functionality. Remove code of the link and code paper that is not supported anymore. Reviewed By: kuarora, junjieqi Differential Revision: D55247802 fbshipit-source-id: 03f176be092bff6b2db359cc956905d8646ea702 --- benchs/link_and_code/README.md | 137 +-------- benchs/link_and_code/bench_link_and_code.py | 300 -------------------- benchs/link_and_code/datasets.py | 236 --------------- benchs/link_and_code/neighbor_codec.py | 241 ---------------- faiss/IndexHNSW.cpp | 16 +- faiss/gpu/GpuIndex.h | 10 +- faiss/impl/HNSW.cpp | 4 +- faiss/impl/HNSW.h | 20 +- tests/test_graph_based.py | 10 + 9 files changed, 27 insertions(+), 947 deletions(-) delete mode 100755 benchs/link_and_code/bench_link_and_code.py delete mode 100755 benchs/link_and_code/datasets.py delete mode 100755 benchs/link_and_code/neighbor_codec.py diff --git a/benchs/link_and_code/README.md b/benchs/link_and_code/README.md index 697c7bdfc6..0c04cadac5 100644 --- a/benchs/link_and_code/README.md +++ b/benchs/link_and_code/README.md @@ -21,138 +21,5 @@ graph to improve the reconstruction. It is described in ArXiV [here](https://arxiv.org/abs/1804.09996) -Code structure --------------- - -The test runs with 3 files: - -- `bench_link_and_code.py`: driver script - -- `datasets.py`: code to load the datasets. The example code runs on the - deep1b and bigann datasets. See the [toplevel README](../README.md) - on how to download them. They should be put in a directory, edit - datasets.py to set the path. - -- `neighbor_codec.py`: this is where the representation is trained. - -The code runs on top of Faiss. The HNSW index can be extended with a -`ReconstructFromNeighbors` C++ object that refines the distances. The -training is implemented in Python. - -Update: 2023-12-28: the current Faiss dropped support for reconstruction with -this method. - -Reproducing Table 2 in the paper --------------------------------- - -The results of table 2 (accuracy on deep100M) in the paper can be -obtained with: - -```bash -python bench_link_and_code.py \ - --db deep100M \ - --M0 6 \ - --indexkey OPQ36_144,HNSW32_PQ36 \ - --indexfile $bdir/deep100M_PQ36_L6.index \ - --beta_nsq 4 \ - --beta_centroids $bdir/deep100M_PQ36_L6_nsq4.npy \ - --neigh_recons_codes $bdir/deep100M_PQ36_L6_nsq4_codes.npy \ - --k_reorder 0,5 --efSearch 1,1024 -``` - -Set `bdir` to a scratch directory. - -Explanation of the flags: - -- `--db deep1M`: dataset to process - -- `--M0 6`: number of links on the base level (L6) - -- `--indexkey OPQ36_144,HNSW32_PQ36`: Faiss index key to construct the - HNSW structure. It means that vectors are transformed by OPQ and - encoded with PQ 36x8 (with an intermediate size of 144D). The HNSW - level>0 nodes have 32 links (theses ones are "cheap" to store - because there are fewer nodes in the upper levels. - -- `--indexfile $bdir/deep1M_PQ36_M6.index`: name of the index file - (without information for the L&C extension) - -- `--beta_nsq 4`: number of bytes to allocate for the codes (M in the - paper) - -- `--beta_centroids $bdir/deep1M_PQ36_M6_nsq4.npy`: filename to store - the trained beta centroids - -- `--neigh_recons_codes $bdir/deep1M_PQ36_M6_nsq4_codes.npy`: filename - for the encoded weights (beta) of the combination - -- `--k_reorder 0,5`: number of results to reorder. 0 = baseline - without reordering, 5 = value used throughout the paper - -- `--efSearch 1,1024`: number of nodes to visit (T in the paper) - -The script will proceed with the following steps: - -0. load dataset (and possibly compute the ground-truth if the -ground-truth file is not provided) - -1. train the OPQ encoder - -2. build the index and store it - -3. compute the residuals and train the beta vocabulary to do the reconstruction - -4. encode the vertices - -5. search and evaluate the search results. - -With option `--exhaustive` the results of the exhaustive column can be -obtained. - -The run above should output: -```bash -... -setting k_reorder=5 -... -efSearch=1024 0.3132 ms per query, R@1: 0.4283 R@10: 0.6337 R@100: 0.6520 ndis 40941919 nreorder 50000 - -``` -which matches the paper's table 2. - -Note that in multi-threaded mode, the building of the HNSW structure -is not deterministic. Therefore, the results across runs may not be exactly the same. - -Reproducing Figure 5 in the paper ---------------------------------- - -Figure 5 just evaluates the combination of HNSW and PQ. For example, -the operating point L6&OPQ40 can be obtained with - -```bash -python bench_link_and_code.py \ - --db deep1M \ - --M0 6 \ - --indexkey OPQ40_160,HNSW32_PQ40 \ - --indexfile $bdir/deep1M_PQ40_M6.index \ - --beta_nsq 1 --beta_k 1 \ - --beta_centroids $bdir/deep1M_PQ40_M6_nsq0.npy \ - --neigh_recons_codes $bdir/deep1M_PQ36_M6_nsq0_codes.npy \ - --k_reorder 0 --efSearch 16,64,256,1024 -``` - -The arguments are similar to the previous table. Note that nsq = 0 is -simulated by setting beta_nsq = 1 and beta_k = 1 (ie a code with a single -reproduction value). - -The output should look like: - -```bash -setting k_reorder=0 -efSearch=16 0.0147 ms per query, R@1: 0.3409 R@10: 0.4388 R@100: 0.4394 ndis 2629735 nreorder 0 -efSearch=64 0.0122 ms per query, R@1: 0.4836 R@10: 0.6490 R@100: 0.6509 ndis 4623221 nreorder 0 -efSearch=256 0.0344 ms per query, R@1: 0.5730 R@10: 0.7915 R@100: 0.7951 ndis 11090176 nreorder 0 -efSearch=1024 0.2656 ms per query, R@1: 0.6212 R@10: 0.8722 R@100: 0.8765 ndis 33501951 nreorder 0 -``` - -The results with k_reorder=5 are not reported in the paper, they -represent the performance of a "free coding" version of the algorithm. +The necessary code for this paper was removed from Faiss in version 1.8.0. +For a functioning verinsion, use Faiss 1.7.4. diff --git a/benchs/link_and_code/bench_link_and_code.py b/benchs/link_and_code/bench_link_and_code.py deleted file mode 100755 index ed8f86d631..0000000000 --- a/benchs/link_and_code/bench_link_and_code.py +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -from __future__ import print_function -import os -import sys -import time -import numpy as np -import faiss -import argparse -import datasets -from datasets import sanitize -import neighbor_codec - -###################################################### -# Command-line parsing -###################################################### - - -parser = argparse.ArgumentParser() - -def aa(*args, **kwargs): - group.add_argument(*args, **kwargs) - -group = parser.add_argument_group('dataset options') - -aa('--db', default='deep1M', help='dataset') -aa( '--compute_gt', default=False, action='store_true', - help='compute and store the groundtruth') - -group = parser.add_argument_group('index consturction') - -aa('--indexkey', default='HNSW32', help='index_factory type') -aa('--efConstruction', default=200, type=int, - help='HNSW construction factor') -aa('--M0', default=-1, type=int, help='size of base level') -aa('--maxtrain', default=256 * 256, type=int, - help='maximum number of training points') -aa('--indexfile', default='', help='file to read or write index from') -aa('--add_bs', default=-1, type=int, - help='add elements index by batches of this size') -aa('--link_singletons', default=False, action='store_true', - help='do a pass to link in the singletons') - -group = parser.add_argument_group( - 'searching (reconstruct_from_neighbors options)') - -aa('--beta_centroids', default='', - help='file with codebook') -aa('--neigh_recons_codes', default='', - help='file with codes for reconstruction') -aa('--beta_ntrain', default=250000, type=int, help='') -aa('--beta_k', default=256, type=int, help='beta codebook size') -aa('--beta_nsq', default=1, type=int, help='number of beta sub-vectors') -aa('--beta_niter', default=10, type=int, help='') -aa('--k_reorder', default='-1', help='') - -group = parser.add_argument_group('searching') - -aa('--k', default=100, type=int, help='nb of nearest neighbors') -aa('--exhaustive', default=False, action='store_true', - help='report the exhaustive search topline') -aa('--searchthreads', default=-1, type=int, - help='nb of threads to use at search time') -aa('--efSearch', default='', type=str, - help='comma-separated values of efSearch to try') - -args = parser.parse_args() - -print("args:", args) - - -###################################################### -# Load dataset -###################################################### - -xt, xb, xq, gt = datasets.load_data( - dataset=args.db, compute_gt=args.compute_gt) - -nq, d = xq.shape -nb, d = xb.shape - - -###################################################### -# Make index -###################################################### - -if os.path.exists(args.indexfile): - - print("reading", args.indexfile) - index = faiss.read_index(args.indexfile) - - if isinstance(index, faiss.IndexPreTransform): - index_hnsw = faiss.downcast_index(index.index) - vec_transform = index.chain.at(0).apply_py - else: - index_hnsw = index - vec_transform = lambda x:x - - hnsw = index_hnsw.hnsw - hnsw_stats = faiss.cvar.hnsw_stats - -else: - - print("build index, key=", args.indexkey) - - index = faiss.index_factory(d, args.indexkey) - - if isinstance(index, faiss.IndexPreTransform): - index_hnsw = faiss.downcast_index(index.index) - vec_transform = index.chain.at(0).apply_py - else: - index_hnsw = index - vec_transform = lambda x:x - - hnsw = index_hnsw.hnsw - hnsw.efConstruction = args.efConstruction - hnsw_stats = faiss.cvar.hnsw_stats - index.verbose = True - index_hnsw.verbose = True - index_hnsw.storage.verbose = True - - if args.M0 != -1: - print("set level 0 nb of neighbors to", args.M0) - hnsw.set_nb_neighbors(0, args.M0) - - xt2 = sanitize(xt[:args.maxtrain]) - assert np.all(np.isfinite(xt2)) - - print("train, size", xt.shape) - t0 = time.time() - index.train(xt2) - print(" train in %.3f s" % (time.time() - t0)) - - print("adding") - t0 = time.time() - if args.add_bs == -1: - index.add(sanitize(xb)) - else: - for i0 in range(0, nb, args.add_bs): - i1 = min(nb, i0 + args.add_bs) - print(" adding %d:%d / %d" % (i0, i1, nb)) - index.add(sanitize(xb[i0:i1])) - - print(" add in %.3f s" % (time.time() - t0)) - print("storing", args.indexfile) - faiss.write_index(index, args.indexfile) - - -###################################################### -# Train beta centroids and encode dataset -###################################################### - -if args.beta_centroids: - print("reordering links") - index_hnsw.reorder_links() - - if os.path.exists(args.beta_centroids): - print("load", args.beta_centroids) - beta_centroids = np.load(args.beta_centroids) - nsq, k, M1 = beta_centroids.shape - assert M1 == hnsw.nb_neighbors(0) + 1 - - rfn = faiss.ReconstructFromNeighbors(index_hnsw, k, nsq) - else: - print("train beta centroids") - rfn = faiss.ReconstructFromNeighbors( - index_hnsw, args.beta_k, args.beta_nsq) - - xb_full = vec_transform(sanitize(xb[:args.beta_ntrain])) - - beta_centroids = neighbor_codec.train_beta_codebook( - rfn, xb_full, niter=args.beta_niter) - - print(" storing", args.beta_centroids) - np.save(args.beta_centroids, beta_centroids) - - - faiss.copy_array_to_vector(beta_centroids.ravel(), - rfn.codebook) - index_hnsw.reconstruct_from_neighbors = rfn - - if rfn.k == 1: - pass # no codes to take care of - elif os.path.exists(args.neigh_recons_codes): - print("loading neigh codes", args.neigh_recons_codes) - codes = np.load(args.neigh_recons_codes) - assert codes.size == rfn.code_size * index.ntotal - faiss.copy_array_to_vector(codes.astype('uint8'), - rfn.codes) - rfn.ntotal = index.ntotal - else: - print("encoding neigh codes") - t0 = time.time() - - bs = 1000000 if args.add_bs == -1 else args.add_bs - - for i0 in range(0, nb, bs): - i1 = min(i0 + bs, nb) - print(" encode %d:%d / %d [%.3f s]\r" % ( - i0, i1, nb, time.time() - t0), end=' ') - sys.stdout.flush() - xbatch = vec_transform(sanitize(xb[i0:i1])) - rfn.add_codes(i1 - i0, faiss.swig_ptr(xbatch)) - print() - - print("storing %s" % args.neigh_recons_codes) - codes = faiss.vector_to_array(rfn.codes) - np.save(args.neigh_recons_codes, codes) - -###################################################### -# Exhaustive evaluation -###################################################### - -if args.exhaustive: - print("exhaustive evaluation") - xq_tr = vec_transform(sanitize(xq)) - index2 = faiss.IndexFlatL2(index_hnsw.d) - accu_recons_error = 0.0 - - if faiss.get_num_gpus() > 0: - print("do eval on GPU") - co = faiss.GpuMultipleClonerOptions() - co.shard = False - index2 = faiss.index_cpu_to_all_gpus(index2, co) - - # process in batches in case the dataset does not fit in RAM - rh = datasets.ResultHeap(xq_tr.shape[0], 100) - t0 = time.time() - bs = 500000 - for i0 in range(0, nb, bs): - i1 = min(nb, i0 + bs) - print(' handling batch %d:%d' % (i0, i1)) - - xb_recons = np.empty( - (i1 - i0, index_hnsw.d), dtype='float32') - rfn.reconstruct_n(i0, i1 - i0, faiss.swig_ptr(xb_recons)) - - accu_recons_error += ( - (vec_transform(sanitize(xb[i0:i1])) - - xb_recons)**2).sum() - - index2.reset() - index2.add(xb_recons) - D, I = index2.search(xq_tr, 100) - rh.add_batch_result(D, I, i0) - - rh.finalize() - del index2 - t1 = time.time() - print("done in %.3f s" % (t1 - t0)) - print("total reconstruction error: ", accu_recons_error) - print("eval retrieval:") - datasets.evaluate_DI(rh.D, rh.I, gt) - - -def get_neighbors(hnsw, i, level): - " list the neighbors for node i at level " - assert i < hnsw.levels.size() - assert level < hnsw.levels.at(i) - be = np.empty(2, 'uint64') - hnsw.neighbor_range(i, level, faiss.swig_ptr(be), faiss.swig_ptr(be[1:])) - return [hnsw.neighbors.at(j) for j in range(be[0], be[1])] - - -############################################################# -# Index is ready -############################################################# - -xq = sanitize(xq) - -if args.searchthreads != -1: - print("Setting nb of threads to", args.searchthreads) - faiss.omp_set_num_threads(args.searchthreads) - - -if gt is None: - print("no valid groundtruth -- exit") - sys.exit() - - -k_reorders = [int(x) for x in args.k_reorder.split(',')] -efSearchs = [int(x) for x in args.efSearch.split(',')] - - -for k_reorder in k_reorders: - - if index_hnsw.reconstruct_from_neighbors: - print("setting k_reorder=%d" % k_reorder) - index_hnsw.reconstruct_from_neighbors.k_reorder = k_reorder - - for efSearch in efSearchs: - print("efSearch=%-4d" % efSearch, end=' ') - hnsw.efSearch = efSearch - hnsw_stats.reset() - datasets.evaluate(xq, gt, index, k=args.k, endl=False) - - print("ndis %d nreorder %d" % (hnsw_stats.ndis, hnsw_stats.nreorder)) diff --git a/benchs/link_and_code/datasets.py b/benchs/link_and_code/datasets.py deleted file mode 100755 index a043eb8883..0000000000 --- a/benchs/link_and_code/datasets.py +++ /dev/null @@ -1,236 +0,0 @@ -#! /usr/bin/env python2 - -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -""" -Common functions to load datasets and compute their ground-truth -""" -from __future__ import print_function - -import time -import numpy as np -import faiss -import pdb -import sys - -# set this to the directory that contains the datafiles. -# deep1b data should be at simdir + 'deep1b' -# bigann data should be at simdir + 'bigann' -simdir = '/mnt/vol/gfsai-east/ai-group/datasets/simsearch/' - -################################################################# -# Small I/O functions -################################################################# - - -def ivecs_read(fname): - a = np.fromfile(fname, dtype='int32') - d = a[0] - return a.reshape(-1, d + 1)[:, 1:].copy() - - -def fvecs_read(fname): - return ivecs_read(fname).view('float32') - - -def ivecs_mmap(fname): - a = np.memmap(fname, dtype='int32', mode='r') - d = a[0] - return a.reshape(-1, d + 1)[:, 1:] - - -def fvecs_mmap(fname): - return ivecs_mmap(fname).view('float32') - - -def bvecs_mmap(fname): - x = np.memmap(fname, dtype='uint8', mode='r') - d = x[:4].view('int32')[0] - return x.reshape(-1, d + 4)[:, 4:] - - -def ivecs_write(fname, m): - n, d = m.shape - m1 = np.empty((n, d + 1), dtype='int32') - m1[:, 0] = d - m1[:, 1:] = m - m1.tofile(fname) - - -def fvecs_write(fname, m): - m = m.astype('float32') - ivecs_write(fname, m.view('int32')) - - -################################################################# -# Dataset -################################################################# - -def sanitize(x): - return np.ascontiguousarray(x, dtype='float32') - - -class ResultHeap: - """ Combine query results from a sliced dataset """ - - def __init__(self, nq, k): - " nq: number of query vectors, k: number of results per query " - self.I = np.zeros((nq, k), dtype='int64') - self.D = np.zeros((nq, k), dtype='float32') - self.nq, self.k = nq, k - heaps = faiss.float_maxheap_array_t() - heaps.k = k - heaps.nh = nq - heaps.val = faiss.swig_ptr(self.D) - heaps.ids = faiss.swig_ptr(self.I) - heaps.heapify() - self.heaps = heaps - - def add_batch_result(self, D, I, i0): - assert D.shape == (self.nq, self.k) - assert I.shape == (self.nq, self.k) - I += i0 - self.heaps.addn_with_ids( - self.k, faiss.swig_ptr(D), - faiss.swig_ptr(I), self.k) - - def finalize(self): - self.heaps.reorder() - - - -def compute_GT_sliced(xb, xq, k): - print("compute GT") - t0 = time.time() - nb, d = xb.shape - nq, d = xq.shape - rh = ResultHeap(nq, k) - bs = 10 ** 5 - - xqs = sanitize(xq) - - db_gt = faiss.index_cpu_to_all_gpus(faiss.IndexFlatL2(d)) - - # compute ground-truth by blocks of bs, and add to heaps - for i0 in range(0, nb, bs): - i1 = min(nb, i0 + bs) - xsl = sanitize(xb[i0:i1]) - db_gt.add(xsl) - D, I = db_gt.search(xqs, k) - rh.add_batch_result(D, I, i0) - db_gt.reset() - print("\r %d/%d, %.3f s" % (i0, nb, time.time() - t0), end=' ') - sys.stdout.flush() - print() - rh.finalize() - gt_I = rh.I - - print("GT time: %.3f s" % (time.time() - t0)) - return gt_I - - -def do_compute_gt(xb, xq, k): - print("computing GT") - nb, d = xb.shape - index = faiss.index_cpu_to_all_gpus(faiss.IndexFlatL2(d)) - if nb < 100 * 1000: - print(" add") - index.add(np.ascontiguousarray(xb, dtype='float32')) - print(" search") - D, I = index.search(np.ascontiguousarray(xq, dtype='float32'), k) - else: - I = compute_GT_sliced(xb, xq, k) - - return I.astype('int32') - - -def load_data(dataset='deep1M', compute_gt=False): - - print("load data", dataset) - - if dataset == 'sift1M': - basedir = simdir + 'sift1M/' - - xt = fvecs_read(basedir + "sift_learn.fvecs") - xb = fvecs_read(basedir + "sift_base.fvecs") - xq = fvecs_read(basedir + "sift_query.fvecs") - gt = ivecs_read(basedir + "sift_groundtruth.ivecs") - - elif dataset.startswith('bigann'): - basedir = simdir + 'bigann/' - - dbsize = 1000 if dataset == "bigann1B" else int(dataset[6:-1]) - xb = bvecs_mmap(basedir + 'bigann_base.bvecs') - xq = bvecs_mmap(basedir + 'bigann_query.bvecs') - xt = bvecs_mmap(basedir + 'bigann_learn.bvecs') - # trim xb to correct size - xb = xb[:dbsize * 1000 * 1000] - gt = ivecs_read(basedir + 'gnd/idx_%dM.ivecs' % dbsize) - - elif dataset.startswith("deep"): - basedir = simdir + 'deep1b/' - szsuf = dataset[4:] - if szsuf[-1] == 'M': - dbsize = 10 ** 6 * int(szsuf[:-1]) - elif szsuf == '1B': - dbsize = 10 ** 9 - elif szsuf[-1] == 'k': - dbsize = 1000 * int(szsuf[:-1]) - else: - assert False, "did not recognize suffix " + szsuf - - xt = fvecs_mmap(basedir + "learn.fvecs") - xb = fvecs_mmap(basedir + "base.fvecs") - xq = fvecs_read(basedir + "deep1B_queries.fvecs") - - xb = xb[:dbsize] - - gt_fname = basedir + "%s_groundtruth.ivecs" % dataset - if compute_gt: - gt = do_compute_gt(xb, xq, 100) - print("store", gt_fname) - ivecs_write(gt_fname, gt) - - gt = ivecs_read(gt_fname) - - else: - assert False - - print("dataset %s sizes: B %s Q %s T %s" % ( - dataset, xb.shape, xq.shape, xt.shape)) - - return xt, xb, xq, gt - -################################################################# -# Evaluation -################################################################# - - -def evaluate_DI(D, I, gt): - nq = gt.shape[0] - k = I.shape[1] - rank = 1 - while rank <= k: - recall = (I[:, :rank] == gt[:, :1]).sum() / float(nq) - print("R@%d: %.4f" % (rank, recall), end=' ') - rank *= 10 - - -def evaluate(xq, gt, index, k=100, endl=True): - t0 = time.time() - D, I = index.search(xq, k) - t1 = time.time() - nq = xq.shape[0] - print("\t %8.4f ms per query, " % ( - (t1 - t0) * 1000.0 / nq), end=' ') - rank = 1 - while rank <= k: - recall = (I[:, :rank] == gt[:, :1]).sum() / float(nq) - print("R@%d: %.4f" % (rank, recall), end=' ') - rank *= 10 - if endl: - print() - return D, I diff --git a/benchs/link_and_code/neighbor_codec.py b/benchs/link_and_code/neighbor_codec.py deleted file mode 100755 index 54cad8168a..0000000000 --- a/benchs/link_and_code/neighbor_codec.py +++ /dev/null @@ -1,241 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -""" -This is the training code for the link and code. Especially the -neighbors_kmeans function implements the EM-algorithm to find the -appropriate weightings and cluster them. -""" -from __future__ import print_function - -import time -import numpy as np -import faiss - -#---------------------------------------------------------- -# Utils -#---------------------------------------------------------- - -def sanitize(x): - return np.ascontiguousarray(x, dtype='float32') - - -def train_kmeans(x, k, ngpu, max_points_per_centroid=256): - "Runs kmeans on one or several GPUs" - d = x.shape[1] - clus = faiss.Clustering(d, k) - clus.verbose = True - clus.niter = 20 - clus.max_points_per_centroid = max_points_per_centroid - - if ngpu == 0: - index = faiss.IndexFlatL2(d) - else: - res = [faiss.StandardGpuResources() for i in range(ngpu)] - - flat_config = [] - for i in range(ngpu): - cfg = faiss.GpuIndexFlatConfig() - cfg.useFloat16 = False - cfg.device = i - flat_config.append(cfg) - - if ngpu == 1: - index = faiss.GpuIndexFlatL2(res[0], d, flat_config[0]) - else: - indexes = [faiss.GpuIndexFlatL2(res[i], d, flat_config[i]) - for i in range(ngpu)] - index = faiss.IndexReplicas() - for sub_index in indexes: - index.addIndex(sub_index) - - # perform the training - clus.train(x, index) - centroids = faiss.vector_float_to_array(clus.centroids) - - stats = clus.iteration_stats - stats = [stats.at(i) for i in range(stats.size())] - obj = np.array([st.obj for st in stats]) - print("final objective: %.4g" % obj[-1]) - - return centroids.reshape(k, d) - - -#---------------------------------------------------------- -# Learning the codebook from neighbors -#---------------------------------------------------------- - - -# works with both a full Inn table and dynamically generated neighbors - -def get_Inn_shape(Inn): - if type(Inn) != tuple: - return Inn.shape - return Inn[:2] - -def get_neighbor_table(x_coded, Inn, i): - if type(Inn) != tuple: - return x_coded[Inn[i,:],:] - rfn = x_coded - M, d = rfn.M, rfn.index.d - out = np.zeros((M + 1, d), dtype='float32') - int_i = int(i) - rfn.get_neighbor_table(int_i, faiss.swig_ptr(out)) - _, _, sq = Inn - return out[:, sq * rfn.dsub : (sq + 1) * rfn.dsub] - - -# Function that produces the best regression values from the vector -# and its neighbors -def regress_from_neighbors (x, x_coded, Inn): - (N, knn) = get_Inn_shape(Inn) - betas = np.zeros((N,knn)) - t0 = time.time() - for i in range (N): - xi = x[i,:] - NNi = get_neighbor_table(x_coded, Inn, i) - betas[i,:] = np.linalg.lstsq(NNi.transpose(), xi, rcond=0.01)[0] - if i % (N / 10) == 0: - print ("[%d:%d] %6.3fs" % (i, i + N / 10, time.time() - t0)) - return betas - - - -# find the best beta minimizing ||x-x_coded[Inn,:]*beta||^2 -def regress_opt_beta (x, x_coded, Inn): - (N, knn) = get_Inn_shape(Inn) - d = x.shape[1] - - # construct the linear system to be solved - X = np.zeros ((d*N)) - Y = np.zeros ((d*N, knn)) - for i in range (N): - X[i*d:(i+1)*d] = x[i,:] - neighbor_table = get_neighbor_table(x_coded, Inn, i) - Y[i*d:(i+1)*d, :] = neighbor_table.transpose() - beta_opt = np.linalg.lstsq(Y, X, rcond=0.01)[0] - return beta_opt - - -# Find the best encoding by minimizing the reconstruction error using -# a set of pre-computed beta values -def assign_beta (beta_centroids, x, x_coded, Inn, verbose=True): - if type(Inn) == tuple: - return assign_beta_2(beta_centroids, x, x_coded, Inn) - (N, knn) = Inn.shape - x_ibeta = np.zeros ((N), dtype='int32') - t0= time.time() - for i in range (N): - NNi = x_coded[Inn[i,:]] - # Consider all possible betas for the encoding and compute the - # encoding error - x_reg_all = np.dot (beta_centroids, NNi) - err = ((x_reg_all - x[i,:]) ** 2).sum(axis=1) - x_ibeta[i] = err.argmin() - if verbose: - if i % (N / 10) == 0: - print ("[%d:%d] %6.3fs" % (i, i + N / 10, time.time() - t0)) - return x_ibeta - - -# Reconstruct a set of vectors using the beta_centroids, the -# assignment, the encoded neighbors identified by the list Inn (which -# includes the vector itself) -def recons_from_neighbors (beta_centroids, x_ibeta, x_coded, Inn): - (N, knn) = Inn.shape - x_rec = np.zeros(x_coded.shape) - t0= time.time() - for i in range (N): - NNi = x_coded[Inn[i,:]] - x_rec[i, :] = np.dot (beta_centroids[x_ibeta[i]], NNi) - if i % (N / 10) == 0: - print ("[%d:%d] %6.3fs" % (i, i + N / 10, time.time() - t0)) - return x_rec - - -# Compute a EM-like algorithm trying at optimizing the beta such as they -# minimize the reconstruction error from the neighbors -def neighbors_kmeans (x, x_coded, Inn, K, ngpus=1, niter=5): - # First compute centroids using a regular k-means algorithm - betas = regress_from_neighbors (x, x_coded, Inn) - beta_centroids = train_kmeans( - sanitize(betas), K, ngpus, max_points_per_centroid=1000000) - _, knn = get_Inn_shape(Inn) - d = x.shape[1] - - rs = np.random.RandomState() - for iter in range(niter): - print('iter', iter) - idx = assign_beta (beta_centroids, x, x_coded, Inn, verbose=False) - - hist = np.bincount(idx) - for cl0 in np.where(hist == 0)[0]: - print(" cluster %d empty, split" % cl0, end=' ') - cl1 = idx[np.random.randint(idx.size)] - pos = np.nonzero (idx == cl1)[0] - pos = rs.choice(pos, pos.size / 2) - print(" cl %d -> %d + %d" % (cl1, len(pos), hist[cl1] - len(pos))) - idx[pos] = cl0 - hist = np.bincount(idx) - - tot_err = 0 - for k in range (K): - pos = np.nonzero (idx == k)[0] - npos = pos.shape[0] - - X = np.zeros (d*npos) - Y = np.zeros ((d*npos, knn)) - - for i in range(npos): - X[i*d:(i+1)*d] = x[pos[i],:] - neighbor_table = get_neighbor_table(x_coded, Inn, pos[i]) - Y[i*d:(i+1)*d, :] = neighbor_table.transpose() - sol, residuals, _, _ = np.linalg.lstsq(Y, X, rcond=0.01) - if residuals.size > 0: - tot_err += residuals.sum() - beta_centroids[k, :] = sol - print(' err=%g' % tot_err) - return beta_centroids - - -# assign the betas in C++ -def assign_beta_2(beta_centroids, x, rfn, Inn): - _, _, sq = Inn - if rfn.k == 1: - return np.zeros(x.shape[0], dtype=int) - # add dummy dimensions to beta_centroids and x - all_beta_centroids = np.zeros( - (rfn.nsq, rfn.k, rfn.M + 1), dtype='float32') - all_beta_centroids[sq] = beta_centroids - all_x = np.zeros((len(x), rfn.d), dtype='float32') - all_x[:, sq * rfn.dsub : (sq + 1) * rfn.dsub] = x - rfn.codes.clear() - rfn.ntotal = 0 - faiss.copy_array_to_vector( - all_beta_centroids.ravel(), rfn.codebook) - rfn.add_codes(len(x), faiss.swig_ptr(all_x)) - codes = faiss.vector_to_array(rfn.codes) - codes = codes.reshape(-1, rfn.nsq) - return codes[:, sq] - - -####################################################### -# For usage from bench_storages.py - -def train_beta_codebook(rfn, xb_full, niter=10): - beta_centroids = [] - for sq in range(rfn.nsq): - d0, d1 = sq * rfn.dsub, (sq + 1) * rfn.dsub - print("training subquantizer %d/%d on dimensions %d:%d" % ( - sq, rfn.nsq, d0, d1)) - beta_centroids_i = neighbors_kmeans( - xb_full[:, d0:d1], rfn, (xb_full.shape[0], rfn.M + 1, sq), - rfn.k, - ngpus=0, niter=niter) - beta_centroids.append(beta_centroids_i) - rfn.ntotal = 0 - rfn.codes.clear() - rfn.codebook.clear() - return np.stack(beta_centroids) diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index 9a67332d67..3325c8c0e1 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -307,7 +307,7 @@ void hnsw_search( FAISS_THROW_IF_NOT_MSG(params, "params type invalid"); efSearch = params->efSearch; } - size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0; + size_t n1 = 0, n2 = 0, ndis = 0; idx_t check_period = InterruptCallback::get_period_hint( hnsw.max_level * index->d * efSearch); @@ -323,7 +323,7 @@ void hnsw_search( std::unique_ptr dis( storage_distance_computer(index->storage)); -#pragma omp for reduction(+ : n1, n2, n3, ndis, nreorder) schedule(guided) +#pragma omp for reduction(+ : n1, n2, ndis) schedule(guided) for (idx_t i = i0; i < i1; i++) { res.begin(i); dis->set_query(x + i * index->d); @@ -331,16 +331,14 @@ void hnsw_search( HNSWStats stats = hnsw.search(*dis, res, vt, params); n1 += stats.n1; n2 += stats.n2; - n3 += stats.n3; ndis += stats.ndis; - nreorder += stats.nreorder; res.end(); } } InterruptCallback::check(); } - hnsw_stats.combine({n1, n2, n3, ndis, nreorder}); + hnsw_stats.combine({n1, n2, ndis}); } } // anonymous namespace @@ -800,7 +798,7 @@ void IndexHNSW2Level::search( IndexHNSW::search(n, x, k, distances, labels); } else { // "mixed" search - size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0; + size_t n1 = 0, n2 = 0, ndis = 0; const IndexIVFPQ* index_ivfpq = dynamic_cast(storage); @@ -832,7 +830,7 @@ void IndexHNSW2Level::search( int candidates_size = hnsw.upper_beam; MinimaxHeap candidates(candidates_size); -#pragma omp for reduction(+ : n1, n2, n3, ndis, nreorder) +#pragma omp for reduction(+ : n1, n2, ndis) for (idx_t i = 0; i < n; i++) { idx_t* idxi = labels + i * k; float* simi = distances + i * k; @@ -877,9 +875,7 @@ void IndexHNSW2Level::search( k); n1 += search_stats.n1; n2 += search_stats.n2; - n3 += search_stats.n3; ndis += search_stats.ndis; - nreorder += search_stats.nreorder; vt.advance(); vt.advance(); @@ -888,7 +884,7 @@ void IndexHNSW2Level::search( } } - hnsw_stats.combine({n1, n2, n3, ndis, nreorder}); + hnsw_stats.combine({n1, n2, ndis}); } } diff --git a/faiss/gpu/GpuIndex.h b/faiss/gpu/GpuIndex.h index 36de98c098..cc10f21589 100644 --- a/faiss/gpu/GpuIndex.h +++ b/faiss/gpu/GpuIndex.h @@ -84,19 +84,14 @@ class GpuIndex : public faiss::Index { /// `x` and `labels` can be resident on the CPU or any GPU; copies are /// performed as needed - void assign( - idx_t n, - const float* x, - idx_t* labels, - // faiss::Index has idx_t for k - idx_t k = 1) const override; + void assign(idx_t n, const float* x, idx_t* labels, idx_t k = 1) + const override; /// `x`, `distances` and `labels` can be resident on the CPU or any /// GPU; copies are performed as needed void search( idx_t n, const float* x, - // faiss::Index has idx_t for k idx_t k, float* distances, idx_t* labels, @@ -107,7 +102,6 @@ class GpuIndex : public faiss::Index { void search_and_reconstruct( idx_t n, const float* x, - // faiss::Index has idx_t for k idx_t k, float* distances, idx_t* labels, diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index a9fb9daf5b..b1324e1211 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -664,7 +664,7 @@ int search_from_candidates( if (candidates.size() == 0) { stats.n2++; } - stats.n3 += ndis; + stats.ndis += ndis; } return nres; @@ -793,7 +793,7 @@ std::priority_queue search_from_candidate_unbounded( if (candidates.size() == 0) { ++stats.n2; } - stats.n3 += ndis; + stats.ndis += ndis; return top_candidates; } diff --git a/faiss/impl/HNSW.h b/faiss/impl/HNSW.h index cb6b422c3d..8261423cdd 100644 --- a/faiss/impl/HNSW.h +++ b/faiss/impl/HNSW.h @@ -230,30 +230,20 @@ struct HNSW { }; struct HNSWStats { - size_t n1, n2, n3; - size_t ndis; - size_t nreorder; - - HNSWStats( - size_t n1 = 0, - size_t n2 = 0, - size_t n3 = 0, - size_t ndis = 0, - size_t nreorder = 0) - : n1(n1), n2(n2), n3(n3), ndis(ndis), nreorder(nreorder) {} + size_t n1 = 0; /// numbner of vectors searched + size_t n2 = + 0; /// number of queries for which the candidate list is exhasted + size_t ndis = 0; /// number of distances computed void reset() { - n1 = n2 = n3 = 0; + n1 = n2 = 0; ndis = 0; - nreorder = 0; } void combine(const HNSWStats& other) { n1 += other.n1; n2 += other.n2; - n3 += other.n3; ndis += other.ndis; - nreorder += other.nreorder; } }; diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py index 914fac3ff1..dd4212d717 100644 --- a/tests/test_graph_based.py +++ b/tests/test_graph_based.py @@ -123,6 +123,16 @@ def test_hnsw_IP(self): mask = Iref[:, 0] == Ihnsw[:, 0] assert np.allclose(Dref[mask, 0], Dhnsw[mask, 0]) + def test_ndis_stats(self): + d = self.xq.shape[1] + + index = faiss.IndexHNSWFlat(d, 16) + index.add(self.xb) + stats = faiss.cvar.hnsw_stats + stats.reset() + Dhnsw, Ihnsw = index.search(self.xq, 1) + self.assertGreater(stats.ndis, len(self.xq) * index.hnsw.efSearch) + class TestNSG(unittest.TestCase): From 798427c019d1596ff720fc5785d5fcacf31a9b7c Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Fri, 22 Mar 2024 14:58:14 -0700 Subject: [PATCH 106/206] Handling FaissException in few destructors of ResultHandler.h (#3311) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3311 **Context** [Issue 2948](https://github.com/facebookresearch/faiss/issues/2948) highlights potential issue of calling allocation on result handler which may throw exception but it is not handled. **In this diff**, I observed two calls where we may potentially call allocation in ResultHandler.h and handled FaissException. 1/ partial result when finalized in ~SingleResultHandler 2/ partial result when merged in ~RangeSearchBlockResultHandler Reviewed By: junjieqi Differential Revision: D55258213 fbshipit-source-id: 259be472e73619b2fcb0ea480d6d3486affeafdf --- faiss/impl/ResultHandler.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/faiss/impl/ResultHandler.h b/faiss/impl/ResultHandler.h index 270de8dcd6..713fe8e49f 100644 --- a/faiss/impl/ResultHandler.h +++ b/faiss/impl/ResultHandler.h @@ -12,8 +12,10 @@ #pragma once #include +#include #include #include +#include namespace faiss { @@ -504,7 +506,15 @@ struct RangeSearchBlockResultHandler : BlockResultHandler { void end() {} ~SingleResultHandler() { - pres.finalize(); + try { + // finalize the partial result + pres.finalize(); + } catch (const faiss::FaissException& e) { + // Do nothing if allocation fails in finalizing partial results. +#ifndef NDEBUG + std::cerr << e.what() << std::endl; +#endif + } } }; @@ -559,8 +569,15 @@ struct RangeSearchBlockResultHandler : BlockResultHandler { } ~RangeSearchBlockResultHandler() { - if (partial_results.size() > 0) { - RangeSearchPartialResult::merge(partial_results); + try { + if (partial_results.size() > 0) { + RangeSearchPartialResult::merge(partial_results); + } + } catch (const faiss::FaissException& e) { + // Do nothing if allocation fails in merge. +#ifndef NDEBUG + std::cerr << e.what() << std::endl; +#endif } } }; From af5793cf128168520564a21c7b4dac9e655cee36 Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Fri, 22 Mar 2024 15:04:01 -0700 Subject: [PATCH 107/206] Adding test for IndexBinaryFlat.reconstruct_n() (#3310) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3310 **Context** [Issue 2751](https://github.com/facebookresearch/faiss/issues/2751) is already fixed as class wrappers has replacement definition of reconstruct_n in handle_IndexBinary. **In this diff**, Writing test test_reconstruct for binary index to validate fix for above issue. Reviewed By: junjieqi Differential Revision: D55168600 fbshipit-source-id: b62dc5fa89d65b843c52faa7456f046142e34421 --- tests/test_index_binary.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_index_binary.py b/tests/test_index_binary.py index 312530ad46..b505e0ba1c 100644 --- a/tests/test_index_binary.py +++ b/tests/test_index_binary.py @@ -143,6 +143,15 @@ def test_range_search(self): # nb tests is actually low... self.assertTrue(nt1 > 19 and nt2 > 19) + def test_reconstruct(self): + index = faiss.IndexBinaryFlat(64) + input_vector = np.random.randint(0, 255, size=(10, index.code_size)).astype("uint8") + index.add(input_vector) + + reconstructed_vector = index.reconstruct_n(0, 4) + assert reconstructed_vector.shape == (4, index.code_size) + assert np.all(input_vector[:4] == reconstructed_vector) + class TestBinaryIVF(unittest.TestCase): From 0c96b0d7e0e399458e7fb0703015f03dbecb614d Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Mon, 25 Mar 2024 04:02:23 -0700 Subject: [PATCH 108/206] enable rapidsai-nightly channel for libraft (#3317) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3317 libraft packages are first published in rapidsai-nightly and moved to rapidsai after release, at which point they're removed from rapidsai-nightly In this diff we enable both channels with a preference to rapidsai (since it's before rapidsai-nightly on the command line). Reviewed By: mlomeli1 Differential Revision: D55310143 fbshipit-source-id: b85e0fda86a442f435d985ace1d7eb37209c74e1 --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 94aad3b11e..289f812526 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -168,7 +168,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c conda-forge + -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge - when: condition: and: @@ -182,7 +182,7 @@ jobs: command: | cd conda conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c conda-forge + --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge build_cmake: parameters: From 14b8af6e736fdfff636584841e61e0161d8ceadd Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Mon, 25 Mar 2024 11:19:40 -0700 Subject: [PATCH 109/206] Fix IVFPQFastScan decode function (#3312) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3312 as the [#issue3258](https://github.com/facebookresearch/faiss/issues/3258) mentioned, the IVFPQFastScan should have same decoding result as IVFPQ. However, current result is not as expected. In this PR/Diff, we are going to fix the decoding function Reviewed By: mdouze Differential Revision: D55264781 fbshipit-source-id: dfdae9eabceadfc5a3ebb851930d71ce3c1c654d --- faiss/IndexIVF.h | 8 +++++ faiss/IndexIVFPQFastScan.cpp | 23 +++++++++++-- tests/test_fast_scan_ivf.py | 63 +++++++++++++++++++++++++++--------- 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/faiss/IndexIVF.h b/faiss/IndexIVF.h index 45c65ef839..185561d086 100644 --- a/faiss/IndexIVF.h +++ b/faiss/IndexIVF.h @@ -433,6 +433,14 @@ struct IndexIVF : Index, IndexIVFInterface { /* The standalone codec interface (except sa_decode that is specific) */ size_t sa_code_size() const override; + + /** encode a set of vectors + * sa_encode will call encode_vector with include_listno=true + * @param n nb of vectors to encode + * @param x the vectors to encode + * @param bytes output array for the codes + * @return nb of bytes written to codes + */ void sa_encode(idx_t n, const float* x, uint8_t* bytes) const override; IndexIVF(); diff --git a/faiss/IndexIVFPQFastScan.cpp b/faiss/IndexIVFPQFastScan.cpp index d069db1354..2844ae4936 100644 --- a/faiss/IndexIVFPQFastScan.cpp +++ b/faiss/IndexIVFPQFastScan.cpp @@ -286,9 +286,28 @@ void IndexIVFPQFastScan::compute_LUT( } } -void IndexIVFPQFastScan::sa_decode(idx_t n, const uint8_t* bytes, float* x) +void IndexIVFPQFastScan::sa_decode(idx_t n, const uint8_t* codes, float* x) const { - pq.decode(bytes, x, n); + size_t coarse_size = coarse_code_size(); + +#pragma omp parallel if (n > 1) + { + std::vector residual(d); + +#pragma omp for + for (idx_t i = 0; i < n; i++) { + const uint8_t* code = codes + i * (code_size + coarse_size); + int64_t list_no = decode_listno(code); + float* xi = x + i * d; + pq.decode(code + coarse_size, xi); + if (by_residual) { + quantizer->reconstruct(list_no, residual.data()); + for (size_t j = 0; j < d; j++) { + xi[j] += residual[j]; + } + } + } + } } } // namespace faiss diff --git a/tests/test_fast_scan_ivf.py b/tests/test_fast_scan_ivf.py index d6dad8fec3..f48dd2e47a 100644 --- a/tests/test_fast_scan_ivf.py +++ b/tests/test_fast_scan_ivf.py @@ -84,9 +84,7 @@ def sp(x): b = btab[0] dis_new = self.compute_dis_quant(codes, LUTq, biasq, a, b) - # print(a, b, dis_ref.sum()) avg_realtive_error = np.abs(dis_new - dis_ref).sum() / dis_ref.sum() - # print('a=', a, 'avg_relative_error=', avg_realtive_error) self.assertLess(avg_realtive_error, 0.0005) def test_no_residual_ip(self): @@ -228,8 +226,6 @@ def eval_quant_loss(self, by_residual, metric=faiss.METRIC_L2): m3 = three_metrics(Da, Ia, Db, Ib) - - # print(by_residual, metric, recall_at_1, recall_at_10, intersection_at_10) ref_results = { (True, 1): [0.985, 1.0, 9.872], (True, 0): [ 0.987, 1.0, 9.914], @@ -261,6 +257,7 @@ class TestEquivPQ(unittest.TestCase): def test_equiv_pq(self): ds = datasets.SyntheticDataset(32, 2000, 200, 4) + xq = ds.get_queries() index = faiss.index_factory(32, "IVF1,PQ16x4np") index.by_residual = False @@ -268,7 +265,7 @@ def test_equiv_pq(self): index.quantizer.add(np.zeros((1, 32), dtype='float32')) index.train(ds.get_train()) index.add(ds.get_database()) - Dref, Iref = index.search(ds.get_queries(), 4) + Dref, Iref = index.search(xq, 4) index_pq = faiss.index_factory(32, "PQ16x4np") index_pq.pq = index.pq @@ -276,21 +273,64 @@ def test_equiv_pq(self): index_pq.codes = faiss. downcast_InvertedLists( index.invlists).codes.at(0) index_pq.ntotal = index.ntotal - Dnew, Inew = index_pq.search(ds.get_queries(), 4) + Dnew, Inew = index_pq.search(xq, 4) np.testing.assert_array_equal(Iref, Inew) np.testing.assert_array_equal(Dref, Dnew) index_pq2 = faiss.IndexPQFastScan(index_pq) index_pq2.implem = 12 - Dref, Iref = index_pq2.search(ds.get_queries(), 4) + Dref, Iref = index_pq2.search(xq, 4) index2 = faiss.IndexIVFPQFastScan(index) index2.implem = 12 - Dnew, Inew = index2.search(ds.get_queries(), 4) + Dnew, Inew = index2.search(xq, 4) np.testing.assert_array_equal(Iref, Inew) np.testing.assert_array_equal(Dref, Dnew) + # test encode and decode + + np.testing.assert_array_equal( + index_pq.sa_encode(xq), + index2.sa_encode(xq) + ) + + np.testing.assert_array_equal( + index_pq.sa_decode(index_pq.sa_encode(xq)), + index2.sa_decode(index2.sa_encode(xq)) + ) + + np.testing.assert_array_equal( + ((index_pq.sa_decode(index_pq.sa_encode(xq)) - xq) ** 2).sum(1), + ((index2.sa_decode(index2.sa_encode(xq)) - xq) ** 2).sum(1) + ) + + def test_equiv_pq_encode_decode(self): + ds = datasets.SyntheticDataset(32, 1000, 200, 10) + xq = ds.get_queries() + + index_ivfpq = faiss.index_factory(ds.d, "IVF10,PQ8x4np") + index_ivfpq.train(ds.get_train()) + + index_ivfpqfs = faiss.IndexIVFPQFastScan(index_ivfpq) + + np.testing.assert_array_equal( + index_ivfpq.sa_encode(xq), + index_ivfpqfs.sa_encode(xq) + ) + + np.testing.assert_array_equal( + index_ivfpq.sa_decode(index_ivfpq.sa_encode(xq)), + index_ivfpqfs.sa_decode(index_ivfpqfs.sa_encode(xq)) + ) + + np.testing.assert_array_equal( + ((index_ivfpq.sa_decode(index_ivfpq.sa_encode(xq)) - xq) ** 2) + .sum(1), + ((index_ivfpqfs.sa_decode(index_ivfpqfs.sa_encode(xq)) - xq) ** 2) + .sum(1) + ) + class TestIVFImplem12(unittest.TestCase): @@ -463,7 +503,6 @@ def do_test(self, by_residual=False, metric=faiss.METRIC_L2, d=32, bbs=32): Dnew, Inew = index2.search(ds.get_queries(), 10) m3 = three_metrics(Dref, Iref, Dnew, Inew) - # print((by_residual, metric, d), ":", m3) ref_m3_tab = { (True, 1, 32): (0.995, 1.0, 9.91), (True, 0, 32): (0.99, 1.0, 9.91), @@ -554,7 +593,6 @@ def subtest_accuracy(self, aq, st, by_residual, implem, metric_type='L2'): recall_ref = (Iref == gt).sum() / nq recall1 = (I1 == gt).sum() / nq - print(aq, st, by_residual, implem, metric_type, recall_ref, recall1) assert abs(recall_ref - recall1) < 0.051 def xx_test_accuracy(self): @@ -599,7 +637,6 @@ def subtest_rescale_accuracy(self, aq, st, by_residual, implem): recall_ref = (Iref == gt).sum() / nq recall1 = (I1 == gt).sum() / nq - print(aq, st, by_residual, implem, recall_ref, recall1) assert abs(recall_ref - recall1) < 0.05 def xx_test_rescale_accuracy(self): @@ -624,7 +661,6 @@ def subtest_from_ivfaq(self, implem): nq = Iref.shape[0] recall_ref = (Iref == gt).sum() / nq recall1 = (I1 == gt).sum() / nq - print(recall_ref, recall1) assert abs(recall_ref - recall1) < 0.02 def test_from_ivfaq(self): @@ -763,7 +799,6 @@ def subtest_accuracy(self, paq): recall_ref = (Iref == gt).sum() / nq recall1 = (I1 == gt).sum() / nq - print(paq, recall_ref, recall1) assert abs(recall_ref - recall1) < 0.05 def test_accuracy_PLSQ(self): @@ -847,7 +882,6 @@ def do_test(self, metric=faiss.METRIC_L2): # find a reasonable radius D, I = index.search(ds.get_queries(), 10) radius = np.median(D[:, -1]) - # print("radius=", radius) lims1, D1, I1 = index.range_search(ds.get_queries(), radius) index2 = faiss.IndexIVFPQFastScan(index) @@ -860,7 +894,6 @@ def do_test(self, metric=faiss.METRIC_L2): for i in range(ds.nq): ref = set(I1[lims1[i]: lims1[i + 1]]) new = set(I2[lims2[i]: lims2[i + 1]]) - print(ref, new) nmiss += len(ref - new) nextra += len(new - ref) From 55dc880c2f813637c5a35cdc7fcae39f30c2c71e Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Wed, 27 Mar 2024 10:53:49 -0700 Subject: [PATCH 110/206] Change cmake to build googletest from source (#3319) Summary: In the https://github.com/facebookresearch/faiss/pull/3278, we to find_package to link to GTest. However, it needs to have googletest to build independently. Not everyone builds their googletest locally first. In this diff, we still try to build googletest from source and combine find_package together. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3319 Test Plan: STEP 1: Install deps ``` conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 ``` STEP2: Compile ``` cmake -B build \ -DBUILD_TESTING=ON \ -DBUILD_SHARED_LIBS=ON \ -DFAISS_ENABLE_GPU=OFF \ -DFAISS_ENABLE_RAFT=OFF \ -DFAISS_OPT_LEVEL=avx2 \ -DFAISS_ENABLE_C_API=ON \ -DPYTHON_EXECUTABLE=$(which python) \ -DCMAKE_BUILD_TYPE=Release \ -DBLA_VENDOR=Intel10_64_dyn \ -DCMAKE_CUDA_FLAGS="-gencode arch=compute_75,code=sm_75" \ . ``` Reviewed By: algoriddle Differential Revision: D55358059 Pulled By: junjieqi fbshipit-source-id: 95ad4a745238b88b438728de64173f99d3d50dbe --- tests/CMakeLists.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0cb8219096..66ec9f74a5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,6 +59,34 @@ if(FAISS_OPT_LEVEL STREQUAL "avx512") target_link_libraries(faiss_test PRIVATE faiss_avx512) endif() +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG 58d77fa8070e8cec2dc1ed015d66b454c8d78850 # release-1.12.1 + OVERRIDE_FIND_PACKAGE) +set(BUILD_GMOCK CACHE BOOL OFF) +set(INSTALL_GTEST CACHE BOOL OFF) +FetchContent_MakeAvailable(googletest) + +if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake + AND NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfig.cmake) + file( + WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake + [=[ +include(CMakeFindDependencyMacro) +find_dependency(googletest) +if(NOT TARGET GTest::GTest) + add_library(GTest::GTest INTERFACE IMPORTED) + target_link_libraries(GTest::GTest INTERFACE GTest::gtest) +endif() +if(NOT TARGET GTest::Main) + add_library(GTest::Main INTERFACE IMPORTED) + target_link_libraries(GTest::Main INTERFACE GTest::gtest_main) +endif() +]=]) +endif() + find_package(OpenMP REQUIRED) find_package(GTest CONFIG REQUIRED) From 03db694aa799fa5f5fc036743dfcaea5e4cc82bb Mon Sep 17 00:00:00 2001 From: Chip-Kerchner Date: Thu, 28 Mar 2024 03:38:02 -0700 Subject: [PATCH 111/206] Fix problems when using 64-bit integers. (#3322) Summary: Fixes problem when compiling OpenBLAS with INTERFACE64=1 (64-bit integers). Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3322 Reviewed By: algoriddle Differential Revision: D55469397 Pulled By: mdouze fbshipit-source-id: 14d916fb074f6ea0f591e0324bb7b8674a624473 --- faiss/CMakeLists.txt | 5 ++++- faiss/impl/LocalSearchQuantizer.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index a890a46f11..33e1849568 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -290,7 +290,10 @@ if(WIN32) target_compile_definitions(faiss_avx512 PRIVATE FAISS_MAIN_LIB) endif() -target_compile_definitions(faiss PRIVATE FINTEGER=int) +string(FIND "${CMAKE_CXX_FLAGS}" "FINTEGER" finteger_idx) +if (${finteger_idx} EQUAL -1) + target_compile_definitions(faiss PRIVATE FINTEGER=int) +endif() target_compile_definitions(faiss_avx2 PRIVATE FINTEGER=int) target_compile_definitions(faiss_avx512 PRIVATE FINTEGER=int) diff --git a/faiss/impl/LocalSearchQuantizer.cpp b/faiss/impl/LocalSearchQuantizer.cpp index 8da989a9a4..943fe32c9d 100644 --- a/faiss/impl/LocalSearchQuantizer.cpp +++ b/faiss/impl/LocalSearchQuantizer.cpp @@ -104,10 +104,10 @@ int dgemm_( namespace { -void fmat_inverse(float* a, int n) { - int info; - int lwork = n * n; - std::vector ipiv(n); +void fmat_inverse(float* a, FINTEGER n) { + FINTEGER info; + FINTEGER lwork = n * n; + std::vector ipiv(n); std::vector workspace(lwork); sgetrf_(&n, &n, a, &n, ipiv.data(), &info); @@ -123,10 +123,10 @@ void dfvec_add(size_t d, const double* a, const float* b, double* c) { } } -void dmat_inverse(double* a, int n) { - int info; - int lwork = n * n; - std::vector ipiv(n); +void dmat_inverse(double* a, FINTEGER n) { + FINTEGER info; + FINTEGER lwork = n * n; + std::vector ipiv(n); std::vector workspace(lwork); dgetrf_(&n, &n, a, &n, ipiv.data(), &info); From d6854136afa3b987defb2c8e8108bad76ebdb949 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Thu, 28 Mar 2024 22:54:51 -0700 Subject: [PATCH 112/206] Fix faiss swig build with version > 4.2.x (#3315) Summary: Currently, faiss can't build with swig version > 4.2.x. As the https://github.com/facebookresearch/faiss/issues/3239 mentioned. Swig removed the support for 32bit https://github.com/swig/swig/commit/9fb3a4939e4ec528f050057d8ccd743a066222ac. So SWIGTYPE_p_unsigned_long_long isn't supported any more. In this diff, we are going to remove the unsupported type from Faiss swig. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3315 Test Plan: STEP 1: create a new conda env ``` conda create --name faiss_swig conda activate faiss_swig ``` STEP 2: install dependecies from conda-forge ``` conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 -c conda-forge ``` STEP 3: CMAKE ``` cmake -B build \ -DBUILD_TESTING=ON \ -DBUILD_SHARED_LIBS=ON \ -DFAISS_ENABLE_GPU=OFF \ -DFAISS_ENABLE_RAFT=OFF \ -DFAISS_OPT_LEVEL=avx512 \ -DFAISS_ENABLE_C_API=ON \ -DPYTHON_EXECUTABLE=$(which python) \ -DCMAKE_BUILD_TYPE=Release \ -DBLA_VENDOR=Intel10_64_dyn \ -DCMAKE_CUDA_FLAGS="-gencode arch=compute_75,code=sm_75" \ . ``` STEP 4: build ``` make -C build -j faiss && make -C build -j swigfaiss ``` Screenshot 2024-03-25 at 12 24 16 AM Reviewed By: algoriddle Differential Revision: D55304004 Pulled By: junjieqi fbshipit-source-id: e958009dc637aa33b0e1a574a16a846a4abb1525 --- .circleci/config.yml | 4 ++-- conda/faiss-gpu-raft/meta.yaml | 2 +- faiss/python/swigfaiss.swig | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 289f812526..549e4a2793 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -224,7 +224,7 @@ jobs: - run: name: Install env using main channel command: | - conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64 + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64 - when: condition: equal: [ "ON", << parameters.raft >> ] @@ -232,7 +232,7 @@ jobs: - run: name: Install env using conda-forge channel command: | - conda install -y -q python=3.11 cmake make swig=4.0.2 mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - when: condition: and: diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 12dfc889b1..c43e7656c3 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -84,7 +84,7 @@ outputs: build: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - - swig =4.0.2 + - swig - cmake >=3.23.1 - make # [not win] host: diff --git a/faiss/python/swigfaiss.swig b/faiss/python/swigfaiss.swig index fb7f50dd2e..0ea93609e3 100644 --- a/faiss/python/swigfaiss.swig +++ b/faiss/python/swigfaiss.swig @@ -1022,14 +1022,14 @@ PyObject *swig_ptr (PyObject *a) return SWIG_NewPointerObj(data, SWIGTYPE_p_bool, 0); } if(PyArray_TYPE(ao) == NPY_UINT64) { -#ifdef SWIGWORDSIZE64 +#if (__SIZEOF_LONG__ == 8) return SWIG_NewPointerObj(data, SWIGTYPE_p_unsigned_long, 0); #else return SWIG_NewPointerObj(data, SWIGTYPE_p_unsigned_long_long, 0); #endif } if(PyArray_TYPE(ao) == NPY_INT64) { -#ifdef SWIGWORDSIZE64 +#if (__SIZEOF_LONG__ == 8) return SWIG_NewPointerObj(data, SWIGTYPE_p_long, 0); #else return SWIG_NewPointerObj(data, SWIGTYPE_p_long_long, 0); From d99f07e91a19bfffee8c482b117ded6699ca82bc Mon Sep 17 00:00:00 2001 From: Alexandr Guzhva Date: Fri, 29 Mar 2024 01:25:24 -0700 Subject: [PATCH 113/206] AVX512 for PQFastScan (#3276) Summary: AVX-512 implementation for PQFastScan for QBS. For local benchmarks on 4th gen Xeon, the QPS is up to 10% higher, mostly for a single query case. But as far as I remember, production cases would show higher performance improvements. * Baseline `benchs/bench_ivf_fastscan_single_query.py` (sift1M): https://gist.github.com/alexanderguzhva/c9cde2cb5e9c7675f429623e6faa9fbf * Candidate `benchs/bench_ivf_fastscan_single_query.py` (sift1M): https://gist.github.com/alexanderguzhva/4e8530073a108f73771d38e55bc45b17 * Baseline `benchs/bench_ivf_fastscan.py` (sift1M): https://gist.github.com/alexanderguzhva/9eb03ed60354d7e76cfa25e676f983ac * Candidate `benchs/bench_ivf_fastscan.py` (sift1M): https://gist.github.com/alexanderguzhva/3cbfeba1364dd445a2bb52455966979e mdouze should I modify `pq4_fast_scan_search_1.cpp` as well? It is somewhat cumbersome to dig through various possible sub-implementations Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3276 Reviewed By: junjieqi Differential Revision: D54943632 Pulled By: mdouze fbshipit-source-id: 3d70066e9779039559b1734c2be99bf439058246 --- faiss/impl/LookupTableScaler.h | 34 ++ faiss/impl/pq4_fast_scan_search_qbs.cpp | 447 ++++++++++++++++++++++++ faiss/impl/simd_result_handlers.h | 2 +- faiss/utils/simdlib.h | 7 +- faiss/utils/simdlib_avx512.h | 296 ++++++++++++++++ 5 files changed, 784 insertions(+), 2 deletions(-) create mode 100644 faiss/utils/simdlib_avx512.h diff --git a/faiss/impl/LookupTableScaler.h b/faiss/impl/LookupTableScaler.h index c553a0f14d..b6438307fb 100644 --- a/faiss/impl/LookupTableScaler.h +++ b/faiss/impl/LookupTableScaler.h @@ -38,6 +38,23 @@ struct DummyScaler { return simd16uint16(0); } +#ifdef __AVX512F__ + inline simd64uint8 lookup(const simd64uint8&, const simd64uint8&) const { + FAISS_THROW_MSG("DummyScaler::lookup should not be called."); + return simd64uint8(0); + } + + inline simd32uint16 scale_lo(const simd64uint8&) const { + FAISS_THROW_MSG("DummyScaler::scale_lo should not be called."); + return simd32uint16(0); + } + + inline simd32uint16 scale_hi(const simd64uint8&) const { + FAISS_THROW_MSG("DummyScaler::scale_hi should not be called."); + return simd32uint16(0); + } +#endif + template inline dist_t scale_one(const dist_t&) const { FAISS_THROW_MSG("DummyScaler::scale_one should not be called."); @@ -67,6 +84,23 @@ struct NormTableScaler { return (simd16uint16(res) >> 8) * scale_simd; } +#ifdef __AVX512F__ + inline simd64uint8 lookup(const simd64uint8& lut, const simd64uint8& c) + const { + return lut.lookup_4_lanes(c); + } + + inline simd32uint16 scale_lo(const simd64uint8& res) const { + auto scale_simd_wide = simd32uint16(scale_simd, scale_simd); + return simd32uint16(res) * scale_simd_wide; + } + + inline simd32uint16 scale_hi(const simd64uint8& res) const { + auto scale_simd_wide = simd32uint16(scale_simd, scale_simd); + return (simd32uint16(res) >> 8) * scale_simd_wide; + } +#endif + // for non-SIMD implem 2, 3, 4 template inline dist_t scale_one(const dist_t& x) const { diff --git a/faiss/impl/pq4_fast_scan_search_qbs.cpp b/faiss/impl/pq4_fast_scan_search_qbs.cpp index d69542c309..bf2ccd1f76 100644 --- a/faiss/impl/pq4_fast_scan_search_qbs.cpp +++ b/faiss/impl/pq4_fast_scan_search_qbs.cpp @@ -31,6 +31,8 @@ namespace { * writes results in a ResultHandler */ +#ifndef __AVX512F__ + template void kernel_accumulate_block( int nsq, @@ -111,6 +113,451 @@ void kernel_accumulate_block( } } +#else + +// a special version for NQ=1. +// Despite the function being large in the text form, it compiles to a very +// compact assembler code. +FAISS_PRAGMA_IMPRECISE_FUNCTION_BEGIN +template +void kernel_accumulate_block_avx512_nq1( + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + ResultHandler& res, + const Scaler& scaler) { + // NQ is kept in order to match the similarity to baseline function + constexpr int NQ = 1; + // distance accumulators. We can accept more for NQ=1 + // layout: accu[q][b]: distance accumulator for vectors 32*b..32*b+15 + simd32uint16 accu[NQ][4]; + // layout: accu[q][b]: distance accumulator for vectors 32*b+16..32*b+31 + simd32uint16 accu1[NQ][4]; + + for (int q = 0; q < NQ; q++) { + for (int b = 0; b < 4; b++) { + accu[q][b].clear(); + accu1[q][b].clear(); + } + } + + // process "nsq - scaler.nscale" part + const int nsq_minus_nscale = nsq - scaler.nscale; + const int nsq_minus_nscale_8 = (nsq_minus_nscale / 8) * 8; + const int nsq_minus_nscale_4 = (nsq_minus_nscale / 4) * 4; + + // process in chunks of 8 + for (int sq = 0; sq < nsq_minus_nscale_8; sq += 8) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 c1(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + simd64uint8 c1hi = simd64uint8(simd32uint16(c1) >> 4) & mask; + simd64uint8 c1lo = c1 & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + { + simd64uint8 res0 = lut.lookup_4_lanes(clo); + simd64uint8 res1 = lut.lookup_4_lanes(chi); + + accu[q][0] += simd32uint16(res0); + accu[q][1] += simd32uint16(res0) >> 8; + + accu[q][2] += simd32uint16(res1); + accu[q][3] += simd32uint16(res1) >> 8; + } + } + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + { + simd64uint8 res0 = lut.lookup_4_lanes(c1lo); + simd64uint8 res1 = lut.lookup_4_lanes(c1hi); + + accu1[q][0] += simd32uint16(res0); + accu1[q][1] += simd32uint16(res0) >> 8; + + accu1[q][2] += simd32uint16(res1); + accu1[q][3] += simd32uint16(res1) >> 8; + } + } + } + + // process leftovers: a single chunk of size 4 + if (nsq_minus_nscale_8 != nsq_minus_nscale_4) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + simd64uint8 res0 = lut.lookup_4_lanes(clo); + simd64uint8 res1 = lut.lookup_4_lanes(chi); + + accu[q][0] += simd32uint16(res0); + accu[q][1] += simd32uint16(res0) >> 8; + + accu[q][2] += simd32uint16(res1); + accu[q][3] += simd32uint16(res1) >> 8; + } + } + + // process leftovers: a single chunk of size 2 + if (nsq_minus_nscale_4 != nsq_minus_nscale) { + // prefetch + simd32uint8 c(codes); + codes += 32; + + simd32uint8 mask(0xf); + // shift op does not exist for int8... + simd32uint8 chi = simd32uint8(simd16uint16(c) >> 4) & mask; + simd32uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 2 quantizers + simd32uint8 lut(LUT); + LUT += 32; + + simd32uint8 res0 = lut.lookup_2_lanes(clo); + simd32uint8 res1 = lut.lookup_2_lanes(chi); + + accu[q][0] += simd32uint16(simd16uint16(res0)); + accu[q][1] += simd32uint16(simd16uint16(res0) >> 8); + + accu[q][2] += simd32uint16(simd16uint16(res1)); + accu[q][3] += simd32uint16(simd16uint16(res1) >> 8); + } + } + + // process "sq" part + const int nscale = scaler.nscale; + const int nscale_8 = (nscale / 8) * 8; + const int nscale_4 = (nscale / 4) * 4; + + // process in chunks of 8 + for (int sq = 0; sq < nscale_8; sq += 8) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 c1(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + simd64uint8 c1hi = simd64uint8(simd32uint16(c1) >> 4) & mask; + simd64uint8 c1lo = c1 & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + { + simd64uint8 res0 = scaler.lookup(lut, clo); + accu[q][0] += scaler.scale_lo(res0); // handle vectors 0..15 + accu[q][1] += scaler.scale_hi(res0); // handle vectors 16..31 + + simd64uint8 res1 = scaler.lookup(lut, chi); + accu[q][2] += scaler.scale_lo(res1); // handle vectors 32..47 + accu[q][3] += scaler.scale_hi(res1); // handle vectors 48..63 + } + } + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + { + simd64uint8 res0 = scaler.lookup(lut, c1lo); + accu1[q][0] += scaler.scale_lo(res0); // handle vectors 0..7 + accu1[q][1] += scaler.scale_hi(res0); // handle vectors 8..15 + + simd64uint8 res1 = scaler.lookup(lut, c1hi); + accu1[q][2] += scaler.scale_lo(res1); // handle vectors 16..23 + accu1[q][3] += scaler.scale_hi(res1); // handle vectors 24..31 + } + } + } + + // process leftovers: a single chunk of size 4 + if (nscale_8 != nscale_4) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd64uint8 lut(LUT); + LUT += 64; + + simd64uint8 res0 = scaler.lookup(lut, clo); + accu[q][0] += scaler.scale_lo(res0); // handle vectors 0..15 + accu[q][1] += scaler.scale_hi(res0); // handle vectors 16..31 + + simd64uint8 res1 = scaler.lookup(lut, chi); + accu[q][2] += scaler.scale_lo(res1); // handle vectors 32..47 + accu[q][3] += scaler.scale_hi(res1); // handle vectors 48..63 + } + } + + // process leftovers: a single chunk of size 2 + if (nscale_4 != nscale) { + // prefetch + simd32uint8 c(codes); + codes += 32; + + simd32uint8 mask(0xf); + // shift op does not exist for int8... + simd32uint8 chi = simd32uint8(simd16uint16(c) >> 4) & mask; + simd32uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 2 quantizers + simd32uint8 lut(LUT); + LUT += 32; + + simd32uint8 res0 = scaler.lookup(lut, clo); + accu[q][0] += + simd32uint16(scaler.scale_lo(res0)); // handle vectors 0..7 + accu[q][1] += + simd32uint16(scaler.scale_hi(res0)); // handle vectors 8..15 + + simd32uint8 res1 = scaler.lookup(lut, chi); + accu[q][2] += simd32uint16( + scaler.scale_lo(res1)); // handle vectors 16..23 + accu[q][3] += simd32uint16( + scaler.scale_hi(res1)); // handle vectors 24..31 + } + } + + for (int q = 0; q < NQ; q++) { + for (int b = 0; b < 4; b++) { + accu[q][b] += accu1[q][b]; + } + } + + for (int q = 0; q < NQ; q++) { + accu[q][0] -= accu[q][1] << 8; + simd16uint16 dis0 = combine4x2(accu[q][0], accu[q][1]); + accu[q][2] -= accu[q][3] << 8; + simd16uint16 dis1 = combine4x2(accu[q][2], accu[q][3]); + res.handle(q, 0, dis0, dis1); + } +} + +// general-purpose case +FAISS_PRAGMA_IMPRECISE_FUNCTION_BEGIN +template +void kernel_accumulate_block_avx512_nqx( + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + ResultHandler& res, + const Scaler& scaler) { + // dummy alloc to keep the windows compiler happy + constexpr int NQA = NQ > 0 ? NQ : 1; + // distance accumulators + // layout: accu[q][b]: distance accumulator for vectors 8*b..8*b+7 + simd32uint16 accu[NQA][4]; + + for (int q = 0; q < NQ; q++) { + for (int b = 0; b < 4; b++) { + accu[q][b].clear(); + } + } + + // process "nsq - scaler.nscale" part + const int nsq_minus_nscale = nsq - scaler.nscale; + const int nsq_minus_nscale_4 = (nsq_minus_nscale / 4) * 4; + + // process in chunks of 8 + for (int sq = 0; sq < nsq_minus_nscale_4; sq += 4) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd32uint8 lut_a(LUT); + simd32uint8 lut_b(LUT + NQ * 32); + + simd64uint8 lut(lut_a, lut_b); + LUT += 32; + + { + simd64uint8 res0 = lut.lookup_4_lanes(clo); + simd64uint8 res1 = lut.lookup_4_lanes(chi); + + accu[q][0] += simd32uint16(res0); + accu[q][1] += simd32uint16(res0) >> 8; + + accu[q][2] += simd32uint16(res1); + accu[q][3] += simd32uint16(res1) >> 8; + } + } + + LUT += NQ * 32; + } + + // process leftovers: a single chunk of size 2 + if (nsq_minus_nscale_4 != nsq_minus_nscale) { + // prefetch + simd32uint8 c(codes); + codes += 32; + + simd32uint8 mask(0xf); + // shift op does not exist for int8... + simd32uint8 chi = simd32uint8(simd16uint16(c) >> 4) & mask; + simd32uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 2 quantizers + simd32uint8 lut(LUT); + LUT += 32; + + simd32uint8 res0 = lut.lookup_2_lanes(clo); + simd32uint8 res1 = lut.lookup_2_lanes(chi); + + accu[q][0] += simd32uint16(simd16uint16(res0)); + accu[q][1] += simd32uint16(simd16uint16(res0) >> 8); + + accu[q][2] += simd32uint16(simd16uint16(res1)); + accu[q][3] += simd32uint16(simd16uint16(res1) >> 8); + } + } + + // process "sq" part + const int nscale = scaler.nscale; + const int nscale_4 = (nscale / 4) * 4; + + // process in chunks of 4 + for (int sq = 0; sq < nscale_4; sq += 4) { + // prefetch + simd64uint8 c(codes); + codes += 64; + + simd64uint8 mask(0xf); + // shift op does not exist for int8... + simd64uint8 chi = simd64uint8(simd32uint16(c) >> 4) & mask; + simd64uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 4 quantizers + simd32uint8 lut_a(LUT); + simd32uint8 lut_b(LUT + NQ * 32); + + simd64uint8 lut(lut_a, lut_b); + LUT += 32; + + { + simd64uint8 res0 = scaler.lookup(lut, clo); + accu[q][0] += scaler.scale_lo(res0); // handle vectors 0..7 + accu[q][1] += scaler.scale_hi(res0); // handle vectors 8..15 + + simd64uint8 res1 = scaler.lookup(lut, chi); + accu[q][2] += scaler.scale_lo(res1); // handle vectors 16..23 + accu[q][3] += scaler.scale_hi(res1); // handle vectors 24..31 + } + } + + LUT += NQ * 32; + } + + // process leftovers: a single chunk of size 2 + if (nscale_4 != nscale) { + // prefetch + simd32uint8 c(codes); + codes += 32; + + simd32uint8 mask(0xf); + // shift op does not exist for int8... + simd32uint8 chi = simd32uint8(simd16uint16(c) >> 4) & mask; + simd32uint8 clo = c & mask; + + for (int q = 0; q < NQ; q++) { + // load LUTs for 2 quantizers + simd32uint8 lut(LUT); + LUT += 32; + + simd32uint8 res0 = scaler.lookup(lut, clo); + accu[q][0] += + simd32uint16(scaler.scale_lo(res0)); // handle vectors 0..7 + accu[q][1] += + simd32uint16(scaler.scale_hi(res0)); // handle vectors 8..15 + + simd32uint8 res1 = scaler.lookup(lut, chi); + accu[q][2] += simd32uint16( + scaler.scale_lo(res1)); // handle vectors 16..23 + accu[q][3] += simd32uint16( + scaler.scale_hi(res1)); // handle vectors 24..31 + } + } + + for (int q = 0; q < NQ; q++) { + accu[q][0] -= accu[q][1] << 8; + simd16uint16 dis0 = combine4x2(accu[q][0], accu[q][1]); + accu[q][2] -= accu[q][3] << 8; + simd16uint16 dis1 = combine4x2(accu[q][2], accu[q][3]); + res.handle(q, 0, dis0, dis1); + } +} + +template +void kernel_accumulate_block( + int nsq, + const uint8_t* codes, + const uint8_t* LUT, + ResultHandler& res, + const Scaler& scaler) { + if constexpr (NQ == 1) { + kernel_accumulate_block_avx512_nq1( + nsq, codes, LUT, res, scaler); + } else { + kernel_accumulate_block_avx512_nqx( + nsq, codes, LUT, res, scaler); + } +} + +#endif + // handle at most 4 blocks of queries template void accumulate_q_4step( diff --git a/faiss/impl/simd_result_handlers.h b/faiss/impl/simd_result_handlers.h index 2d8e5388d9..633d480990 100644 --- a/faiss/impl/simd_result_handlers.h +++ b/faiss/impl/simd_result_handlers.h @@ -505,7 +505,7 @@ struct RangeHandler : ResultHandlerCompare { n_per_query.resize(nq + 1); } - virtual void begin(const float* norms) { + virtual void begin(const float* norms) override { normalizers = norms; for (int q = 0; q < nq; ++q) { thresholds[q] = diff --git a/faiss/utils/simdlib.h b/faiss/utils/simdlib.h index 27e9cc59f5..beeec2374e 100644 --- a/faiss/utils/simdlib.h +++ b/faiss/utils/simdlib.h @@ -14,7 +14,12 @@ * functions. */ -#ifdef __AVX2__ +#if defined(__AVX512F__) + +#include +#include + +#elif defined(__AVX2__) #include diff --git a/faiss/utils/simdlib_avx512.h b/faiss/utils/simdlib_avx512.h new file mode 100644 index 0000000000..9ce0965895 --- /dev/null +++ b/faiss/utils/simdlib_avx512.h @@ -0,0 +1,296 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +#include + +#include + +#include + +namespace faiss { + +/** Simple wrapper around the AVX 512-bit registers + * + * The objective is to separate the different interpretations of the same + * registers (as a vector of uint8, uint16 or uint32), to provide printing + * functions, and to give more readable names to the AVX intrinsics. It does not + * pretend to be exhausitve, functions are added as needed. + */ + +/// 512-bit representation without interpretation as a vector +struct simd512bit { + union { + __m512i i; + __m512 f; + }; + + simd512bit() {} + + explicit simd512bit(__m512i i) : i(i) {} + + explicit simd512bit(__m512 f) : f(f) {} + + explicit simd512bit(const void* x) + : i(_mm512_loadu_si512((__m512i const*)x)) {} + + // sets up a lower half of the register while keeping upper one as zero + explicit simd512bit(simd256bit lo) + : simd512bit(_mm512_inserti32x8( + _mm512_castsi256_si512(lo.i), + _mm256_setzero_si256(), + 1)) {} + + // constructs from lower and upper halves + explicit simd512bit(simd256bit lo, simd256bit hi) + : simd512bit(_mm512_inserti32x8( + _mm512_castsi256_si512(lo.i), + hi.i, + 1)) {} + + void clear() { + i = _mm512_setzero_si512(); + } + + void storeu(void* ptr) const { + _mm512_storeu_si512((__m512i*)ptr, i); + } + + void loadu(const void* ptr) { + i = _mm512_loadu_si512((__m512i*)ptr); + } + + void store(void* ptr) const { + _mm512_storeu_si512((__m512i*)ptr, i); + } + + void bin(char bits[513]) const { + char bytes[64]; + storeu((void*)bytes); + for (int i = 0; i < 512; i++) { + bits[i] = '0' + ((bytes[i / 8] >> (i % 8)) & 1); + } + bits[512] = 0; + } + + std::string bin() const { + char bits[257]; + bin(bits); + return std::string(bits); + } +}; + +/// vector of 32 elements in uint16 +struct simd32uint16 : simd512bit { + simd32uint16() {} + + explicit simd32uint16(__m512i i) : simd512bit(i) {} + + explicit simd32uint16(int x) : simd512bit(_mm512_set1_epi16(x)) {} + + explicit simd32uint16(uint16_t x) : simd512bit(_mm512_set1_epi16(x)) {} + + explicit simd32uint16(simd512bit x) : simd512bit(x) {} + + explicit simd32uint16(const uint16_t* x) : simd512bit((const void*)x) {} + + // sets up a lower half of the register + explicit simd32uint16(simd256bit lo) : simd512bit(lo) {} + + // constructs from lower and upper halves + explicit simd32uint16(simd256bit lo, simd256bit hi) : simd512bit(lo, hi) {} + + std::string elements_to_string(const char* fmt) const { + uint16_t bytes[32]; + storeu((void*)bytes); + char res[2000]; + char* ptr = res; + for (int i = 0; i < 32; i++) { + ptr += sprintf(ptr, fmt, bytes[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } + + std::string hex() const { + return elements_to_string("%02x,"); + } + + std::string dec() const { + return elements_to_string("%3d,"); + } + + void set1(uint16_t x) { + i = _mm512_set1_epi16((short)x); + } + + simd32uint16 operator*(const simd32uint16& other) const { + return simd32uint16(_mm512_mullo_epi16(i, other.i)); + } + + // shift must be known at compile time + simd32uint16 operator>>(const int shift) const { + return simd32uint16(_mm512_srli_epi16(i, shift)); + } + + // shift must be known at compile time + simd32uint16 operator<<(const int shift) const { + return simd32uint16(_mm512_slli_epi16(i, shift)); + } + + simd32uint16 operator+=(simd32uint16 other) { + i = _mm512_add_epi16(i, other.i); + return *this; + } + + simd32uint16 operator-=(simd32uint16 other) { + i = _mm512_sub_epi16(i, other.i); + return *this; + } + + simd32uint16 operator+(simd32uint16 other) const { + return simd32uint16(_mm512_add_epi16(i, other.i)); + } + + simd32uint16 operator-(simd32uint16 other) const { + return simd32uint16(_mm512_sub_epi16(i, other.i)); + } + + simd32uint16 operator&(simd512bit other) const { + return simd32uint16(_mm512_and_si512(i, other.i)); + } + + simd32uint16 operator|(simd512bit other) const { + return simd32uint16(_mm512_or_si512(i, other.i)); + } + + simd32uint16 operator^(simd512bit other) const { + return simd32uint16(_mm512_xor_si512(i, other.i)); + } + + simd32uint16 operator~() const { + return simd32uint16(_mm512_xor_si512(i, _mm512_set1_epi32(-1))); + } + + simd16uint16 low() const { + return simd16uint16(_mm512_castsi512_si256(i)); + } + + simd16uint16 high() const { + return simd16uint16(_mm512_extracti32x8_epi32(i, 1)); + } + + // for debugging only + uint16_t operator[](int i) const { + ALIGNED(64) uint16_t tab[32]; + store(tab); + return tab[i]; + } + + void accu_min(simd32uint16 incoming) { + i = _mm512_min_epu16(i, incoming.i); + } + + void accu_max(simd32uint16 incoming) { + i = _mm512_max_epu16(i, incoming.i); + } +}; + +// decompose in 128-lanes: a = (a0, a1, a2, a3), b = (b0, b1, b2, b3) +// return (a0 + a1 + a2 + a3, b0 + b1 + b2 + b3) +inline simd16uint16 combine4x2(simd32uint16 a, simd32uint16 b) { + return combine2x2(a.low(), b.low()) + combine2x2(a.high(), b.high()); +} + +// vector of 32 unsigned 8-bit integers +struct simd64uint8 : simd512bit { + simd64uint8() {} + + explicit simd64uint8(__m512i i) : simd512bit(i) {} + + explicit simd64uint8(int x) : simd512bit(_mm512_set1_epi8(x)) {} + + explicit simd64uint8(uint8_t x) : simd512bit(_mm512_set1_epi8(x)) {} + + // sets up a lower half of the register + explicit simd64uint8(simd256bit lo) : simd512bit(lo) {} + + // constructs from lower and upper halves + explicit simd64uint8(simd256bit lo, simd256bit hi) : simd512bit(lo, hi) {} + + explicit simd64uint8(simd512bit x) : simd512bit(x) {} + + explicit simd64uint8(const uint8_t* x) : simd512bit((const void*)x) {} + + std::string elements_to_string(const char* fmt) const { + uint8_t bytes[64]; + storeu((void*)bytes); + char res[2000]; + char* ptr = res; + for (int i = 0; i < 64; i++) { + ptr += sprintf(ptr, fmt, bytes[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } + + std::string hex() const { + return elements_to_string("%02x,"); + } + + std::string dec() const { + return elements_to_string("%3d,"); + } + + void set1(uint8_t x) { + i = _mm512_set1_epi8((char)x); + } + + simd64uint8 operator&(simd512bit other) const { + return simd64uint8(_mm512_and_si512(i, other.i)); + } + + simd64uint8 operator+(simd64uint8 other) const { + return simd64uint8(_mm512_add_epi8(i, other.i)); + } + + simd64uint8 lookup_4_lanes(simd64uint8 idx) const { + return simd64uint8(_mm512_shuffle_epi8(i, idx.i)); + } + + // extract + 0-extend lane + // this operation is slow (3 cycles) + simd32uint16 lane0_as_uint16() const { + __m256i x = _mm512_extracti32x8_epi32(i, 0); + return simd32uint16(_mm512_cvtepu8_epi16(x)); + } + + simd32uint16 lane1_as_uint16() const { + __m256i x = _mm512_extracti32x8_epi32(i, 1); + return simd32uint16(_mm512_cvtepu8_epi16(x)); + } + + simd64uint8 operator+=(simd64uint8 other) { + i = _mm512_add_epi8(i, other.i); + return *this; + } + + // for debugging only + uint8_t operator[](int i) const { + ALIGNED(64) uint8_t tab[64]; + store(tab); + return tab[i]; + } +}; + +} // namespace faiss From 4e6b6f8a12c93de33415467d1be649832e05afa6 Mon Sep 17 00:00:00 2001 From: Aalekh Patel Date: Fri, 29 Mar 2024 02:37:19 -0700 Subject: [PATCH 114/206] Add the ability to clone and read binary indexes to the C API. (#3318) Summary: I noticed we have a pretty decent C API for binary indexes and please correct me if I'm wrong but we seem to be missing a couple of functions, like the ability to clone and read binary indexes. This PR provides those functions. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3318 Reviewed By: algoriddle Differential Revision: D55469615 Pulled By: mdouze fbshipit-source-id: 42e6f827d8b5ad6bc3efe989e47ede3aa06c1810 --- c_api/clone_index_c.cpp | 12 ++++++++++++ c_api/clone_index_c.h | 4 ++++ c_api/index_factory_c.cpp | 16 +++++++++++++++- c_api/index_factory_c.h | 11 ++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/c_api/clone_index_c.cpp b/c_api/clone_index_c.cpp index 8211156aaa..606e5f9b0a 100644 --- a/c_api/clone_index_c.cpp +++ b/c_api/clone_index_c.cpp @@ -14,6 +14,7 @@ #include "macros_impl.h" using faiss::Index; +using faiss::IndexBinary; int faiss_clone_index(const FaissIndex* idx, FaissIndex** p_out) { try { @@ -22,3 +23,14 @@ int faiss_clone_index(const FaissIndex* idx, FaissIndex** p_out) { } CATCH_AND_HANDLE } + +int faiss_clone_index_binary( + const FaissIndexBinary* idx, + FaissIndexBinary** p_out) { + try { + auto out = faiss::clone_binary_index( + reinterpret_cast(idx)); + *p_out = reinterpret_cast(out); + } + CATCH_AND_HANDLE +} \ No newline at end of file diff --git a/c_api/clone_index_c.h b/c_api/clone_index_c.h index 3d0bd6745f..d2da35b82f 100644 --- a/c_api/clone_index_c.h +++ b/c_api/clone_index_c.h @@ -13,6 +13,7 @@ #define FAISS_CLONE_INDEX_C_H #include +#include "IndexBinary_c.h" #include "Index_c.h" #include "faiss_c.h" @@ -25,6 +26,9 @@ extern "C" { /** Clone an index. This is equivalent to `faiss::clone_index` */ int faiss_clone_index(const FaissIndex*, FaissIndex** p_out); +/** Clone a binary index. This is equivalent to `faiss::clone_index_binary` */ +int faiss_clone_index_binary(const FaissIndexBinary*, FaissIndexBinary** p_out); + #ifdef __cplusplus } #endif diff --git a/c_api/index_factory_c.cpp b/c_api/index_factory_c.cpp index e9abf141f8..3a1ab9bab9 100644 --- a/c_api/index_factory_c.cpp +++ b/c_api/index_factory_c.cpp @@ -15,7 +15,7 @@ using faiss::Index; -/** Build and index with the sequence of processing steps described in +/** Build an index with the sequence of processing steps described in * the string. */ int faiss_index_factory( @@ -29,3 +29,17 @@ int faiss_index_factory( } CATCH_AND_HANDLE } + +/** Build an index with the sequence of processing steps described in + * the string. + */ +int faiss_index_binary_factory( + FaissIndexBinary** p_index, + int d, + const char* description) { + try { + *p_index = reinterpret_cast( + faiss::index_binary_factory(d, description)); + } + CATCH_AND_HANDLE +} \ No newline at end of file diff --git a/c_api/index_factory_c.h b/c_api/index_factory_c.h index 11fb0faa16..ccd58ac778 100644 --- a/c_api/index_factory_c.h +++ b/c_api/index_factory_c.h @@ -11,6 +11,7 @@ #ifndef FAISS_INDEX_FACTORY_C_H #define FAISS_INDEX_FACTORY_C_H +#include "IndexBinary_c.h" #include "Index_c.h" #include "faiss_c.h" @@ -18,7 +19,7 @@ extern "C" { #endif -/** Build and index with the sequence of processing steps described in +/** Build an index with the sequence of processing steps described in * the string. */ int faiss_index_factory( @@ -27,6 +28,14 @@ int faiss_index_factory( const char* description, FaissMetricType metric); +/** Build a binary index with the sequence of processing steps described in + * the string. + */ +int faiss_index_binary_factory( + FaissIndexBinary** p_index, + int d, + const char* description); + #ifdef __cplusplus } #endif From 77e2e79cd0a680adc343b9840dd865da724c579e Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Fri, 29 Mar 2024 11:43:33 -0700 Subject: [PATCH 115/206] Throw when attempting to move IndexPQ to GPU (#3328) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3328 Reviewed By: junjieqi Differential Revision: D55476917 fbshipit-source-id: e7f64adefa07650fda32ad2300a1b933cedc9c79 --- faiss/gpu/GpuCloner.cpp | 2 ++ faiss/gpu/test/test_index_cpu_to_gpu.py | 29 +++++++++++++++++++++++++ faiss/impl/FaissAssert.h | 7 ++++++ 3 files changed, 38 insertions(+) create mode 100644 faiss/gpu/test/test_index_cpu_to_gpu.py diff --git a/faiss/gpu/GpuCloner.cpp b/faiss/gpu/GpuCloner.cpp index 20583720f3..06ad082272 100644 --- a/faiss/gpu/GpuCloner.cpp +++ b/faiss/gpu/GpuCloner.cpp @@ -224,6 +224,8 @@ faiss::Index* index_cpu_to_gpu( int device, const faiss::Index* index, const GpuClonerOptions* options) { + auto index_pq = dynamic_cast(index); + FAISS_THROW_IF_MSG(index_pq, "This index type is not implemented on GPU."); GpuClonerOptions defaults; ToGpuCloner cl(provider, device, options ? *options : defaults); return cl.clone_Index(index); diff --git a/faiss/gpu/test/test_index_cpu_to_gpu.py b/faiss/gpu/test/test_index_cpu_to_gpu.py new file mode 100644 index 0000000000..84c35e2af7 --- /dev/null +++ b/faiss/gpu/test/test_index_cpu_to_gpu.py @@ -0,0 +1,29 @@ +import numpy as np +import unittest +import faiss + + +class TestMoveToGpu(unittest.TestCase): + def test_index_cpu_to_gpu(self): + dimension = 128 + n = 2500 + db_vectors = np.random.random((n, dimension)).astype('float32') + code_size = 16 + res = faiss.StandardGpuResources() + index_pq = faiss.IndexPQ(dimension, code_size, 6) + index_pq.train(db_vectors) + index_pq.add(db_vectors) + self.assertRaisesRegex(Exception, ".*not implemented.*", + faiss.index_cpu_to_gpu, res, 0, index_pq) + + def test_index_cpu_to_gpu_does_not_throw_with_index_flat(self): + dimension = 128 + n = 100 + db_vectors = np.random.random((n, dimension)).astype('float32') + res = faiss.StandardGpuResources() + index_flat = faiss.IndexFlatL2(dimension) + index_flat.add(db_vectors) + try: + faiss.index_cpu_to_gpu(res, 0, index_flat) + except Exception: + self.fail("index_cpu_to_gpu() threw an unexpected exception.") diff --git a/faiss/impl/FaissAssert.h b/faiss/impl/FaissAssert.h index 6f666f684c..2aea23e6a8 100644 --- a/faiss/impl/FaissAssert.h +++ b/faiss/impl/FaissAssert.h @@ -94,6 +94,13 @@ } \ } while (false) +#define FAISS_THROW_IF_MSG(X, MSG) \ + do { \ + if (X) { \ + FAISS_THROW_FMT("Error: '%s' failed: " MSG, #X); \ + } \ + } while (false) + #define FAISS_THROW_IF_NOT_MSG(X, MSG) \ do { \ if (!(X)) { \ From c9c86f0daafc2d0ccbfa40c2d46779b26102a349 Mon Sep 17 00:00:00 2001 From: Warmchay <1282046785@qq.com> Date: Tue, 2 Apr 2024 06:11:53 -0700 Subject: [PATCH 116/206] Fix missing overload variable in Rocksdb ivf demo (#3326) Summary: **Bugs:** When following rocksdb_ivf demo to build executable file, its output as: ```bash faiss/demos/rocksdb_ivf/RocksDBInvertedLists.h:52:35: error: 'faiss::InvertedListsIterator* faiss_rocksdb::RocksDBInvertedLists::get_iterator(size_t) const' marked 'override', but does not override 52 | faiss::InvertedListsIterator* get_iterator(size_t list_no) const override; | ^~~~~~~~~~~~ make[2]: *** [CMakeFiles/demo_rocksdb_ivf.dir/build.make:90: CMakeFiles/demo_rocksdb_ivf.dir/RocksDBInvertedLists.cpp.o] Error 1 ``` **Solution:** Add relevant variable `void* inverted_list_contex` corresponding `get_iterator`'s base virtual function. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3326 Reviewed By: mlomeli1, mdouze Differential Revision: D55629580 Pulled By: algoriddle fbshipit-source-id: a12fcacb483e0dd576411ad91a3dd1e0de94abec --- demos/rocksdb_ivf/RocksDBInvertedLists.cpp | 3 ++- demos/rocksdb_ivf/RocksDBInvertedLists.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/demos/rocksdb_ivf/RocksDBInvertedLists.cpp b/demos/rocksdb_ivf/RocksDBInvertedLists.cpp index 99c51c1456..8d692f0b54 100644 --- a/demos/rocksdb_ivf/RocksDBInvertedLists.cpp +++ b/demos/rocksdb_ivf/RocksDBInvertedLists.cpp @@ -101,7 +101,8 @@ void RocksDBInvertedLists::resize(size_t /*list_no*/, size_t /*new_size*/) { } InvertedListsIterator* RocksDBInvertedLists::get_iterator( - size_t list_no) const { + size_t list_no, + void* inverted_list_context) const { return new RocksDBInvertedListsIterator(db_.get(), list_no, code_size); } diff --git a/demos/rocksdb_ivf/RocksDBInvertedLists.h b/demos/rocksdb_ivf/RocksDBInvertedLists.h index fdc83d1d27..f9d70a4f97 100644 --- a/demos/rocksdb_ivf/RocksDBInvertedLists.h +++ b/demos/rocksdb_ivf/RocksDBInvertedLists.h @@ -49,7 +49,9 @@ struct RocksDBInvertedLists : faiss::InvertedLists { void resize(size_t list_no, size_t new_size) override; - faiss::InvertedListsIterator* get_iterator(size_t list_no) const override; + faiss::InvertedListsIterator* get_iterator( + size_t list_no, + void* inverted_list_context) const override; private: std::unique_ptr db_; From da9f292a4b1c3382431e06996732e4ea10081b8a Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Wed, 3 Apr 2024 10:36:56 -0700 Subject: [PATCH 117/206] Support of skip_ids in merge_from_multiple function of OnDiskInvertedLists (#3327) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3327 **Context** 1. [Issue 2621](https://github.com/facebookresearch/faiss/issues/2621) discuss inconsistency between OnDiskInvertedList and InvertedList. OnDiskInvertedList is supposed to handle disk based multiple Index Shards. Thus, we should name it differently when merging invls from index shard. 2. [Issue 2876](https://github.com/facebookresearch/faiss/issues/2876) provides usecase of shifting ids when merging invls from different shards. **In this diff**, 1. To address #1 above, I renamed the merge_from function to merge_from_multiple without touching merge_from base class. why so? To continue to allow merge invl from one index to ondiskinvl from other index. 2. To address #2 above, I have added support of shift_ids in merge_from_multiple to shift ids from different shards. This can be used when each shard has same set of ids but different data. This is not recommended if id is already unique across shards. Reviewed By: mdouze Differential Revision: D55482518 fbshipit-source-id: 95470c7449160488d2b45b024d134cbc037a2083 --- contrib/ondisk.py | 4 +- faiss/invlists/OnDiskInvertedLists.cpp | 23 ++++++-- faiss/invlists/OnDiskInvertedLists.h | 3 +- tests/test_contrib.py | 73 +++++++++++++++++++++++--- tests/test_merge.cpp | 28 +++++++++- 5 files changed, 115 insertions(+), 16 deletions(-) diff --git a/contrib/ondisk.py b/contrib/ondisk.py index 26a95f44f5..81ec71941c 100644 --- a/contrib/ondisk.py +++ b/contrib/ondisk.py @@ -11,7 +11,7 @@ def merge_ondisk( - trained_index: faiss.Index, shard_fnames: List[str], ivfdata_fname: str + trained_index: faiss.Index, shard_fnames: List[str], ivfdata_fname: str, shift_ids=False ) -> None: """Add the contents of the indexes stored in shard_fnames into the index trained_index. The on-disk data is stored in ivfdata_fname""" @@ -51,7 +51,7 @@ def merge_ondisk( ivf_vector.push_back(ivf) LOG.info("merge %d inverted lists " % ivf_vector.size()) - ntotal = invlists.merge_from(ivf_vector.data(), ivf_vector.size()) + ntotal = invlists.merge_from_multiple(ivf_vector.data(), ivf_vector.size(), shift_ids) # now replace the inverted lists in the output index index.ntotal = index_ivf.ntotal = ntotal diff --git a/faiss/invlists/OnDiskInvertedLists.cpp b/faiss/invlists/OnDiskInvertedLists.cpp index 3017d164c6..dc17fe67f6 100644 --- a/faiss/invlists/OnDiskInvertedLists.cpp +++ b/faiss/invlists/OnDiskInvertedLists.cpp @@ -565,15 +565,16 @@ void OnDiskInvertedLists::free_slot(size_t offset, size_t capacity) { /***************************************** * Compact form *****************************************/ - -size_t OnDiskInvertedLists::merge_from( +size_t OnDiskInvertedLists::merge_from_multiple( const InvertedLists** ils, int n_il, + bool shift_ids, bool verbose) { FAISS_THROW_IF_NOT_MSG( totsize == 0, "works only on an empty InvertedLists"); std::vector sizes(nlist); + std::vector shift_id_offsets(n_il); for (int i = 0; i < n_il; i++) { const InvertedLists* il = ils[i]; FAISS_THROW_IF_NOT(il->nlist == nlist && il->code_size == code_size); @@ -581,6 +582,10 @@ size_t OnDiskInvertedLists::merge_from( for (size_t j = 0; j < nlist; j++) { sizes[j] += il->list_size(j); } + + size_t il_totsize = il->compute_ntotal(); + shift_id_offsets[i] = + (shift_ids && i > 0) ? shift_id_offsets[i - 1] + il_totsize : 0; } size_t cums = 0; @@ -605,11 +610,21 @@ size_t OnDiskInvertedLists::merge_from( const InvertedLists* il = ils[i]; size_t n_entry = il->list_size(j); l.size += n_entry; + ScopedIds scope_ids(il, j); + const idx_t* scope_ids_data = scope_ids.get(); + std::vector new_ids; + if (shift_ids) { + new_ids.resize(n_entry); + for (size_t k = 0; k < n_entry; k++) { + new_ids[k] = scope_ids[k] + shift_id_offsets[i]; + } + scope_ids_data = new_ids.data(); + } update_entries( j, l.size - n_entry, n_entry, - ScopedIds(il, j).get(), + scope_ids_data, ScopedCodes(il, j).get()); } assert(l.size == l.capacity); @@ -638,7 +653,7 @@ size_t OnDiskInvertedLists::merge_from( size_t OnDiskInvertedLists::merge_from_1( const InvertedLists* ils, bool verbose) { - return merge_from(&ils, 1, verbose); + return merge_from_multiple(&ils, 1, verbose); } void OnDiskInvertedLists::crop_invlists(size_t l0, size_t l1) { diff --git a/faiss/invlists/OnDiskInvertedLists.h b/faiss/invlists/OnDiskInvertedLists.h index 98cb653a7a..01c7f3481e 100644 --- a/faiss/invlists/OnDiskInvertedLists.h +++ b/faiss/invlists/OnDiskInvertedLists.h @@ -101,9 +101,10 @@ struct OnDiskInvertedLists : InvertedLists { // copy all inverted lists into *this, in compact form (without // allocating slots) - size_t merge_from( + size_t merge_from_multiple( const InvertedLists** ils, int n_il, + bool shift_ids = false, bool verbose = false); /// same as merge_from for a single invlist diff --git a/tests/test_contrib.py b/tests/test_contrib.py index 84b90a4e5f..0e7cbbfb03 100644 --- a/tests/test_contrib.py +++ b/tests/test_contrib.py @@ -9,6 +9,7 @@ import platform import os import random +import shutil import tempfile from faiss.contrib import datasets @@ -17,15 +18,13 @@ from faiss.contrib import ivf_tools from faiss.contrib import clustering from faiss.contrib import big_batch_search +from faiss.contrib.ondisk import merge_ondisk from common_faiss_tests import get_dataset_2 -try: - from faiss.contrib.exhaustive_search import \ - knn_ground_truth, knn, range_ground_truth, \ - range_search_max_results, exponential_query_iterator -except: - pass # Submodule import broken in python 2. - +from faiss.contrib.exhaustive_search import \ + knn_ground_truth, knn, range_ground_truth, \ + range_search_max_results, exponential_query_iterator +from contextlib import contextmanager @unittest.skipIf(platform.python_version_tuple()[0] < '3', 'Submodule import broken in python 2.') @@ -674,3 +673,63 @@ def test_code_set(self): np.testing.assert_equal( np.sort(np.unique(codes, axis=0), axis=None), np.sort(codes[inserted], axis=None)) + + +@unittest.skipIf(platform.system() == 'Windows', + 'OnDiskInvertedLists is unsupported on Windows.') +class TestMerge(unittest.TestCase): + @contextmanager + def temp_directory(self): + temp_dir = tempfile.mkdtemp() + try: + yield temp_dir + finally: + shutil.rmtree(temp_dir) + + def do_test_ondisk_merge(self, shift_ids=False): + with self.temp_directory() as tmpdir: + # only train and add index to disk without adding elements. + # this will create empty inverted lists. + ds = datasets.SyntheticDataset(32, 2000, 200, 20) + index = faiss.index_factory(ds.d, "IVF32,Flat") + index.train(ds.get_train()) + faiss.write_index(index, tmpdir + "/trained.index") + + # create 4 shards and add elements to them + ns = 4 # number of shards + + for bno in range(ns): + index = faiss.read_index(tmpdir + "/trained.index") + i0, i1 = int(bno * ds.nb / ns), int((bno + 1) * ds.nb / ns) + if shift_ids: + index.add_with_ids(ds.xb[i0:i1], np.arange(0, ds.nb / ns)) + else: + index.add_with_ids(ds.xb[i0:i1], np.arange(i0, i1)) + faiss.write_index(index, tmpdir + "/block_%d.index" % bno) + + # construct the output index and merge them on disk + index = faiss.read_index(tmpdir + "/trained.index") + block_fnames = [tmpdir + "/block_%d.index" % bno for bno in range(4)] + + merge_ondisk( + index, block_fnames, tmpdir + "/merged_index.ivfdata", shift_ids + ) + faiss.write_index(index, tmpdir + "/populated.index") + + # perform a search from index on disk + index = faiss.read_index(tmpdir + "/populated.index") + index.nprobe = 5 + D, I = index.search(ds.xq, 5) + + # ground-truth + gtI = ds.get_groundtruth(5) + + recall_at_1 = (I[:, :1] == gtI[:, :1]).sum() / float(ds.xq.shape[0]) + self.assertGreaterEqual(recall_at_1, 0.5) + + def test_ondisk_merge(self): + self.do_test_ondisk_merge() + + def test_ondisk_merge_with_shift_ids(self): + # verified that recall is same for test_ondisk_merge and + self.do_test_ondisk_merge(True) diff --git a/tests/test_merge.cpp b/tests/test_merge.cpp index 5a1d08cfba..edbe2a03a6 100644 --- a/tests/test_merge.cpp +++ b/tests/test_merge.cpp @@ -32,6 +32,7 @@ size_t nq = 100; int nindex = 4; int k = 10; int nlist = 40; +int shard_size = nb / nindex; struct CommonData { std::vector database; @@ -100,7 +101,7 @@ int compare_merged( auto il = new faiss::OnDiskInvertedLists( index0->nlist, index0->code_size, filename.c_str()); - il->merge_from(lists.data(), lists.size()); + il->merge_from_multiple(lists.data(), lists.size(), shift_ids); index0->replace_invlists(il, true); index0->ntotal = ntotal; @@ -110,11 +111,14 @@ int compare_merged( nq, cd.queries.data(), k, newD.data(), newI.data()); size_t ndiff = 0; + bool adjust_ids = shift_ids && !standard_merge; for (size_t i = 0; i < k * nq; i++) { - if (refI[i] != newI[i]) { + idx_t new_id = adjust_ids ? refI[i] % shard_size : refI[i]; + if (refI[i] != new_id) { ndiff++; } } + return ndiff; } @@ -220,3 +224,23 @@ TEST(MERGE, merge_flat_ondisk_2) { int ndiff = compare_merged(&index_shards, false, false); EXPECT_GE(0, ndiff); } + +// now use ondisk specific merge and use shift ids +TEST(MERGE, merge_flat_ondisk_3) { + faiss::IndexShards index_shards(d, false, false); + index_shards.own_indices = true; + + std::vector ids; + for (int i = 0; i < nb; ++i) { + int id = i % shard_size; + ids.push_back(id); + } + for (int i = 0; i < nindex; i++) { + index_shards.add_shard( + new faiss::IndexIVFFlat(&cd.quantizer, d, nlist)); + } + EXPECT_TRUE(index_shards.is_trained); + index_shards.add_with_ids(nb, cd.database.data(), ids.data()); + int ndiff = compare_merged(&index_shards, true, false); + EXPECT_GE(0, ndiff); +} From cfc7fe513b92bbe540d7d02664deb55cf2f6238b Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Fri, 5 Apr 2024 14:08:35 -0700 Subject: [PATCH 118/206] Implement reconstruct_n for GPU IVFFlat indexes (#3338) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3338 add reconstruct_n for GPU IVFFlat Reviewed By: mdouze Differential Revision: D55577561 fbshipit-source-id: 47f8b939611e2df7dbcd087129538145f627293c --- faiss/gpu/GpuIndexIVFFlat.cu | 22 ++++++++ faiss/gpu/GpuIndexIVFFlat.h | 2 + faiss/gpu/impl/IVFBase.cu | 4 ++ faiss/gpu/impl/IVFBase.cuh | 13 ++++- faiss/gpu/impl/IVFFlat.cu | 47 +++++++++++++++++ faiss/gpu/impl/IVFFlat.cuh | 2 + faiss/gpu/test/TestGpuIndexIVFFlat.cpp | 65 ++++++++++++++++++++++++ faiss/gpu/test/test_gpu_basics.py | 1 + faiss/gpu/test/test_gpu_index_ivfflat.py | 25 +++++++++ faiss/gpu/test/torch_test_contrib_gpu.py | 36 ++++++++++++- faiss/gpu/utils/DeviceVector.cuh | 2 + 11 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 faiss/gpu/test/test_gpu_index_ivfflat.py diff --git a/faiss/gpu/GpuIndexIVFFlat.cu b/faiss/gpu/GpuIndexIVFFlat.cu index 440b449a50..884b5b0fc0 100644 --- a/faiss/gpu/GpuIndexIVFFlat.cu +++ b/faiss/gpu/GpuIndexIVFFlat.cu @@ -356,5 +356,27 @@ void GpuIndexIVFFlat::setIndex_( } } +void GpuIndexIVFFlat::reconstruct_n(idx_t i0, idx_t ni, float* out) const { + FAISS_ASSERT(index_); + + if (ni == 0) { + // nothing to do + return; + } + + FAISS_THROW_IF_NOT_FMT( + i0 < this->ntotal, + "start index (%zu) out of bounds (ntotal %zu)", + i0, + this->ntotal); + FAISS_THROW_IF_NOT_FMT( + i0 + ni - 1 < this->ntotal, + "max index requested (%zu) out of bounds (ntotal %zu)", + i0 + ni - 1, + this->ntotal); + + index_->reconstruct_n(i0, ni, out); +} + } // namespace gpu } // namespace faiss diff --git a/faiss/gpu/GpuIndexIVFFlat.h b/faiss/gpu/GpuIndexIVFFlat.h index 678bf8e7f4..1401e2b291 100644 --- a/faiss/gpu/GpuIndexIVFFlat.h +++ b/faiss/gpu/GpuIndexIVFFlat.h @@ -87,6 +87,8 @@ class GpuIndexIVFFlat : public GpuIndexIVF { /// Trains the coarse quantizer based on the given vector data void train(idx_t n, const float* x) override; + void reconstruct_n(idx_t i0, idx_t n, float* out) const override; + protected: /// Initialize appropriate index void setIndex_( diff --git a/faiss/gpu/impl/IVFBase.cu b/faiss/gpu/impl/IVFBase.cu index 890d489440..3b373b8280 100644 --- a/faiss/gpu/impl/IVFBase.cu +++ b/faiss/gpu/impl/IVFBase.cu @@ -340,6 +340,10 @@ void IVFBase::copyInvertedListsTo(InvertedLists* ivf) { } } +void IVFBase::reconstruct_n(idx_t i0, idx_t n, float* out) { + FAISS_THROW_MSG("not implemented"); +} + void IVFBase::addEncodedVectorsToList_( idx_t listId, const void* codes, diff --git a/faiss/gpu/impl/IVFBase.cuh b/faiss/gpu/impl/IVFBase.cuh index 6b1f2ac394..04af9a906e 100644 --- a/faiss/gpu/impl/IVFBase.cuh +++ b/faiss/gpu/impl/IVFBase.cuh @@ -109,9 +109,18 @@ class IVFBase { Tensor& outIndices, bool storePairs) = 0; + /* It is used to reconstruct a given number of vectors in an Inverted File + * (IVF) index + * @param i0 index of the first vector to reconstruct + * @param n number of vectors to reconstruct + * @param out This is a pointer to a buffer where the reconstructed + * vectors will be stored. + */ + virtual void reconstruct_n(idx_t i0, idx_t n, float* out); + protected: - /// Adds a set of codes and indices to a list, with the representation - /// coming from the CPU equivalent + /// Adds a set of codes and indices to a list, with the + /// representation coming from the CPU equivalent virtual void addEncodedVectorsToList_( idx_t listId, // resident on the host diff --git a/faiss/gpu/impl/IVFFlat.cu b/faiss/gpu/impl/IVFFlat.cu index 4607e49870..e0ecfd82cf 100644 --- a/faiss/gpu/impl/IVFFlat.cu +++ b/faiss/gpu/impl/IVFFlat.cu @@ -283,6 +283,53 @@ void IVFFlat::searchPreassigned( storePairs); } +void IVFFlat::reconstruct_n(idx_t i0, idx_t ni, float* out) { + if (ni == 0) { + // nothing to do + return; + } + + auto stream = resources_->getDefaultStreamCurrentDevice(); + + for (idx_t list_no = 0; list_no < numLists_; list_no++) { + size_t list_size = deviceListData_[list_no]->numVecs; + + auto idlist = getListIndices(list_no); + + for (idx_t offset = 0; offset < list_size; offset++) { + idx_t id = idlist[offset]; + if (!(id >= i0 && id < i0 + ni)) { + continue; + } + + // vector data in the non-interleaved format is laid out like: + // v0d0 v0d1 ... v0d(dim-1) v1d0 v1d1 ... v1d(dim-1) + + // vector data in the interleaved format is laid out like: + // (v0d0 v1d0 ... v31d0) (v0d1 v1d1 ... v31d1) + // (v0d(dim - 1) ... v31d(dim-1)) + // (v32d0 v33d0 ... v63d0) (... v63d(dim-1)) (v64d0 ...) + + // where vectors are chunked into groups of 32, and each dimension + // for each of the 32 vectors is contiguous + + auto vectorChunk = offset / 32; + auto vectorWithinChunk = offset % 32; + + auto listDataPtr = (float*)deviceListData_[list_no]->data.data(); + listDataPtr += vectorChunk * 32 * dim_ + vectorWithinChunk; + + for (int d = 0; d < dim_; ++d) { + fromDevice( + listDataPtr + 32 * d, + out + (id - i0) * dim_ + d, + 1, + stream); + } + } + } +} + void IVFFlat::searchImpl_( Tensor& queries, Tensor& coarseDistances, diff --git a/faiss/gpu/impl/IVFFlat.cuh b/faiss/gpu/impl/IVFFlat.cuh index 246fc18b16..889b510795 100644 --- a/faiss/gpu/impl/IVFFlat.cuh +++ b/faiss/gpu/impl/IVFFlat.cuh @@ -51,6 +51,8 @@ class IVFFlat : public IVFBase { Tensor& outIndices, bool storePairs) override; + void reconstruct_n(idx_t i0, idx_t n, float* out) override; + protected: /// Returns the number of bytes in which an IVF list containing numVecs /// vectors is encoded on the device. Note that due to padding this is not diff --git a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp index 6e423e582e..28eefec308 100644 --- a/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +++ b/faiss/gpu/test/TestGpuIndexIVFFlat.cpp @@ -842,6 +842,71 @@ TEST(TestGpuIndexIVFFlat, LongIVFList) { #endif } +TEST(TestGpuIndexIVFFlat, Reconstruct_n) { + Options opt; + + std::vector trainVecs = faiss::gpu::randVecs(opt.numTrain, opt.dim); + std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); + + faiss::IndexFlatL2 cpuQuantizer(opt.dim); + faiss::IndexIVFFlat cpuIndex( + &cpuQuantizer, opt.dim, opt.numCentroids, faiss::METRIC_L2); + cpuIndex.nprobe = opt.nprobe; + cpuIndex.train(opt.numTrain, trainVecs.data()); + cpuIndex.add(opt.numAdd, addVecs.data()); + + faiss::gpu::StandardGpuResources res; + res.noTempMemory(); + + faiss::gpu::GpuIndexIVFFlatConfig config; + config.device = opt.device; + config.indicesOptions = faiss::gpu::INDICES_64_BIT; + config.use_raft = false; + + faiss::gpu::GpuIndexIVFFlat gpuIndex( + &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); + gpuIndex.nprobe = opt.nprobe; + + gpuIndex.train(opt.numTrain, trainVecs.data()); + gpuIndex.add(opt.numAdd, addVecs.data()); + + std::vector gpuVals(opt.numAdd * opt.dim); + + gpuIndex.reconstruct_n(0, gpuIndex.ntotal, gpuVals.data()); + + std::vector cpuVals(opt.numAdd * opt.dim); + + cpuIndex.reconstruct_n(0, cpuIndex.ntotal, cpuVals.data()); + + EXPECT_EQ(gpuVals, cpuVals); + + config.indicesOptions = faiss::gpu::INDICES_32_BIT; + + faiss::gpu::GpuIndexIVFFlat gpuIndex1( + &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); + gpuIndex1.nprobe = opt.nprobe; + + gpuIndex1.train(opt.numTrain, trainVecs.data()); + gpuIndex1.add(opt.numAdd, addVecs.data()); + + gpuIndex1.reconstruct_n(0, gpuIndex1.ntotal, gpuVals.data()); + + EXPECT_EQ(gpuVals, cpuVals); + + config.indicesOptions = faiss::gpu::INDICES_CPU; + + faiss::gpu::GpuIndexIVFFlat gpuIndex2( + &res, opt.dim, opt.numCentroids, faiss::METRIC_L2, config); + gpuIndex2.nprobe = opt.nprobe; + + gpuIndex2.train(opt.numTrain, trainVecs.data()); + gpuIndex2.add(opt.numAdd, addVecs.data()); + + gpuIndex2.reconstruct_n(0, gpuIndex2.ntotal, gpuVals.data()); + + EXPECT_EQ(gpuVals, cpuVals); +} + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); diff --git a/faiss/gpu/test/test_gpu_basics.py b/faiss/gpu/test/test_gpu_basics.py index f3f0a525d4..4b4024d236 100755 --- a/faiss/gpu/test/test_gpu_basics.py +++ b/faiss/gpu/test/test_gpu_basics.py @@ -11,6 +11,7 @@ import random from common_faiss_tests import get_dataset_2 + class ReferencedObject(unittest.TestCase): d = 16 diff --git a/faiss/gpu/test/test_gpu_index_ivfflat.py b/faiss/gpu/test/test_gpu_index_ivfflat.py new file mode 100644 index 0000000000..099615aff5 --- /dev/null +++ b/faiss/gpu/test/test_gpu_index_ivfflat.py @@ -0,0 +1,25 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import unittest + +import faiss +import numpy as np + + +class TestGpuIndexIvfflat(unittest.TestCase): + def test_reconstruct_n(self): + index = faiss.index_factory(4, "IVF10,Flat") + x = np.random.RandomState(123).rand(10, 4).astype('float32') + index.train(x) + index.add(x) + res = faiss.StandardGpuResources() + res.noTempMemory() + config = faiss.GpuIndexIVFFlatConfig() + config.use_raft = False + index2 = faiss.GpuIndexIVFFlat(res, index, config) + recons = index2.reconstruct_n(0, 10) + + np.testing.assert_array_equal(recons, x) diff --git a/faiss/gpu/test/torch_test_contrib_gpu.py b/faiss/gpu/test/torch_test_contrib_gpu.py index 1510b10f1d..0c949c29f2 100644 --- a/faiss/gpu/test/torch_test_contrib_gpu.py +++ b/faiss/gpu/test/torch_test_contrib_gpu.py @@ -108,7 +108,7 @@ def test_train_add_with_ids(self): self.assertTrue(np.array_equal(I.reshape(10), ids_np[10:20])) # tests reconstruct, reconstruct_n - def test_reconstruct(self): + def test_flat_reconstruct(self): d = 32 res = faiss.StandardGpuResources() res.noTempMemory() @@ -157,6 +157,40 @@ def test_reconstruct(self): index.reconstruct_n(50, 10, y) self.assertTrue(torch.equal(xb[50:60], y)) + def test_ivfflat_reconstruct(self): + d = 32 + nlist = 5 + res = faiss.StandardGpuResources() + res.noTempMemory() + config = faiss.GpuIndexIVFFlatConfig() + config.use_raft = False + + index = faiss.GpuIndexIVFFlat(res, d, nlist, faiss.METRIC_L2, config) + + xb = torch.rand(100, d, device=torch.device('cuda', 0), dtype=torch.float32) + index.train(xb) + index.add(xb) + + # Test reconstruct_n with torch gpu (native return) + y = index.reconstruct_n(10, 10) + self.assertTrue(y.is_cuda) + self.assertTrue(torch.equal(xb[10:20], y)) + + # Test reconstruct with numpy output provided + y = np.empty((10, d), dtype='float32') + index.reconstruct_n(20, 10, y) + self.assertTrue(np.array_equal(xb.cpu().numpy()[20:30], y)) + + # Test reconstruct_n with torch cpu output provided + y = torch.empty(10, d, dtype=torch.float32) + index.reconstruct_n(40, 10, y) + self.assertTrue(torch.equal(xb[40:50].cpu(), y)) + + # Test reconstruct_n with torch gpu output provided + y = torch.empty(10, d, device=torch.device('cuda', 0), dtype=torch.float32) + index.reconstruct_n(50, 10, y) + self.assertTrue(torch.equal(xb[50:60], y)) + # tests assign def test_assign(self): d = 32 diff --git a/faiss/gpu/utils/DeviceVector.cuh b/faiss/gpu/utils/DeviceVector.cuh index 0517d06c32..51cb7c8d37 100644 --- a/faiss/gpu/utils/DeviceVector.cuh +++ b/faiss/gpu/utils/DeviceVector.cuh @@ -169,6 +169,8 @@ class DeviceVector { T out; CUDA_VERIFY(cudaMemcpyAsync( &out, data() + idx, sizeof(T), cudaMemcpyDeviceToHost, stream)); + + return out; } // Clean up after oversized allocations, while leaving some space to From f34588aae79f558a6b590f7464a98ba8a2cb1e28 Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Fri, 5 Apr 2024 15:54:23 -0700 Subject: [PATCH 119/206] Support for Remove ids from IVFPQFastScan index (#3349) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3349 **Context** [Issue 3128](https://github.com/facebookresearch/faiss/issues/3128) is an enhancement request to support remove_ids for IVFPQFastScan. Existing mechanism use direct map and iterate over items in selector and use scopecodes and scopeIds to replace item to be removed. Given that codes are packed, it is hard to return single code how it is packed in CodePackerPQ4. Thus, we need a custom implementation to removed_ids. **In this diff**, 1. We have added custom implementation of remove_ids from BlockInvertedLists which unpack code as it iterate and repack in new position. DirectMap use this remove_id function in BlockInvertedLists for type NoMap in DirectMap. 2. Also, we are throwing exception for other map type in DirectMap i.e. HashTable Reviewed By: mdouze Differential Revision: D55723390 fbshipit-source-id: 0017b556bd790765251e778ac48ed37ff3a29a45 --- faiss/invlists/BlockInvertedLists.cpp | 34 ++++++++++++++---- faiss/invlists/BlockInvertedLists.h | 3 ++ faiss/invlists/DirectMap.cpp | 10 +++++- tests/test_merge_index.py | 50 ++++++++++++++++++++------- 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/faiss/invlists/BlockInvertedLists.cpp b/faiss/invlists/BlockInvertedLists.cpp index 6370d11871..dbdb0302dc 100644 --- a/faiss/invlists/BlockInvertedLists.cpp +++ b/faiss/invlists/BlockInvertedLists.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -54,7 +55,9 @@ size_t BlockInvertedLists::add_entries( codes[list_no].resize(n_block * block_size); if (o % block_size == 0) { // copy whole blocks - memcpy(&codes[list_no][o * code_size], code, n_block * block_size); + memcpy(&codes[list_no][o * packer->code_size], + code, + n_block * block_size); } else { FAISS_THROW_IF_NOT_MSG(packer, "missing code packer"); std::vector buffer(packer->code_size); @@ -76,6 +79,29 @@ const uint8_t* BlockInvertedLists::get_codes(size_t list_no) const { return codes[list_no].get(); } +size_t BlockInvertedLists::remove_ids(const IDSelector& sel) { + idx_t nremove = 0; +#pragma omp parallel for + for (idx_t i = 0; i < nlist; i++) { + std::vector buffer(packer->code_size); + idx_t l = ids[i].size(), j = 0; + while (j < l) { + if (sel.is_member(ids[i][j])) { + l--; + ids[i][j] = ids[i][l]; + packer->unpack_1(codes[i].data(), l, buffer.data()); + packer->pack_1(buffer.data(), j, codes[i].data()); + } else { + j++; + } + } + resize(i, l); + nremove += ids[i].size() - l; + } + + return nremove; +} + const idx_t* BlockInvertedLists::get_ids(size_t list_no) const { assert(list_no < nlist); return ids[list_no].data(); @@ -102,12 +128,6 @@ void BlockInvertedLists::update_entries( const idx_t*, const uint8_t*) { FAISS_THROW_MSG("not impemented"); - /* - assert (list_no < nlist); - assert (n_entry + offset <= ids[list_no].size()); - memcpy (&ids[list_no][offset], ids_in, sizeof(ids_in[0]) * n_entry); - memcpy (&codes[list_no][offset * code_size], codes_in, code_size * n_entry); - */ } BlockInvertedLists::~BlockInvertedLists() { diff --git a/faiss/invlists/BlockInvertedLists.h b/faiss/invlists/BlockInvertedLists.h index 8d8df720bf..2b9cbba455 100644 --- a/faiss/invlists/BlockInvertedLists.h +++ b/faiss/invlists/BlockInvertedLists.h @@ -15,6 +15,7 @@ namespace faiss { struct CodePacker; +struct IDSelector; /** Inverted Lists that are organized by blocks. * @@ -47,6 +48,8 @@ struct BlockInvertedLists : InvertedLists { size_t list_size(size_t list_no) const override; const uint8_t* get_codes(size_t list_no) const override; const idx_t* get_ids(size_t list_no) const override; + /// remove ids from the InvertedLists + size_t remove_ids(const IDSelector& sel); // works only on empty BlockInvertedLists // the codes should be of size ceil(n_entry / n_per_block) * block_size diff --git a/faiss/invlists/DirectMap.cpp b/faiss/invlists/DirectMap.cpp index 2b272922d5..dc2b92aa1c 100644 --- a/faiss/invlists/DirectMap.cpp +++ b/faiss/invlists/DirectMap.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace faiss { @@ -148,8 +149,12 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { std::vector toremove(nlist); size_t nremove = 0; - + BlockInvertedLists* block_invlists = + dynamic_cast(invlists); if (type == NoMap) { + if (block_invlists != nullptr) { + return block_invlists->remove_ids(sel); + } // exhaustive scan of IVF #pragma omp parallel for for (idx_t i = 0; i < nlist; i++) { @@ -178,6 +183,9 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { } } } else if (type == Hashtable) { + FAISS_THROW_IF_MSG( + block_invlists, + "remove with hashtable is not supported with BlockInvertedLists"); const IDSelectorArray* sela = dynamic_cast(&sel); FAISS_THROW_IF_NOT_MSG( diff --git a/tests/test_merge_index.py b/tests/test_merge_index.py index 8c4c1f0912..4417f57fe7 100644 --- a/tests/test_merge_index.py +++ b/tests/test_merge_index.py @@ -246,19 +246,45 @@ def test_merge_IDMap2(self): class TestRemoveFastScan(unittest.TestCase): - def do_fast_scan_test(self, factory_key, size1): + def do_fast_scan_test(self, + factory_key, + with_ids=False, + direct_map_type=faiss.DirectMap.NoMap): ds = SyntheticDataset(110, 1000, 1000, 100) - index1 = faiss.index_factory(ds.d, factory_key) - index1.train(ds.get_train()) - index1.reset() + index = faiss.index_factory(ds.d, factory_key) + index.train(ds.get_train()) + + index.reset() tokeep = [i % 3 == 0 for i in range(ds.nb)] - index1.add(ds.get_database()[tokeep]) - _, Iref = index1.search(ds.get_queries(), 5) - index1.reset() - index1.add(ds.get_database()) - index1.remove_ids(np.where(np.logical_not(tokeep))[0]) - _, Inew = index1.search(ds.get_queries(), 5) + if with_ids: + index.add_with_ids(ds.get_database()[tokeep], np.arange(ds.nb)[tokeep]) + faiss.extract_index_ivf(index).nprobe = 5 + else: + index.add(ds.get_database()[tokeep]) + _, Iref = index.search(ds.get_queries(), 5) + + index.reset() + if with_ids: + index.add_with_ids(ds.get_database(), np.arange(ds.nb)) + index.set_direct_map_type(direct_map_type) + faiss.extract_index_ivf(index).nprobe = 5 + else: + index.add(ds.get_database()) + index.remove_ids(np.where(np.logical_not(tokeep))[0]) + _, Inew = index.search(ds.get_queries(), 5) np.testing.assert_array_equal(Inew, Iref) - def test_remove(self): - self.do_fast_scan_test("PQ5x4fs", 320) + def test_remove_PQFastScan(self): + # with_ids is not support for this type of index + self.do_fast_scan_test("PQ5x4fs", False) + + def test_remove_IVFPQFastScan(self): + self.do_fast_scan_test("IVF20,PQ5x4fs", True) + + def test_remove_IVFPQFastScan_2(self): + self.assertRaisesRegex(Exception, + ".*not supported.*", + self.do_fast_scan_test, + "IVF20,PQ5x4fs", + True, + faiss.DirectMap.Hashtable) From 7657e812c45f21cb4da78b110b6a21c67f522a4e Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Fri, 5 Apr 2024 18:13:03 -0700 Subject: [PATCH 120/206] Change index_cpu_to_gpu to throw for indices not implemented on GPU (#3336) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3336 Issues: https://github.com/facebookresearch/faiss/issues/3269 https://github.com/facebookresearch/faiss/issues/3024 List of implemented GPU indices: https://github.com/facebookresearch/faiss/wiki/Faiss-on-the-GPU#implemented-indexes Reviewed By: mdouze Differential Revision: D55577576 fbshipit-source-id: 49f490cfba6784661e378acf4de3cce4195bb43b --- CHANGELOG.md | 2 + faiss/gpu/GpuCloner.cpp | 13 +++- faiss/gpu/GpuClonerOptions.h | 6 ++ faiss/gpu/GpuIndexIVF.cu | 28 ++++++- faiss/gpu/GpuIndexIVF.h | 6 ++ faiss/gpu/test/test_gpu_index.py | 5 +- faiss/gpu/test/test_index_cpu_to_gpu.py | 98 ++++++++++++++++++++----- faiss/impl/FaissAssert.h | 7 -- 8 files changed, 130 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e61bd997ca..8d289ec2f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ We try to indicate most contributions here with the contributor names who are no the Facebook Faiss team. Feel free to add entries here if you submit a PR. ## [Unreleased] +### Changed +- Previously, when moving indices to GPU with coarse quantizers that were not implemented on GPU, the cloner would silently fallback to CPU. This version will now throw an exception instead and the calling code would need to explicitly allow fallback to CPU by setting a flag in cloner config. ## [1.8.0] - 2024-02-27 ### Added diff --git a/faiss/gpu/GpuCloner.cpp b/faiss/gpu/GpuCloner.cpp index 06ad082272..8f895ac9c7 100644 --- a/faiss/gpu/GpuCloner.cpp +++ b/faiss/gpu/GpuCloner.cpp @@ -153,6 +153,7 @@ Index* ToGpuCloner::clone_Index(const Index* index) { config.indicesOptions = indicesOptions; config.flatConfig.useFloat16 = useFloat16CoarseQuantizer; config.use_raft = use_raft; + config.allowCpuCoarseQuantizer = allowCpuCoarseQuantizer; GpuIndexIVFFlat* res = new GpuIndexIVFFlat( provider, ifl->d, ifl->nlist, ifl->metric_type, config); @@ -205,6 +206,7 @@ Index* ToGpuCloner::clone_Index(const Index* index) { config.usePrecomputedTables = usePrecomputed; config.use_raft = use_raft; config.interleavedLayout = use_raft; + config.allowCpuCoarseQuantizer = allowCpuCoarseQuantizer; GpuIndexIVFPQ* res = new GpuIndexIVFPQ(provider, ipq, config); @@ -214,8 +216,13 @@ Index* ToGpuCloner::clone_Index(const Index* index) { return res; } else { - // default: use CPU cloner - return Cloner::clone_Index(index); + // use CPU cloner for IDMap and PreTransform + auto index_idmap = dynamic_cast(index); + auto index_pt = dynamic_cast(index); + if (index_idmap || index_pt) { + return Cloner::clone_Index(index); + } + FAISS_THROW_MSG("This index type is not implemented on GPU."); } } @@ -224,8 +231,6 @@ faiss::Index* index_cpu_to_gpu( int device, const faiss::Index* index, const GpuClonerOptions* options) { - auto index_pq = dynamic_cast(index); - FAISS_THROW_IF_MSG(index_pq, "This index type is not implemented on GPU."); GpuClonerOptions defaults; ToGpuCloner cl(provider, device, options ? *options : defaults); return cl.clone_Index(index); diff --git a/faiss/gpu/GpuClonerOptions.h b/faiss/gpu/GpuClonerOptions.h index 197e09dc88..e643e848fb 100644 --- a/faiss/gpu/GpuClonerOptions.h +++ b/faiss/gpu/GpuClonerOptions.h @@ -43,6 +43,12 @@ struct GpuClonerOptions { #else bool use_raft = false; #endif + + /// This flag controls the CPU fallback logic for coarse quantizer + /// component of the index. When set to false (default), the cloner will + /// throw an exception for indices not implemented on GPU. When set to + /// true, it will fallback to a CPU implementation. + bool allowCpuCoarseQuantizer = false; }; struct GpuMultipleClonerOptions : public GpuClonerOptions { diff --git a/faiss/gpu/GpuIndexIVF.cu b/faiss/gpu/GpuIndexIVF.cu index 0c5b8db686..40129a54c5 100644 --- a/faiss/gpu/GpuIndexIVF.cu +++ b/faiss/gpu/GpuIndexIVF.cu @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -172,10 +173,29 @@ void GpuIndexIVF::copyFrom(const faiss::IndexIVF* index) { // over to the GPU, on the same device that we are on. GpuResourcesProviderFromInstance pfi(getResources()); - GpuClonerOptions options; - auto cloner = ToGpuCloner(&pfi, getDevice(), options); - - quantizer = cloner.clone_Index(index->quantizer); + // Attempt to clone the index to GPU. If it fails because the coarse + // quantizer is not implemented on GPU and the flag to allow CPU + // fallback is set, retry it with CPU cloner and re-throw errors. + try { + GpuClonerOptions options; + auto cloner = ToGpuCloner(&pfi, getDevice(), options); + quantizer = cloner.clone_Index(index->quantizer); + } catch (const std::exception& e) { + if (strstr(e.what(), "not implemented on GPU")) { + if (ivfConfig_.allowCpuCoarseQuantizer) { + Cloner cpuCloner; + quantizer = cpuCloner.clone_Index(index->quantizer); + } else { + FAISS_THROW_MSG( + "This index type is not implemented on " + "GPU and allowCpuCoarseQuantizer is set to false. " + "Please set the flag to true to allow the CPU " + "fallback in cloning."); + } + } else { + throw; + } + } own_fields = true; } else { // Otherwise, this is a GPU coarse quantizer index instance found in a diff --git a/faiss/gpu/GpuIndexIVF.h b/faiss/gpu/GpuIndexIVF.h index a9f092d35b..65a27aa94e 100644 --- a/faiss/gpu/GpuIndexIVF.h +++ b/faiss/gpu/GpuIndexIVF.h @@ -26,6 +26,12 @@ struct GpuIndexIVFConfig : public GpuIndexConfig { /// Configuration for the coarse quantizer object GpuIndexFlatConfig flatConfig; + + /// This flag controls the CPU fallback logic for coarse quantizer + /// component of the index. When set to false (default), the cloner will + /// throw an exception for indices not implemented on GPU. When set to + /// true, it will fallback to a CPU implementation. + bool allowCpuCoarseQuantizer = false; }; /// Base class of all GPU IVF index types. This (for now) deliberately does not diff --git a/faiss/gpu/test/test_gpu_index.py b/faiss/gpu/test/test_gpu_index.py index 620bfea198..28572ebcb4 100755 --- a/faiss/gpu/test/test_gpu_index.py +++ b/faiss/gpu/test/test_gpu_index.py @@ -589,7 +589,10 @@ class TestGpuAutoTune(unittest.TestCase): def test_params(self): index = faiss.index_factory(32, "IVF65536_HNSW,PQ16") - index = faiss.index_cpu_to_gpu(faiss.StandardGpuResources(), 0, index) + res = faiss.StandardGpuResources() + options = faiss.GpuClonerOptions() + options.allowCpuCoarseQuantizer = True + index = faiss.index_cpu_to_gpu(res, 0, index, options) ps = faiss.GpuParameterSpace() ps.initialize(index) for i in range(ps.parameter_ranges.size()): diff --git a/faiss/gpu/test/test_index_cpu_to_gpu.py b/faiss/gpu/test/test_index_cpu_to_gpu.py index 84c35e2af7..088ea2bf74 100644 --- a/faiss/gpu/test/test_index_cpu_to_gpu.py +++ b/faiss/gpu/test/test_index_cpu_to_gpu.py @@ -4,26 +4,86 @@ class TestMoveToGpu(unittest.TestCase): - def test_index_cpu_to_gpu(self): + + @classmethod + def setUpClass(cls): + cls.res = faiss.StandardGpuResources() + + def create_index(self, factory_string): dimension = 128 n = 2500 db_vectors = np.random.random((n, dimension)).astype('float32') - code_size = 16 - res = faiss.StandardGpuResources() - index_pq = faiss.IndexPQ(dimension, code_size, 6) - index_pq.train(db_vectors) - index_pq.add(db_vectors) - self.assertRaisesRegex(Exception, ".*not implemented.*", - faiss.index_cpu_to_gpu, res, 0, index_pq) - - def test_index_cpu_to_gpu_does_not_throw_with_index_flat(self): - dimension = 128 - n = 100 - db_vectors = np.random.random((n, dimension)).astype('float32') - res = faiss.StandardGpuResources() - index_flat = faiss.IndexFlatL2(dimension) - index_flat.add(db_vectors) + index = faiss.index_factory(dimension, factory_string) + index.train(db_vectors) + if factory_string.startswith("IDMap"): + index.add_with_ids(db_vectors, np.arange(n)) + else: + index.add(db_vectors) + return index + + def create_and_clone(self, factory_string, + allowCpuCoarseQuantizer=None, + use_raft=None): + idx = self.create_index(factory_string) + config = faiss.GpuClonerOptions() + if allowCpuCoarseQuantizer is not None: + config.allowCpuCoarseQuantizer = allowCpuCoarseQuantizer + if use_raft is not None: + config.use_raft = use_raft + faiss.index_cpu_to_gpu(self.res, 0, idx, config) + + def verify_throws_not_implemented_exception(self, factory_string): + try: + self.create_and_clone(factory_string) + except Exception as e: + if "not implemented" not in str(e): + self.fail("Expected an exception but no exception was " + "thrown for factory_string: %s." % factory_string) + + def verify_clones_successfully(self, factory_string, + allowCpuCoarseQuantizer=None, + use_raft=None): + try: + self.create_and_clone( + factory_string, + allowCpuCoarseQuantizer=allowCpuCoarseQuantizer, + use_raft=use_raft) + except Exception as e: + self.fail("Unexpected exception thrown factory_string: " + "%s; error message: %s." % (factory_string, str(e))) + + def test_not_implemented_indices(self): + self.verify_throws_not_implemented_exception("PQ16") + self.verify_throws_not_implemented_exception("LSHrt") + self.verify_throws_not_implemented_exception("HNSW") + self.verify_throws_not_implemented_exception("HNSW,PQ16") + self.verify_throws_not_implemented_exception("IDMap,PQ16") + self.verify_throws_not_implemented_exception("IVF256,ITQ64,SH1.2") + + def test_implemented_indices(self): + self.verify_clones_successfully("Flat") + self.verify_clones_successfully("IVF1,Flat") + self.verify_clones_successfully("IVF32,PQ8") + self.verify_clones_successfully("IDMap,Flat") + self.verify_clones_successfully("PCA12,IVF32,Flat") + self.verify_clones_successfully("PCA32,IVF32,PQ8") + self.verify_clones_successfully("PCA32,IVF32,PQ8np") + + # set use_raft to false, these index types are not supported on RAFT + self.verify_clones_successfully("IVF32,SQ8", use_raft=False) + self.verify_clones_successfully( + "PCA32,IVF32,SQ8", use_raft=False) + + def test_with_flag(self): + self.verify_clones_successfully("IVF32_HNSW,Flat", + allowCpuCoarseQuantizer=True) + self.verify_clones_successfully("IVF256(PQ2x4fs),Flat", + allowCpuCoarseQuantizer=True) + + def test_with_flag_set_to_false(self): try: - faiss.index_cpu_to_gpu(res, 0, index_flat) - except Exception: - self.fail("index_cpu_to_gpu() threw an unexpected exception.") + self.verify_clones_successfully("IVF32_HNSW,Flat", + allowCpuCoarseQuantizer=False) + except Exception as e: + if "set the flag to true to allow the CPU fallback" not in str(e): + self.fail("Unexepected error message thrown: %s." % str(e)) diff --git a/faiss/impl/FaissAssert.h b/faiss/impl/FaissAssert.h index 2aea23e6a8..6f666f684c 100644 --- a/faiss/impl/FaissAssert.h +++ b/faiss/impl/FaissAssert.h @@ -94,13 +94,6 @@ } \ } while (false) -#define FAISS_THROW_IF_MSG(X, MSG) \ - do { \ - if (X) { \ - FAISS_THROW_FMT("Error: '%s' failed: " MSG, #X); \ - } \ - } while (false) - #define FAISS_THROW_IF_NOT_MSG(X, MSG) \ do { \ if (!(X)) { \ From 366a8146aa8744277c02328987bec95acf364ba7 Mon Sep 17 00:00:00 2001 From: Gufan Yin Date: Fri, 5 Apr 2024 19:11:34 -0700 Subject: [PATCH 121/206] Revert D55723390: Support for Remove ids from IVFPQFastScan index Differential Revision: D55723390 Original commit changeset: 0017b556bd79 Original Phabricator Diff: D55723390 fbshipit-source-id: 58d61467b30dd11d27398f9f825162f598896845 --- faiss/invlists/BlockInvertedLists.cpp | 34 ++++-------------- faiss/invlists/BlockInvertedLists.h | 3 -- faiss/invlists/DirectMap.cpp | 10 +----- tests/test_merge_index.py | 50 +++++++-------------------- 4 files changed, 20 insertions(+), 77 deletions(-) diff --git a/faiss/invlists/BlockInvertedLists.cpp b/faiss/invlists/BlockInvertedLists.cpp index dbdb0302dc..6370d11871 100644 --- a/faiss/invlists/BlockInvertedLists.cpp +++ b/faiss/invlists/BlockInvertedLists.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -55,9 +54,7 @@ size_t BlockInvertedLists::add_entries( codes[list_no].resize(n_block * block_size); if (o % block_size == 0) { // copy whole blocks - memcpy(&codes[list_no][o * packer->code_size], - code, - n_block * block_size); + memcpy(&codes[list_no][o * code_size], code, n_block * block_size); } else { FAISS_THROW_IF_NOT_MSG(packer, "missing code packer"); std::vector buffer(packer->code_size); @@ -79,29 +76,6 @@ const uint8_t* BlockInvertedLists::get_codes(size_t list_no) const { return codes[list_no].get(); } -size_t BlockInvertedLists::remove_ids(const IDSelector& sel) { - idx_t nremove = 0; -#pragma omp parallel for - for (idx_t i = 0; i < nlist; i++) { - std::vector buffer(packer->code_size); - idx_t l = ids[i].size(), j = 0; - while (j < l) { - if (sel.is_member(ids[i][j])) { - l--; - ids[i][j] = ids[i][l]; - packer->unpack_1(codes[i].data(), l, buffer.data()); - packer->pack_1(buffer.data(), j, codes[i].data()); - } else { - j++; - } - } - resize(i, l); - nremove += ids[i].size() - l; - } - - return nremove; -} - const idx_t* BlockInvertedLists::get_ids(size_t list_no) const { assert(list_no < nlist); return ids[list_no].data(); @@ -128,6 +102,12 @@ void BlockInvertedLists::update_entries( const idx_t*, const uint8_t*) { FAISS_THROW_MSG("not impemented"); + /* + assert (list_no < nlist); + assert (n_entry + offset <= ids[list_no].size()); + memcpy (&ids[list_no][offset], ids_in, sizeof(ids_in[0]) * n_entry); + memcpy (&codes[list_no][offset * code_size], codes_in, code_size * n_entry); + */ } BlockInvertedLists::~BlockInvertedLists() { diff --git a/faiss/invlists/BlockInvertedLists.h b/faiss/invlists/BlockInvertedLists.h index 2b9cbba455..8d8df720bf 100644 --- a/faiss/invlists/BlockInvertedLists.h +++ b/faiss/invlists/BlockInvertedLists.h @@ -15,7 +15,6 @@ namespace faiss { struct CodePacker; -struct IDSelector; /** Inverted Lists that are organized by blocks. * @@ -48,8 +47,6 @@ struct BlockInvertedLists : InvertedLists { size_t list_size(size_t list_no) const override; const uint8_t* get_codes(size_t list_no) const override; const idx_t* get_ids(size_t list_no) const override; - /// remove ids from the InvertedLists - size_t remove_ids(const IDSelector& sel); // works only on empty BlockInvertedLists // the codes should be of size ceil(n_entry / n_per_block) * block_size diff --git a/faiss/invlists/DirectMap.cpp b/faiss/invlists/DirectMap.cpp index dc2b92aa1c..2b272922d5 100644 --- a/faiss/invlists/DirectMap.cpp +++ b/faiss/invlists/DirectMap.cpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace faiss { @@ -149,12 +148,8 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { std::vector toremove(nlist); size_t nremove = 0; - BlockInvertedLists* block_invlists = - dynamic_cast(invlists); + if (type == NoMap) { - if (block_invlists != nullptr) { - return block_invlists->remove_ids(sel); - } // exhaustive scan of IVF #pragma omp parallel for for (idx_t i = 0; i < nlist; i++) { @@ -183,9 +178,6 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { } } } else if (type == Hashtable) { - FAISS_THROW_IF_MSG( - block_invlists, - "remove with hashtable is not supported with BlockInvertedLists"); const IDSelectorArray* sela = dynamic_cast(&sel); FAISS_THROW_IF_NOT_MSG( diff --git a/tests/test_merge_index.py b/tests/test_merge_index.py index 4417f57fe7..8c4c1f0912 100644 --- a/tests/test_merge_index.py +++ b/tests/test_merge_index.py @@ -246,45 +246,19 @@ def test_merge_IDMap2(self): class TestRemoveFastScan(unittest.TestCase): - def do_fast_scan_test(self, - factory_key, - with_ids=False, - direct_map_type=faiss.DirectMap.NoMap): + def do_fast_scan_test(self, factory_key, size1): ds = SyntheticDataset(110, 1000, 1000, 100) - index = faiss.index_factory(ds.d, factory_key) - index.train(ds.get_train()) - - index.reset() + index1 = faiss.index_factory(ds.d, factory_key) + index1.train(ds.get_train()) + index1.reset() tokeep = [i % 3 == 0 for i in range(ds.nb)] - if with_ids: - index.add_with_ids(ds.get_database()[tokeep], np.arange(ds.nb)[tokeep]) - faiss.extract_index_ivf(index).nprobe = 5 - else: - index.add(ds.get_database()[tokeep]) - _, Iref = index.search(ds.get_queries(), 5) - - index.reset() - if with_ids: - index.add_with_ids(ds.get_database(), np.arange(ds.nb)) - index.set_direct_map_type(direct_map_type) - faiss.extract_index_ivf(index).nprobe = 5 - else: - index.add(ds.get_database()) - index.remove_ids(np.where(np.logical_not(tokeep))[0]) - _, Inew = index.search(ds.get_queries(), 5) + index1.add(ds.get_database()[tokeep]) + _, Iref = index1.search(ds.get_queries(), 5) + index1.reset() + index1.add(ds.get_database()) + index1.remove_ids(np.where(np.logical_not(tokeep))[0]) + _, Inew = index1.search(ds.get_queries(), 5) np.testing.assert_array_equal(Inew, Iref) - def test_remove_PQFastScan(self): - # with_ids is not support for this type of index - self.do_fast_scan_test("PQ5x4fs", False) - - def test_remove_IVFPQFastScan(self): - self.do_fast_scan_test("IVF20,PQ5x4fs", True) - - def test_remove_IVFPQFastScan_2(self): - self.assertRaisesRegex(Exception, - ".*not supported.*", - self.do_fast_scan_test, - "IVF20,PQ5x4fs", - True, - faiss.DirectMap.Hashtable) + def test_remove(self): + self.do_fast_scan_test("PQ5x4fs", 320) From 252ae16ea371ca861663db3fcae02cbe40deef05 Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Tue, 9 Apr 2024 09:36:22 -0700 Subject: [PATCH 122/206] Support for Remove ids from IVFPQFastScan index (#3354) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3354 **Change was previously reverted because of build failure as change D55577576 removed the definition of FAISS_THROW_IF_MSG** **Context** [Issue 3128](https://github.com/facebookresearch/faiss/issues/3128) is an enhancement request to support remove_ids for IVFPQFastScan. Existing mechanism use direct map and iterate over items in selector and use scopecodes and scopeIds to replace item to be removed. Given that codes are packed, it is hard to return single code how it is packed in CodePackerPQ4. Thus, we need a custom implementation to removed_ids. **In this diff**, 1. We have added custom implementation of remove_ids from BlockInvertedLists which unpack code as it iterate and repack in new position. DirectMap use this remove_id function in BlockInvertedLists for type NoMap in DirectMap. 2. Also, we are throwing exception for other map type in DirectMap i.e. HashTable Reviewed By: ramilbakhshyiev Differential Revision: D55858959 fbshipit-source-id: c8a0631495380b7dead36720e4507f4d1900d39f --- faiss/impl/FaissAssert.h | 6 ++-- faiss/invlists/BlockInvertedLists.cpp | 34 ++++++++++++++---- faiss/invlists/BlockInvertedLists.h | 3 ++ faiss/invlists/DirectMap.cpp | 10 +++++- tests/test_merge_index.py | 50 ++++++++++++++++++++------- 5 files changed, 81 insertions(+), 22 deletions(-) diff --git a/faiss/impl/FaissAssert.h b/faiss/impl/FaissAssert.h index 6f666f684c..9d357823d0 100644 --- a/faiss/impl/FaissAssert.h +++ b/faiss/impl/FaissAssert.h @@ -94,13 +94,15 @@ } \ } while (false) -#define FAISS_THROW_IF_NOT_MSG(X, MSG) \ +#define FAISS_THROW_IF_MSG(X, MSG) \ do { \ - if (!(X)) { \ + if (X) { \ FAISS_THROW_FMT("Error: '%s' failed: " MSG, #X); \ } \ } while (false) +#define FAISS_THROW_IF_NOT_MSG(X, MSG) FAISS_THROW_IF_MSG(!(X), MSG) + #define FAISS_THROW_IF_NOT_FMT(X, FMT, ...) \ do { \ if (!(X)) { \ diff --git a/faiss/invlists/BlockInvertedLists.cpp b/faiss/invlists/BlockInvertedLists.cpp index 6370d11871..dbdb0302dc 100644 --- a/faiss/invlists/BlockInvertedLists.cpp +++ b/faiss/invlists/BlockInvertedLists.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -54,7 +55,9 @@ size_t BlockInvertedLists::add_entries( codes[list_no].resize(n_block * block_size); if (o % block_size == 0) { // copy whole blocks - memcpy(&codes[list_no][o * code_size], code, n_block * block_size); + memcpy(&codes[list_no][o * packer->code_size], + code, + n_block * block_size); } else { FAISS_THROW_IF_NOT_MSG(packer, "missing code packer"); std::vector buffer(packer->code_size); @@ -76,6 +79,29 @@ const uint8_t* BlockInvertedLists::get_codes(size_t list_no) const { return codes[list_no].get(); } +size_t BlockInvertedLists::remove_ids(const IDSelector& sel) { + idx_t nremove = 0; +#pragma omp parallel for + for (idx_t i = 0; i < nlist; i++) { + std::vector buffer(packer->code_size); + idx_t l = ids[i].size(), j = 0; + while (j < l) { + if (sel.is_member(ids[i][j])) { + l--; + ids[i][j] = ids[i][l]; + packer->unpack_1(codes[i].data(), l, buffer.data()); + packer->pack_1(buffer.data(), j, codes[i].data()); + } else { + j++; + } + } + resize(i, l); + nremove += ids[i].size() - l; + } + + return nremove; +} + const idx_t* BlockInvertedLists::get_ids(size_t list_no) const { assert(list_no < nlist); return ids[list_no].data(); @@ -102,12 +128,6 @@ void BlockInvertedLists::update_entries( const idx_t*, const uint8_t*) { FAISS_THROW_MSG("not impemented"); - /* - assert (list_no < nlist); - assert (n_entry + offset <= ids[list_no].size()); - memcpy (&ids[list_no][offset], ids_in, sizeof(ids_in[0]) * n_entry); - memcpy (&codes[list_no][offset * code_size], codes_in, code_size * n_entry); - */ } BlockInvertedLists::~BlockInvertedLists() { diff --git a/faiss/invlists/BlockInvertedLists.h b/faiss/invlists/BlockInvertedLists.h index 8d8df720bf..2b9cbba455 100644 --- a/faiss/invlists/BlockInvertedLists.h +++ b/faiss/invlists/BlockInvertedLists.h @@ -15,6 +15,7 @@ namespace faiss { struct CodePacker; +struct IDSelector; /** Inverted Lists that are organized by blocks. * @@ -47,6 +48,8 @@ struct BlockInvertedLists : InvertedLists { size_t list_size(size_t list_no) const override; const uint8_t* get_codes(size_t list_no) const override; const idx_t* get_ids(size_t list_no) const override; + /// remove ids from the InvertedLists + size_t remove_ids(const IDSelector& sel); // works only on empty BlockInvertedLists // the codes should be of size ceil(n_entry / n_per_block) * block_size diff --git a/faiss/invlists/DirectMap.cpp b/faiss/invlists/DirectMap.cpp index 2b272922d5..dc2b92aa1c 100644 --- a/faiss/invlists/DirectMap.cpp +++ b/faiss/invlists/DirectMap.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace faiss { @@ -148,8 +149,12 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { std::vector toremove(nlist); size_t nremove = 0; - + BlockInvertedLists* block_invlists = + dynamic_cast(invlists); if (type == NoMap) { + if (block_invlists != nullptr) { + return block_invlists->remove_ids(sel); + } // exhaustive scan of IVF #pragma omp parallel for for (idx_t i = 0; i < nlist; i++) { @@ -178,6 +183,9 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) { } } } else if (type == Hashtable) { + FAISS_THROW_IF_MSG( + block_invlists, + "remove with hashtable is not supported with BlockInvertedLists"); const IDSelectorArray* sela = dynamic_cast(&sel); FAISS_THROW_IF_NOT_MSG( diff --git a/tests/test_merge_index.py b/tests/test_merge_index.py index 8c4c1f0912..4417f57fe7 100644 --- a/tests/test_merge_index.py +++ b/tests/test_merge_index.py @@ -246,19 +246,45 @@ def test_merge_IDMap2(self): class TestRemoveFastScan(unittest.TestCase): - def do_fast_scan_test(self, factory_key, size1): + def do_fast_scan_test(self, + factory_key, + with_ids=False, + direct_map_type=faiss.DirectMap.NoMap): ds = SyntheticDataset(110, 1000, 1000, 100) - index1 = faiss.index_factory(ds.d, factory_key) - index1.train(ds.get_train()) - index1.reset() + index = faiss.index_factory(ds.d, factory_key) + index.train(ds.get_train()) + + index.reset() tokeep = [i % 3 == 0 for i in range(ds.nb)] - index1.add(ds.get_database()[tokeep]) - _, Iref = index1.search(ds.get_queries(), 5) - index1.reset() - index1.add(ds.get_database()) - index1.remove_ids(np.where(np.logical_not(tokeep))[0]) - _, Inew = index1.search(ds.get_queries(), 5) + if with_ids: + index.add_with_ids(ds.get_database()[tokeep], np.arange(ds.nb)[tokeep]) + faiss.extract_index_ivf(index).nprobe = 5 + else: + index.add(ds.get_database()[tokeep]) + _, Iref = index.search(ds.get_queries(), 5) + + index.reset() + if with_ids: + index.add_with_ids(ds.get_database(), np.arange(ds.nb)) + index.set_direct_map_type(direct_map_type) + faiss.extract_index_ivf(index).nprobe = 5 + else: + index.add(ds.get_database()) + index.remove_ids(np.where(np.logical_not(tokeep))[0]) + _, Inew = index.search(ds.get_queries(), 5) np.testing.assert_array_equal(Inew, Iref) - def test_remove(self): - self.do_fast_scan_test("PQ5x4fs", 320) + def test_remove_PQFastScan(self): + # with_ids is not support for this type of index + self.do_fast_scan_test("PQ5x4fs", False) + + def test_remove_IVFPQFastScan(self): + self.do_fast_scan_test("IVF20,PQ5x4fs", True) + + def test_remove_IVFPQFastScan_2(self): + self.assertRaisesRegex(Exception, + ".*not supported.*", + self.do_fast_scan_test, + "IVF20,PQ5x4fs", + True, + faiss.DirectMap.Hashtable) From 17fbeb8d7e3eb12dbc1a6ba7fc58be316761d842 Mon Sep 17 00:00:00 2001 From: Alexandr Guzhva Date: Thu, 11 Apr 2024 14:23:46 -0700 Subject: [PATCH 123/206] Improve filtering & search parameters propagation (#3304) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3304 Reviewed By: junjieqi Differential Revision: D55823369 Pulled By: mdouze fbshipit-source-id: c0e9f4b85d979758f02e9953f3706b63a846bf22 --- faiss/IVFlib.cpp | 5 +- faiss/IndexFastScan.cpp | 10 +- faiss/IndexIVFFastScan.cpp | 189 +++++++++++++++++++++--------- faiss/IndexIVFFastScan.h | 21 ++-- faiss/impl/simd_result_handlers.h | 180 ++++++++++++++++++++-------- 5 files changed, 289 insertions(+), 116 deletions(-) diff --git a/faiss/IVFlib.cpp b/faiss/IVFlib.cpp index 91aa7af7f3..f2c975f4de 100644 --- a/faiss/IVFlib.cpp +++ b/faiss/IVFlib.cpp @@ -352,7 +352,10 @@ void search_with_parameters( const IndexIVF* index_ivf = dynamic_cast(index); FAISS_THROW_IF_NOT(index_ivf); - index_ivf->quantizer->search(n, x, params->nprobe, Dq.data(), Iq.data()); + SearchParameters* quantizer_params = + (params) ? params->quantizer_params : nullptr; + index_ivf->quantizer->search( + n, x, params->nprobe, Dq.data(), Iq.data(), quantizer_params); if (nb_dis_ptr) { *nb_dis_ptr = count_ndis(index_ivf, n * params->nprobe, Iq.data()); diff --git a/faiss/IndexFastScan.cpp b/faiss/IndexFastScan.cpp index 2dfb2f55fd..529465da3e 100644 --- a/faiss/IndexFastScan.cpp +++ b/faiss/IndexFastScan.cpp @@ -189,6 +189,7 @@ void estimators_from_tables_generic( dt += index.ksub; } } + if (C::cmp(heap_dis[0], dis)) { heap_pop(k, heap_dis, heap_ids); heap_push(k, heap_dis, heap_ids, dis, j); @@ -203,17 +204,18 @@ ResultHandlerCompare* make_knn_handler( idx_t k, size_t ntotal, float* distances, - idx_t* labels) { + idx_t* labels, + const IDSelector* sel = nullptr) { using HeapHC = HeapHandler; using ReservoirHC = ReservoirHandler; using SingleResultHC = SingleResultHandler; if (k == 1) { - return new SingleResultHC(n, ntotal, distances, labels); + return new SingleResultHC(n, ntotal, distances, labels, sel); } else if (impl % 2 == 0) { - return new HeapHC(n, ntotal, k, distances, labels); + return new HeapHC(n, ntotal, k, distances, labels, sel); } else /* if (impl % 2 == 1) */ { - return new ReservoirHC(n, ntotal, k, 2 * k, distances, labels); + return new ReservoirHC(n, ntotal, k, 2 * k, distances, labels, sel); } } diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 00bc6c823e..19828753d2 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -211,7 +211,7 @@ void estimators_from_tables_generic( int64_t* heap_ids, const NormTableScaler* scaler) { using accu_t = typename C::T; - int nscale = scaler ? scaler->nscale : 0; + size_t nscale = scaler ? scaler->nscale : 0; for (size_t j = 0; j < ncodes; ++j) { BitstringReader bsr(codes + j * index.code_size, index.code_size); accu_t dis = bias; @@ -270,6 +270,7 @@ void IndexIVFFastScan::compute_LUT_uint8( biases.resize(n * nprobe); } + // OMP for MSVC requires i to have signed integral type #pragma omp parallel for if (n > 100) for (int64_t i = 0; i < n; i++) { const float* t_in = dis_tables_float.get() + i * dim123; @@ -306,11 +307,16 @@ void IndexIVFFastScan::search( idx_t k, float* distances, idx_t* labels, - const SearchParameters* params) const { - auto paramsi = dynamic_cast(params); - FAISS_THROW_IF_NOT_MSG(!params || paramsi, "need IVFSearchParameters"); + const SearchParameters* params_in) const { + const IVFSearchParameters* params = nullptr; + if (params_in) { + params = dynamic_cast(params_in); + FAISS_THROW_IF_NOT_MSG( + params, "IndexIVFFastScan params have incorrect type"); + } + search_preassigned( - n, x, k, nullptr, nullptr, distances, labels, false, paramsi); + n, x, k, nullptr, nullptr, distances, labels, false, params); } void IndexIVFFastScan::search_preassigned( @@ -326,18 +332,17 @@ void IndexIVFFastScan::search_preassigned( IndexIVFStats* stats) const { size_t nprobe = this->nprobe; if (params) { - FAISS_THROW_IF_NOT_MSG( - !params->quantizer_params, "quantizer params not supported"); FAISS_THROW_IF_NOT(params->max_codes == 0); nprobe = params->nprobe; } + FAISS_THROW_IF_NOT_MSG( !store_pairs, "store_pairs not supported for this index"); FAISS_THROW_IF_NOT_MSG(!stats, "stats not supported for this index"); FAISS_THROW_IF_NOT(k > 0); const CoarseQuantized cq = {nprobe, centroid_dis, assign}; - search_dispatch_implem(n, x, k, distances, labels, cq, nullptr); + search_dispatch_implem(n, x, k, distances, labels, cq, nullptr, params); } void IndexIVFFastScan::range_search( @@ -345,10 +350,18 @@ void IndexIVFFastScan::range_search( const float* x, float radius, RangeSearchResult* result, - const SearchParameters* params) const { - FAISS_THROW_IF_NOT(!params); + const SearchParameters* params_in) const { + size_t nprobe = this->nprobe; + const IVFSearchParameters* params = nullptr; + if (params_in) { + params = dynamic_cast(params_in); + FAISS_THROW_IF_NOT_MSG( + params, "IndexIVFFastScan params have incorrect type"); + nprobe = params->nprobe; + } + const CoarseQuantized cq = {nprobe, nullptr, nullptr}; - range_search_dispatch_implem(n, x, radius, *result, cq, nullptr); + range_search_dispatch_implem(n, x, radius, *result, cq, nullptr, params); } namespace { @@ -359,17 +372,18 @@ ResultHandlerCompare* make_knn_handler_fixC( idx_t n, idx_t k, float* distances, - idx_t* labels) { + idx_t* labels, + const IDSelector* sel) { using HeapHC = HeapHandler; using ReservoirHC = ReservoirHandler; using SingleResultHC = SingleResultHandler; if (k == 1) { - return new SingleResultHC(n, 0, distances, labels); + return new SingleResultHC(n, 0, distances, labels, sel); } else if (impl % 2 == 0) { - return new HeapHC(n, 0, k, distances, labels); + return new HeapHC(n, 0, k, distances, labels, sel); } else /* if (impl % 2 == 1) */ { - return new ReservoirHC(n, 0, k, 2 * k, distances, labels); + return new ReservoirHC(n, 0, k, 2 * k, distances, labels, sel); } } @@ -379,13 +393,14 @@ SIMDResultHandlerToFloat* make_knn_handler( idx_t n, idx_t k, float* distances, - idx_t* labels) { + idx_t* labels, + const IDSelector* sel) { if (is_max) { return make_knn_handler_fixC>( - impl, n, k, distances, labels); + impl, n, k, distances, labels, sel); } else { return make_knn_handler_fixC>( - impl, n, k, distances, labels); + impl, n, k, distances, labels, sel); } } @@ -402,10 +417,20 @@ struct CoarseQuantizedWithBuffer : CoarseQuantized { std::vector ids_buffer; std::vector dis_buffer; - void quantize(const Index* quantizer, idx_t n, const float* x) { + void quantize( + const Index* quantizer, + idx_t n, + const float* x, + const SearchParameters* quantizer_params) { dis_buffer.resize(nprobe * n); ids_buffer.resize(nprobe * n); - quantizer->search(n, x, nprobe, dis_buffer.data(), ids_buffer.data()); + quantizer->search( + n, + x, + nprobe, + dis_buffer.data(), + ids_buffer.data(), + quantizer_params); dis = dis_buffer.data(); ids = ids_buffer.data(); } @@ -421,8 +446,11 @@ struct CoarseQuantizedSlice : CoarseQuantizedWithBuffer { } } - void quantize_slice(const Index* quantizer, const float* x) { - quantize(quantizer, i1 - i0, x + quantizer->d * i0); + void quantize_slice( + const Index* quantizer, + const float* x, + const SearchParameters* quantizer_params) { + quantize(quantizer, i1 - i0, x + quantizer->d * i0, quantizer_params); } }; @@ -459,7 +487,13 @@ void IndexIVFFastScan::search_dispatch_implem( float* distances, idx_t* labels, const CoarseQuantized& cq_in, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { + const idx_t nprobe = params ? params->nprobe : this->nprobe; + const IDSelector* sel = (params) ? params->sel : nullptr; + const SearchParameters* quantizer_params = + params ? params->quantizer_params : nullptr; + bool is_max = !is_similarity_metric(metric_type); using RH = SIMDResultHandlerToFloat; @@ -489,52 +523,70 @@ void IndexIVFFastScan::search_dispatch_implem( } CoarseQuantizedWithBuffer cq(cq_in); + cq.nprobe = nprobe; if (!cq.done() && !multiple_threads) { // we do the coarse quantization here execpt when search is // sliced over threads (then it is more efficient to have each thread do // its own coarse quantization) - cq.quantize(quantizer, n, x); + cq.quantize(quantizer, n, x, quantizer_params); + invlists->prefetch_lists(cq.ids, n * cq.nprobe); } if (impl == 1) { if (is_max) { search_implem_1>( - n, x, k, distances, labels, cq, scaler); + n, x, k, distances, labels, cq, scaler, params); } else { search_implem_1>( - n, x, k, distances, labels, cq, scaler); + n, x, k, distances, labels, cq, scaler, params); } } else if (impl == 2) { if (is_max) { search_implem_2>( - n, x, k, distances, labels, cq, scaler); + n, x, k, distances, labels, cq, scaler, params); } else { search_implem_2>( - n, x, k, distances, labels, cq, scaler); + n, x, k, distances, labels, cq, scaler, params); } - } else if (impl >= 10 && impl <= 15) { size_t ndis = 0, nlist_visited = 0; if (!multiple_threads) { // clang-format off if (impl == 12 || impl == 13) { - std::unique_ptr handler(make_knn_handler(is_max, impl, n, k, distances, labels)); + std::unique_ptr handler( + make_knn_handler( + is_max, + impl, + n, + k, + distances, + labels, sel + ) + ); search_implem_12( n, x, *handler.get(), - cq, &ndis, &nlist_visited, scaler); - + cq, &ndis, &nlist_visited, scaler, params); } else if (impl == 14 || impl == 15) { - search_implem_14( n, x, k, distances, labels, - cq, impl, scaler); + cq, impl, scaler, params); } else { - std::unique_ptr handler(make_knn_handler(is_max, impl, n, k, distances, labels)); + std::unique_ptr handler( + make_knn_handler( + is_max, + impl, + n, + k, + distances, + labels, + sel + ) + ); search_implem_10( n, x, *handler.get(), cq, - &ndis, &nlist_visited, scaler); + &ndis, &nlist_visited, scaler, params); } // clang-format on } else { @@ -543,7 +595,8 @@ void IndexIVFFastScan::search_dispatch_implem( if (impl == 14 || impl == 15) { // this might require slicing if there are too // many queries (for now we keep this simple) - search_implem_14(n, x, k, distances, labels, cq, impl, scaler); + search_implem_14( + n, x, k, distances, labels, cq, impl, scaler, params); } else { #pragma omp parallel for reduction(+ : ndis, nlist_visited) for (int slice = 0; slice < nslice; slice++) { @@ -553,19 +606,19 @@ void IndexIVFFastScan::search_dispatch_implem( idx_t* lab_i = labels + i0 * k; CoarseQuantizedSlice cq_i(cq, i0, i1); if (!cq_i.done()) { - cq_i.quantize_slice(quantizer, x); + cq_i.quantize_slice(quantizer, x, quantizer_params); } std::unique_ptr handler(make_knn_handler( - is_max, impl, i1 - i0, k, dis_i, lab_i)); + is_max, impl, i1 - i0, k, dis_i, lab_i, sel)); // clang-format off if (impl == 12 || impl == 13) { search_implem_12( i1 - i0, x + i0 * d, *handler.get(), - cq_i, &ndis, &nlist_visited, scaler); + cq_i, &ndis, &nlist_visited, scaler, params); } else { search_implem_10( i1 - i0, x + i0 * d, *handler.get(), - cq_i, &ndis, &nlist_visited, scaler); + cq_i, &ndis, &nlist_visited, scaler, params); } // clang-format on } @@ -585,7 +638,13 @@ void IndexIVFFastScan::range_search_dispatch_implem( float radius, RangeSearchResult& rres, const CoarseQuantized& cq_in, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { + // const idx_t nprobe = params ? params->nprobe : this->nprobe; + const IDSelector* sel = (params) ? params->sel : nullptr; + const SearchParameters* quantizer_params = + params ? params->quantizer_params : nullptr; + bool is_max = !is_similarity_metric(metric_type); if (n == 0) { @@ -613,7 +672,8 @@ void IndexIVFFastScan::range_search_dispatch_implem( } if (!multiple_threads && !cq.done()) { - cq.quantize(quantizer, n, x); + cq.quantize(quantizer, n, x, quantizer_params); + invlists->prefetch_lists(cq.ids, n * cq.nprobe); } size_t ndis = 0, nlist_visited = 0; @@ -622,10 +682,10 @@ void IndexIVFFastScan::range_search_dispatch_implem( std::unique_ptr handler; if (is_max) { handler.reset(new RangeHandler, true>( - rres, radius, 0)); + rres, radius, 0, sel)); } else { handler.reset(new RangeHandler, true>( - rres, radius, 0)); + rres, radius, 0, sel)); } if (impl == 12) { search_implem_12( @@ -649,17 +709,17 @@ void IndexIVFFastScan::range_search_dispatch_implem( idx_t i1 = n * (slice + 1) / nslice; CoarseQuantizedSlice cq_i(cq, i0, i1); if (!cq_i.done()) { - cq_i.quantize_slice(quantizer, x); + cq_i.quantize_slice(quantizer, x, quantizer_params); } std::unique_ptr handler; if (is_max) { handler.reset(new PartialRangeHandler< CMax, - true>(pres, radius, 0, i0, i1)); + true>(pres, radius, 0, i0, i1, sel)); } else { handler.reset(new PartialRangeHandler< CMin, - true>(pres, radius, 0, i0, i1)); + true>(pres, radius, 0, i0, i1, sel)); } if (impl == 12 || impl == 13) { @@ -670,7 +730,8 @@ void IndexIVFFastScan::range_search_dispatch_implem( cq_i, &ndis, &nlist_visited, - scaler); + scaler, + params); } else { search_implem_10( i1 - i0, @@ -679,7 +740,8 @@ void IndexIVFFastScan::range_search_dispatch_implem( cq_i, &ndis, &nlist_visited, - scaler); + scaler, + params); } } pres.finalize(); @@ -699,7 +761,8 @@ void IndexIVFFastScan::search_implem_1( float* distances, idx_t* labels, const CoarseQuantized& cq, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { FAISS_THROW_IF_NOT(orig_invlists); size_t dim12 = ksub * M; @@ -766,7 +829,8 @@ void IndexIVFFastScan::search_implem_2( float* distances, idx_t* labels, const CoarseQuantized& cq, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { FAISS_THROW_IF_NOT(orig_invlists); size_t dim12 = ksub * M2; @@ -848,7 +912,12 @@ void IndexIVFFastScan::search_implem_10( const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { + const size_t max_codes = params ? params->max_codes : this->max_codes; + const SearchParameters* quantizer_params = + params ? params->quantizer_params : nullptr; + size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; @@ -909,6 +978,7 @@ void IndexIVFFastScan::search_implem_10( ndis++; } } + handler.end(); *ndis_out = ndis; *nlist_out = nlist; @@ -921,7 +991,8 @@ void IndexIVFFastScan::search_implem_12( const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { if (n == 0) { // does not work well with reservoir return; } @@ -933,6 +1004,7 @@ void IndexIVFFastScan::search_implem_12( std::unique_ptr normalizers(new float[2 * n]); compute_LUT_uint8(n, x, cq, dis_tables, biases, normalizers.get()); + handler.begin(skip & 16 ? nullptr : normalizers.get()); struct QC { @@ -958,6 +1030,7 @@ void IndexIVFFastScan::search_implem_12( return a.list_no < b.list_no; }); } + // prepare the result handlers int qbs2 = this->qbs2 ? this->qbs2 : 11; @@ -1049,12 +1122,15 @@ void IndexIVFFastScan::search_implem_14( idx_t* labels, const CoarseQuantized& cq, int impl, - const NormTableScaler* scaler) const { + const NormTableScaler* scaler, + const IVFSearchParameters* params) const { if (n == 0) { // does not work well with reservoir return; } FAISS_THROW_IF_NOT(bbs == 32); + const IDSelector* sel = params ? params->sel : nullptr; + size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; @@ -1157,7 +1233,7 @@ void IndexIVFFastScan::search_implem_14( // prepare the result handlers std::unique_ptr handler(make_knn_handler( - is_max, impl, n, k, local_dis.data(), local_idx.data())); + is_max, impl, n, k, local_dis.data(), local_idx.data(), sel)); handler->begin(normalizers.get()); int qbs2 = this->qbs2 ? this->qbs2 : 11; @@ -1167,6 +1243,7 @@ void IndexIVFFastScan::search_implem_14( tmp_bias.resize(qbs2); handler->dbias = tmp_bias.data(); } + std::set q_set; uint64_t t_copy_pack = 0, t_scan = 0; #pragma omp for schedule(dynamic) diff --git a/faiss/IndexIVFFastScan.h b/faiss/IndexIVFFastScan.h index 159a3a7098..9d4c4910d3 100644 --- a/faiss/IndexIVFFastScan.h +++ b/faiss/IndexIVFFastScan.h @@ -148,7 +148,8 @@ struct IndexIVFFastScan : IndexIVF { float* distances, idx_t* labels, const CoarseQuantized& cq, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; void range_search_dispatch_implem( idx_t n, @@ -156,7 +157,8 @@ struct IndexIVFFastScan : IndexIVF { float radius, RangeSearchResult& rres, const CoarseQuantized& cq_in, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; // impl 1 and 2 are just for verification template @@ -167,7 +169,8 @@ struct IndexIVFFastScan : IndexIVF { float* distances, idx_t* labels, const CoarseQuantized& cq, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; template void search_implem_2( @@ -177,7 +180,8 @@ struct IndexIVFFastScan : IndexIVF { float* distances, idx_t* labels, const CoarseQuantized& cq, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; // implem 10 and 12 are not multithreaded internally, so // export search stats @@ -188,7 +192,8 @@ struct IndexIVFFastScan : IndexIVF { const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; void search_implem_12( idx_t n, @@ -197,7 +202,8 @@ struct IndexIVFFastScan : IndexIVF { const CoarseQuantized& cq, size_t* ndis_out, size_t* nlist_out, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; // implem 14 is multithreaded internally across nprobes and queries void search_implem_14( @@ -208,7 +214,8 @@ struct IndexIVFFastScan : IndexIVF { idx_t* labels, const CoarseQuantized& cq, int impl, - const NormTableScaler* scaler) const; + const NormTableScaler* scaler, + const IVFSearchParameters* params = nullptr) const; // reconstruct vectors from packed invlists void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons) diff --git a/faiss/impl/simd_result_handlers.h b/faiss/impl/simd_result_handlers.h index 633d480990..2fa18fa340 100644 --- a/faiss/impl/simd_result_handlers.h +++ b/faiss/impl/simd_result_handlers.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -137,6 +138,7 @@ struct FixedStorageHandler : SIMDResultHandler { } } } + virtual ~FixedStorageHandler() {} }; @@ -150,8 +152,10 @@ struct ResultHandlerCompare : SIMDResultHandlerToFloat { int64_t i0 = 0; // query origin int64_t j0 = 0; // db origin - ResultHandlerCompare(size_t nq, size_t ntotal) - : SIMDResultHandlerToFloat(nq, ntotal) { + const IDSelector* sel; + + ResultHandlerCompare(size_t nq, size_t ntotal, const IDSelector* sel_in) + : SIMDResultHandlerToFloat(nq, ntotal), sel{sel_in} { this->is_CMax = C::is_max; this->sizeof_ids = sizeof(typename C::TI); this->with_fields = with_id_map; @@ -232,9 +236,14 @@ struct SingleResultHandler : ResultHandlerCompare { float* dis; int64_t* ids; - SingleResultHandler(size_t nq, size_t ntotal, float* dis, int64_t* ids) - : RHC(nq, ntotal), idis(nq), dis(dis), ids(ids) { - for (int i = 0; i < nq; i++) { + SingleResultHandler( + size_t nq, + size_t ntotal, + float* dis, + int64_t* ids, + const IDSelector* sel_in) + : RHC(nq, ntotal, sel_in), idis(nq), dis(dis), ids(ids) { + for (size_t i = 0; i < nq; i++) { ids[i] = -1; idis[i] = C::neutral(); } @@ -256,20 +265,36 @@ struct SingleResultHandler : ResultHandlerCompare { d0.store(d32tab); d1.store(d32tab + 16); - while (lt_mask) { - // find first non-zero - int j = __builtin_ctz(lt_mask); - lt_mask -= 1 << j; - T d = d32tab[j]; - if (C::cmp(idis[q], d)) { - idis[q] = d; - ids[q] = this->adjust_id(b, j); + if (this->sel != nullptr) { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + auto real_idx = this->adjust_id(b, j); + lt_mask -= 1 << j; + if (this->sel->is_member(real_idx)) { + T d = d32tab[j]; + if (C::cmp(idis[q], d)) { + idis[q] = d; + ids[q] = real_idx; + } + } + } + } else { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + T d = d32tab[j]; + if (C::cmp(idis[q], d)) { + idis[q] = d; + ids[q] = this->adjust_id(b, j); + } } } } void end() { - for (int q = 0; q < this->nq; q++) { + for (size_t q = 0; q < this->nq; q++) { if (!normalizers) { dis[q] = idis[q]; } else { @@ -296,8 +321,14 @@ struct HeapHandler : ResultHandlerCompare { int64_t k; // number of results to keep - HeapHandler(size_t nq, size_t ntotal, int64_t k, float* dis, int64_t* ids) - : RHC(nq, ntotal), + HeapHandler( + size_t nq, + size_t ntotal, + int64_t k, + float* dis, + int64_t* ids, + const IDSelector* sel_in) + : RHC(nq, ntotal, sel_in), idis(nq * k), iids(nq * k), dis(dis), @@ -330,21 +361,36 @@ struct HeapHandler : ResultHandlerCompare { d0.store(d32tab); d1.store(d32tab + 16); - while (lt_mask) { - // find first non-zero - int j = __builtin_ctz(lt_mask); - lt_mask -= 1 << j; - T dis = d32tab[j]; - if (C::cmp(heap_dis[0], dis)) { - int64_t idx = this->adjust_id(b, j); - heap_pop(k, heap_dis, heap_ids); - heap_push(k, heap_dis, heap_ids, dis, idx); + if (this->sel != nullptr) { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + auto real_idx = this->adjust_id(b, j); + lt_mask -= 1 << j; + if (this->sel->is_member(real_idx)) { + T dis = d32tab[j]; + if (C::cmp(heap_dis[0], dis)) { + heap_replace_top( + k, heap_dis, heap_ids, dis, real_idx); + } + } + } + } else { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + T dis = d32tab[j]; + if (C::cmp(heap_dis[0], dis)) { + int64_t idx = this->adjust_id(b, j); + heap_replace_top(k, heap_dis, heap_ids, dis, idx); + } } } } void end() override { - for (int q = 0; q < this->nq; q++) { + for (size_t q = 0; q < this->nq; q++) { T* heap_dis_in = idis.data() + q * k; TI* heap_ids_in = iids.data() + q * k; heap_reorder(k, heap_dis_in, heap_ids_in); @@ -393,8 +439,12 @@ struct ReservoirHandler : ResultHandlerCompare { size_t k, size_t cap, float* dis, - int64_t* ids) - : RHC(nq, ntotal), capacity((cap + 15) & ~15), dis(dis), ids(ids) { + int64_t* ids, + const IDSelector* sel_in) + : RHC(nq, ntotal, sel_in), + capacity((cap + 15) & ~15), + dis(dis), + ids(ids) { assert(capacity % 16 == 0); all_ids.resize(nq * capacity); all_vals.resize(nq * capacity); @@ -423,12 +473,25 @@ struct ReservoirHandler : ResultHandlerCompare { d0.store(d32tab); d1.store(d32tab + 16); - while (lt_mask) { - // find first non-zero - int j = __builtin_ctz(lt_mask); - lt_mask -= 1 << j; - T dis = d32tab[j]; - res.add(dis, this->adjust_id(b, j)); + if (this->sel != nullptr) { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + auto real_idx = this->adjust_id(b, j); + lt_mask -= 1 << j; + if (this->sel->is_member(real_idx)) { + T dis = d32tab[j]; + res.add(dis, real_idx); + } + } + } else { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + T dis = d32tab[j]; + res.add(dis, this->adjust_id(b, j)); + } } } @@ -439,7 +502,7 @@ struct ReservoirHandler : ResultHandlerCompare { CMin>::type; std::vector perm(reservoirs[0].n); - for (int q = 0; q < reservoirs.size(); q++) { + for (size_t q = 0; q < reservoirs.size(); q++) { ReservoirTopN& res = reservoirs[q]; size_t n = res.n; @@ -454,14 +517,14 @@ struct ReservoirHandler : ResultHandlerCompare { one_a = 1 / normalizers[2 * q]; b = normalizers[2 * q + 1]; } - for (int i = 0; i < res.i; i++) { + for (size_t i = 0; i < res.i; i++) { perm[i] = i; } // indirect sort of result arrays std::sort(perm.begin(), perm.begin() + res.i, [&res](int i, int j) { return C::cmp(res.vals[j], res.vals[i]); }); - for (int i = 0; i < res.i; i++) { + for (size_t i = 0; i < res.i; i++) { heap_dis[i] = res.vals[perm[i]] * one_a + b; heap_ids[i] = res.ids[perm[i]]; } @@ -499,8 +562,12 @@ struct RangeHandler : ResultHandlerCompare { }; std::vector triplets; - RangeHandler(RangeSearchResult& rres, float radius, size_t ntotal) - : RHC(rres.nq, ntotal), rres(rres), radius(radius) { + RangeHandler( + RangeSearchResult& rres, + float radius, + size_t ntotal, + const IDSelector* sel_in) + : RHC(rres.nq, ntotal, sel_in), rres(rres), radius(radius) { thresholds.resize(nq); n_per_query.resize(nq + 1); } @@ -528,13 +595,28 @@ struct RangeHandler : ResultHandlerCompare { d0.store(d32tab); d1.store(d32tab + 16); - while (lt_mask) { - // find first non-zero - int j = __builtin_ctz(lt_mask); - lt_mask -= 1 << j; - T dis = d32tab[j]; - n_per_query[q]++; - triplets.push_back({idx_t(q + q0), this->adjust_id(b, j), dis}); + if (this->sel != nullptr) { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + + auto real_idx = this->adjust_id(b, j); + if (this->sel->is_member(real_idx)) { + T dis = d32tab[j]; + n_per_query[q]++; + triplets.push_back({idx_t(q + q0), real_idx, dis}); + } + } + } else { + while (lt_mask) { + // find first non-zero + int j = __builtin_ctz(lt_mask); + lt_mask -= 1 << j; + T dis = d32tab[j]; + n_per_query[q]++; + triplets.push_back({idx_t(q + q0), this->adjust_id(b, j), dis}); + } } } @@ -578,8 +660,9 @@ struct PartialRangeHandler : RangeHandler { float radius, size_t ntotal, size_t q0, - size_t q1) - : RangeHandler(*pres.res, radius, ntotal), + size_t q1, + const IDSelector* sel_in) + : RangeHandler(*pres.res, radius, ntotal, sel_in), pres(pres) { nq = q1 - q0; this->q0 = q0; @@ -698,6 +781,7 @@ void dispatch_SIMDResultHanlder( FAISS_THROW_FMT("Unknown id size %d", res.sizeof_ids); } } + } // namespace simd_result_handlers } // namespace faiss From 40e86433368095dd5e257474439195ced551017c Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Thu, 11 Apr 2024 14:23:46 -0700 Subject: [PATCH 124/206] selector parameter for FastScan (#3362) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3362 Add test to Alex' PR Reviewed By: junjieqi Differential Revision: D56003946 fbshipit-source-id: 5a8a881d450bc97ae0777d73ce0ce8607ec6b686 --- tests/test_search_params.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/test_search_params.py b/tests/test_search_params.py index 954d39cd00..22b845c2ea 100644 --- a/tests/test_search_params.py +++ b/tests/test_search_params.py @@ -22,7 +22,7 @@ class TestSelector(unittest.TestCase): combinations as possible. """ - def do_test_id_selector(self, index_key, id_selector_type="batch", mt=faiss.METRIC_L2): + def do_test_id_selector(self, index_key, id_selector_type="batch", mt=faiss.METRIC_L2, k=10): """ Verify that the id selector returns the subset of results that are members according to the IDSelector. Supports id_selector_type="batch", "bitmap", "range", "range_sorted", "and", "or", "xor" @@ -30,7 +30,6 @@ def do_test_id_selector(self, index_key, id_selector_type="batch", mt=faiss.METR ds = datasets.SyntheticDataset(32, 1000, 100, 20) index = faiss.index_factory(ds.d, index_key, mt) index.train(ds.get_train()) - k = 10 # reference result if "range" in id_selector_type: @@ -145,6 +144,16 @@ def test_IVFFlat_range_sorted(self): def test_IVFPQ(self): self.do_test_id_selector("IVF32,PQ4x4np") + def test_IVFPQfs(self): + self.do_test_id_selector("IVF32,PQ4x4fs") + + def test_IVFPQfs_k1(self): + self.do_test_id_selector("IVF32,PQ4x4fs", k=1) + + def test_IVFPQfs_k40(self): + # test reservoir codepath + self.do_test_id_selector("IVF32,PQ4x4fs", k=40) + def test_IVFSQ(self): self.do_test_id_selector("IVF32,SQ8") From acd06d62119bad16a3e0ed3aee9fa63837c2e58c Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Fri, 12 Apr 2024 10:52:31 -0700 Subject: [PATCH 125/206] Switch sprintf to snprintf (#3363) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3363 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead {F1484071654} Reviewed By: kuarora Differential Revision: D56009251 fbshipit-source-id: ec222cf589ff98b016979058d59fc20cccec8f43 --- faiss/impl/io.cpp | 2 +- faiss/utils/simdlib_neon.h | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/faiss/impl/io.cpp b/faiss/impl/io.cpp index 3d3af95036..5f5b2d5ebd 100644 --- a/faiss/impl/io.cpp +++ b/faiss/impl/io.cpp @@ -267,7 +267,7 @@ std::string fourcc_inv_printable(uint32_t x) { str += c; } else { char buf[10]; - sprintf(buf, "\\x%02x", c); + snprintf(buf, sizeof(buf), "\\x%02x", c); str += buf; } } diff --git a/faiss/utils/simdlib_neon.h b/faiss/utils/simdlib_neon.h index 656a561217..439a5210bc 100644 --- a/faiss/utils/simdlib_neon.h +++ b/faiss/utils/simdlib_neon.h @@ -168,9 +168,16 @@ static inline std::string elements_to_string(const char* fmt, const S& simd) { simd.store(bytes); char res[1000], *ptr = res; for (size_t i = 0; i < N; ++i) { - ptr += sprintf(ptr, fmt, bytes[i]); + int bytesWritten = + snprintf(ptr, sizeof(res) - (ptr - res), fmt, bytes[i]); + if (bytesWritten >= 0) { + ptr += bytesWritten; + } else { + break; + } } // strip last , + ptr[-1] = 0; return std::string(res); } From a35eb0ac11908f1ab1a6056dca15e74fb06cd4e7 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 12 Apr 2024 13:03:17 -0700 Subject: [PATCH 126/206] Remove unused variables in faiss/IndexIVF.cpp Summary: LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: dmm-fb Differential Revision: D56065763 fbshipit-source-id: b0541b8a759c4b6ca0e8753fc24b8c227047bd3d --- demos/demo_imi_pq.cpp | 1 - faiss/IndexIVF.cpp | 4 ++-- faiss/utils/distances.cpp | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/demos/demo_imi_pq.cpp b/demos/demo_imi_pq.cpp index a2af65e792..4fab0778d8 100644 --- a/demos/demo_imi_pq.cpp +++ b/demos/demo_imi_pq.cpp @@ -77,7 +77,6 @@ int main() { // the coarse quantizer should not be dealloced before the index // 4 = nb of bytes per code (d must be a multiple of this) // 8 = nb of bits per sub-code (almost always 8) - faiss::MetricType metric = faiss::METRIC_L2; // can be METRIC_INNER_PRODUCT faiss::IndexIVFPQ index( &coarse_quantizer, d, ncentroids, bytes_per_code, 8); index.quantizer_trains_alone = true; diff --git a/faiss/IndexIVF.cpp b/faiss/IndexIVF.cpp index 95d3bc9e68..548aaa4cc7 100644 --- a/faiss/IndexIVF.cpp +++ b/faiss/IndexIVF.cpp @@ -444,7 +444,7 @@ void IndexIVF::search_preassigned( max_codes = unlimited_list_size; } - bool do_parallel = omp_get_max_threads() >= 2 && + [[maybe_unused]] bool do_parallel = omp_get_max_threads() >= 2 && (pmode == 0 ? false : pmode == 3 ? n > 1 : pmode == 1 ? nprobe > 1 @@ -784,7 +784,7 @@ void IndexIVF::range_search_preassigned( int pmode = this->parallel_mode & ~PARALLEL_MODE_NO_HEAP_INIT; // don't start parallel section if single query - bool do_parallel = omp_get_max_threads() >= 2 && + [[maybe_unused]] bool do_parallel = omp_get_max_threads() >= 2 && (pmode == 3 ? false : pmode == 0 ? nx > 1 : pmode == 1 ? nprobe > 1 diff --git a/faiss/utils/distances.cpp b/faiss/utils/distances.cpp index 82bc164ae1..74b56bcc87 100644 --- a/faiss/utils/distances.cpp +++ b/faiss/utils/distances.cpp @@ -141,7 +141,7 @@ void exhaustive_inner_product_seq( const IDSelector* sel = nullptr) { using SingleResultHandler = typename BlockResultHandler::SingleResultHandler; - int nt = std::min(int(nx), omp_get_max_threads()); + [[maybe_unused]] int nt = std::min(int(nx), omp_get_max_threads()); FAISS_ASSERT(use_sel == (sel != nullptr)); @@ -178,7 +178,7 @@ void exhaustive_L2sqr_seq( const IDSelector* sel = nullptr) { using SingleResultHandler = typename BlockResultHandler::SingleResultHandler; - int nt = std::min(int(nx), omp_get_max_threads()); + [[maybe_unused]] int nt = std::min(int(nx), omp_get_max_threads()); FAISS_ASSERT(use_sel == (sel != nullptr)); From ab2b7f50936b3bafd4e076f798413da2399482bd Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Sun, 14 Apr 2024 11:28:32 -0700 Subject: [PATCH 127/206] Apply clang-format 18 Summary: Previously this code conformed from clang-format 12. Reviewed By: igorsugak Differential Revision: D56065247 fbshipit-source-id: f5a985dd8f8b84f2f9e1818b3719b43c5a1b05b3 --- benchs/bench_cppcontrib_sa_decode.cpp | 151 ++++++++++--------------- faiss/IndexBinaryIVF.cpp | 2 +- faiss/gpu/utils/Tensor.cuh | 7 +- faiss/impl/HNSW.cpp | 4 +- faiss/invlists/OnDiskInvertedLists.cpp | 4 +- 5 files changed, 67 insertions(+), 101 deletions(-) diff --git a/benchs/bench_cppcontrib_sa_decode.cpp b/benchs/bench_cppcontrib_sa_decode.cpp index c5c6b0bf18..f0266172a8 100644 --- a/benchs/bench_cppcontrib_sa_decode.cpp +++ b/benchs/bench_cppcontrib_sa_decode.cpp @@ -214,9 +214,8 @@ static void verifyIndex2LevelDecoder( double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_seq" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -264,9 +263,8 @@ static void verifyIndex2LevelDecoder( const double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -327,9 +325,8 @@ static void verifyIndex2LevelDecoder( const double error1 = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel1 << "\t" << error1 << std::endl; + << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel1 << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -357,9 +354,8 @@ static void verifyIndex2LevelDecoder( const double error2 = getError(n, d, outputFaiss, outputKernel2); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2 << "\t" << error2 << std::endl; + << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2 << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -389,9 +385,8 @@ static void verifyIndex2LevelDecoder( const double error2u = getError(n, d, outputFaiss, outputKernel2u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2u << "\t" << error2u << std::endl; + << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2u << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -424,9 +419,8 @@ static void verifyIndex2LevelDecoder( const double error3 = getError(n, d, outputFaiss, outputKernel3); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3 << "\t" << error3 << std::endl; + << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3 << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -463,9 +457,8 @@ static void verifyIndex2LevelDecoder( const double error3u = getError(n, d, outputFaiss, outputKernel3u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3u << "\t" << error3u << std::endl; + << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3u << "\t" << error3u << std::endl; } } @@ -532,9 +525,8 @@ static void verifyMinMaxIndex2LevelDecoder( double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_seq" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -582,9 +574,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -651,9 +642,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error1 = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel1 << "\t" << error1 << std::endl; + << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel1 << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -686,9 +676,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error2 = getError(n, d, outputFaiss, outputKernel2); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2 << "\t" << error2 << std::endl; + << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2 << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -723,9 +712,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error2u = getError(n, d, outputFaiss, outputKernel2u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2u << "\t" << error2u << std::endl; + << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2u << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -763,9 +751,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error3 = getError(n, d, outputFaiss, outputKernel3); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3 << "\t" << error3 << std::endl; + << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3 << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -807,9 +794,8 @@ static void verifyMinMaxIndex2LevelDecoder( const double error3u = getError(n, d, outputFaiss, outputKernel3u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3u << "\t" << error3u << std::endl; + << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3u << "\t" << error3u << std::endl; } } @@ -866,9 +852,8 @@ static void verifyIndexPQDecoder( double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_seq" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -915,9 +900,8 @@ static void verifyIndexPQDecoder( const double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -978,9 +962,8 @@ static void verifyIndexPQDecoder( const double error1 = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel1 << "\t" << error1 << std::endl; + << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel1 << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -1007,9 +990,8 @@ static void verifyIndexPQDecoder( const double error2 = getError(n, d, outputFaiss, outputKernel2); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2 << "\t" << error2 << std::endl; + << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2 << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -1037,9 +1019,8 @@ static void verifyIndexPQDecoder( const double error2u = getError(n, d, outputFaiss, outputKernel2u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2u << "\t" << error2u << std::endl; + << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2u << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -1071,9 +1052,8 @@ static void verifyIndexPQDecoder( const double error3 = getError(n, d, outputFaiss, outputKernel3); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3 << "\t" << error3 << std::endl; + << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3 << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -1107,9 +1087,8 @@ static void verifyIndexPQDecoder( const double error3u = getError(n, d, outputFaiss, outputKernel3u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3u << "\t" << error3u << std::endl; + << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3u << "\t" << error3u << std::endl; } } @@ -1171,9 +1150,8 @@ static void verifyMinMaxIndexPQDecoder( double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_seq" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1220,9 +1198,8 @@ static void verifyMinMaxIndexPQDecoder( const double error = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel << "\t" << error << std::endl; + << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1288,9 +1265,8 @@ static void verifyMinMaxIndexPQDecoder( const double error1 = getError(n, d, outputFaiss, outputKernel1); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel1 << "\t" << error1 << std::endl; + << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel1 << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -1322,9 +1298,8 @@ static void verifyMinMaxIndexPQDecoder( const double error2 = getError(n, d, outputFaiss, outputKernel2); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2 << "\t" << error2 << std::endl; + << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2 << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -1357,9 +1332,8 @@ static void verifyMinMaxIndexPQDecoder( const double error2u = getError(n, d, outputFaiss, outputKernel2u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel2u << "\t" << error2u << std::endl; + << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel2u << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -1396,9 +1370,8 @@ static void verifyMinMaxIndexPQDecoder( const double error3 = getError(n, d, outputFaiss, outputKernel3); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3 << "\t" << error3 << std::endl; + << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3 << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -1437,9 +1410,8 @@ static void verifyMinMaxIndexPQDecoder( const double error3u = getError(n, d, outputFaiss, outputKernel3u); std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" - << "\t" << nIterations << "\t" << timeFaiss << "\t" - << timeKernel3u << "\t" << error3u << std::endl; + << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss + << "\t" << timeKernel3u << "\t" << error3u << std::endl; } } @@ -1512,14 +1484,9 @@ int main(int argc, char** argv) { (N_ITERATIONS % 6) == 0, "Number of iterations should be 6*x"); // print the header - std::cout << "Codec\t" - << "n\t" - << "d\t" - << "Experiment\t" - << "Iterations\t" - << "Faiss time\t" - << "SADecodeKernel time\t" - << "Error" << std::endl; + std::cout << "Codec\t" << "n\t" << "d\t" << "Experiment\t" << "Iterations\t" + << "Faiss time\t" << "SADecodeKernel time\t" << "Error" + << std::endl; // The following experiment types are available: // * store_seq - decode a contiguous block of codes into vectors, one by one diff --git a/faiss/IndexBinaryIVF.cpp b/faiss/IndexBinaryIVF.cpp index 686785a987..ab1b9fd89a 100644 --- a/faiss/IndexBinaryIVF.cpp +++ b/faiss/IndexBinaryIVF.cpp @@ -456,7 +456,7 @@ void search_knn_hamming_heap( } } // parallel for - } // parallel + } // parallel indexIVF_stats.nq += n; indexIVF_stats.nlist += nlistv; diff --git a/faiss/gpu/utils/Tensor.cuh b/faiss/gpu/utils/Tensor.cuh index b13d0e1496..0fbb2417b3 100644 --- a/faiss/gpu/utils/Tensor.cuh +++ b/faiss/gpu/utils/Tensor.cuh @@ -232,13 +232,12 @@ class Tensor { } /// Returns a read/write view of a portion of our tensor. - __host__ __device__ inline detail::SubTensor - operator[](IndexT); + __host__ __device__ inline detail:: + SubTensor operator[](IndexT); /// Returns a read/write view of a portion of our tensor (const). __host__ __device__ inline const detail:: - SubTensor - operator[](IndexT) const; + SubTensor operator[](IndexT) const; /// Returns the size of a given dimension, `[0, Dim - 1]`. No bounds /// checking. diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index b1324e1211..d8c8225968 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -110,8 +110,8 @@ void HNSW::print_neighbor_stats(int level) const { level, nb_neighbors(level)); size_t tot_neigh = 0, tot_common = 0, tot_reciprocal = 0, n_node = 0; -#pragma omp parallel for reduction(+: tot_neigh) reduction(+: tot_common) \ - reduction(+: tot_reciprocal) reduction(+: n_node) +#pragma omp parallel for reduction(+ : tot_neigh) reduction(+ : tot_common) \ + reduction(+ : tot_reciprocal) reduction(+ : n_node) for (int i = 0; i < levels.size(); i++) { if (levels[i] > level) { n_node++; diff --git a/faiss/invlists/OnDiskInvertedLists.cpp b/faiss/invlists/OnDiskInvertedLists.cpp index dc17fe67f6..8565572a9b 100644 --- a/faiss/invlists/OnDiskInvertedLists.cpp +++ b/faiss/invlists/OnDiskInvertedLists.cpp @@ -394,8 +394,8 @@ const idx_t* OnDiskInvertedLists::get_ids(size_t list_no) const { return nullptr; } - return ( - const idx_t*)(ptr + lists[list_no].offset + code_size * lists[list_no].capacity); + return (const idx_t*)(ptr + lists[list_no].offset + + code_size * lists[list_no].capacity); } void OnDiskInvertedLists::update_entries( From 0169f29f375db27e86151320b60932a6b46716d5 Mon Sep 17 00:00:00 2001 From: iotamudelta Date: Wed, 17 Apr 2024 03:43:57 -0700 Subject: [PATCH 128/206] Update required cmake version to 3.24. (#3305) Summary: The CMakeLists.txt in faiss/gpu uses the $=3.23.1 + - cmake >=3.24.0 - make # [not win] - mkl-devel =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} @@ -85,7 +85,7 @@ outputs: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - swig - - cmake >=3.23.1 + - cmake >=3.24.0 - make # [not win] host: - python {{ python }} diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index b0df707181..7ac24e785d 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -48,7 +48,7 @@ outputs: - {{ compiler('cxx') }} - sysroot_linux-64 # [linux64] - llvm-openmp # [osx] - - cmake >=3.23.1 + - cmake >=3.24.0 - make # [not win] - mkl-devel =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} @@ -81,7 +81,7 @@ outputs: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - swig - - cmake >=3.23.1 + - cmake >=3.24.0 - make # [not win] host: - python {{ python }} diff --git a/conda/faiss/meta.yaml b/conda/faiss/meta.yaml index c4d66ca0d3..79e7be953e 100644 --- a/conda/faiss/meta.yaml +++ b/conda/faiss/meta.yaml @@ -39,7 +39,7 @@ outputs: - {{ compiler('cxx') }} - sysroot_linux-64 # [linux64] - llvm-openmp # [osx] - - cmake >=3.23.1 + - cmake >=3.24.0 - make # [not win] - mkl-devel =2023 # [x86_64] host: @@ -69,7 +69,7 @@ outputs: - {{ compiler('cxx') }} - sysroot_linux-64 =2.17 # [linux64] - swig - - cmake >=3.23.1 + - cmake >=3.24.0 - make # [not win] host: - python {{ python }} From 3677ab502135c44da76b0e6b0f3755b0f407b337 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Fri, 19 Apr 2024 13:55:15 -0700 Subject: [PATCH 129/206] Switch clang-format-11 to clang-format-18 (#3372) Summary: In this commit https://github.com/facebookresearch/faiss/commit/ab2b7f50936b3bafd4e076f798413da2399482bd, they changed format based on clang-format-18. However, we still use clang-format-11 in our circle ci job which caused the failure. In this PR, we are going to switch to clang-format-18 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3372 Reviewed By: kuarora Differential Revision: D56280363 Pulled By: junjieqi fbshipit-source-id: f832ab2112f762e6000b55a155e3e43fe99071d7 --- .circleci/config.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 549e4a2793..7e8bd8170a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,12 +38,17 @@ jobs: - run: name: Install clang-format command: | - apt-get update - apt-get install -y git-core clang-format-11 + apt-get update -y + apt-get install -y wget + apt install -y lsb-release wget software-properties-common gnupg + wget https://apt.llvm.org/llvm.sh + chmod u+x llvm.sh + ./llvm.sh 18 + apt-get install -y git-core clang-format-18 - run: name: Verify clang-format command: | - git ls-files | grep -E '\.(cpp|h|cu|cuh)$' | xargs clang-format-11 -i + git ls-files | grep -E '\.(cpp|h|cu|cuh)$' | xargs clang-format-18 -i if git diff --quiet; then echo "Formatting OK!" else From 5893ab77daee3c84ecc74a2c84c18d7cd486fcea Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Mon, 22 Apr 2024 09:30:05 -0700 Subject: [PATCH 130/206] remove unused code (#3371) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3371 This will never happen because N is fixed at compile time and the buffer is large enough. It is misleading to add error handling code for a case that will never happen. Reviewed By: kuarora Differential Revision: D56274458 fbshipit-source-id: ca706f1223dbc97e69d5ac9750b277afa4df80a7 --- faiss/utils/simdlib_neon.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/faiss/utils/simdlib_neon.h b/faiss/utils/simdlib_neon.h index 439a5210bc..1bdf0ed01e 100644 --- a/faiss/utils/simdlib_neon.h +++ b/faiss/utils/simdlib_neon.h @@ -170,14 +170,10 @@ static inline std::string elements_to_string(const char* fmt, const S& simd) { for (size_t i = 0; i < N; ++i) { int bytesWritten = snprintf(ptr, sizeof(res) - (ptr - res), fmt, bytes[i]); - if (bytesWritten >= 0) { - ptr += bytesWritten; - } else { - break; - } + ptr += bytesWritten; } - // strip last , - + // The format usually contains a ',' separator so this is to remove the last + // separator. ptr[-1] = 0; return std::string(res); } From b2e91f685e10dc05269b2e436deaf75e242d7394 Mon Sep 17 00:00:00 2001 From: Carl Love Date: Wed, 24 Apr 2024 02:05:48 -0700 Subject: [PATCH 131/206] Unroll loop in lookup_2_lanes (#3364) Summary: The current loop goes from 0 to 31. It has an if statement to do an assignment for j < 16 and a different assignment for j >= 16. By unrolling the loop to do the j < 16 and the j >= 16 iterations in parallel the if j < 16 is eliminated and the number of loop iterations is reduced in half. Then unroll the loop for the j < 16 and the j >=16 to a depth of 2. This change results in approximately a 55% reduction in the execution time for the bench_ivf_fastscan.py workload on Power 10 when compiled with CMAKE_INSTALL_CONFIG_NAME=Release. The removal of the if (j < 16) statement and the unrolling of the loop removes branch cycle stall and register dependencies on instruction issue. The result is the unrolled code is able issue instructions earlier thus reducing the total number of cycles required to execute the function. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3364 Reviewed By: kuarora Differential Revision: D56455690 Pulled By: mdouze fbshipit-source-id: 490a17a40d9d4439b1a8ea22e991e706d68fb2fa --- faiss/utils/simdlib.h | 4 + faiss/utils/simdlib_ppc64.h | 1084 +++++++++++++++++++++++++++++++++++ 2 files changed, 1088 insertions(+) create mode 100644 faiss/utils/simdlib_ppc64.h diff --git a/faiss/utils/simdlib.h b/faiss/utils/simdlib.h index beeec2374e..ea5020d719 100644 --- a/faiss/utils/simdlib.h +++ b/faiss/utils/simdlib.h @@ -27,6 +27,10 @@ #include +#elif defined(__PPC64__) + +#include + #else // emulated = all operations are implemented as scalars diff --git a/faiss/utils/simdlib_ppc64.h b/faiss/utils/simdlib_ppc64.h new file mode 100644 index 0000000000..94b3e42dc7 --- /dev/null +++ b/faiss/utils/simdlib_ppc64.h @@ -0,0 +1,1084 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +namespace faiss { + +struct simd256bit { + union { + uint8_t u8[32]; + uint16_t u16[16]; + uint32_t u32[8]; + float f32[8]; + }; + + simd256bit() {} + + explicit simd256bit(const void* x) { + memcpy(u8, x, 32); + } + + void clear() { + memset(u8, 0, 32); + } + + void storeu(void* ptr) const { + memcpy(ptr, u8, 32); + } + + void loadu(const void* ptr) { + memcpy(u8, ptr, 32); + } + + void store(void* ptr) const { + storeu(ptr); + } + + void bin(char bits[257]) const { + const char* bytes = (char*)this->u8; + for (int i = 0; i < 256; i++) { + bits[i] = '0' + ((bytes[i / 8] >> (i % 8)) & 1); + } + bits[256] = 0; + } + + std::string bin() const { + char bits[257]; + bin(bits); + return std::string(bits); + } + + // Checks whether the other holds exactly the same bytes. + bool is_same_as(simd256bit other) const { + for (size_t i = 0; i < 8; i++) { + if (u32[i] != other.u32[i]) { + return false; + } + } + + return true; + } +}; + +/// vector of 16 elements in uint16 +struct simd16uint16 : simd256bit { + simd16uint16() {} + + explicit simd16uint16(int x) { + set1(x); + } + + explicit simd16uint16(uint16_t x) { + set1(x); + } + + explicit simd16uint16(const simd256bit& x) : simd256bit(x) {} + + explicit simd16uint16(const uint16_t* x) : simd256bit((const void*)x) {} + + explicit simd16uint16( + uint16_t u0, + uint16_t u1, + uint16_t u2, + uint16_t u3, + uint16_t u4, + uint16_t u5, + uint16_t u6, + uint16_t u7, + uint16_t u8, + uint16_t u9, + uint16_t u10, + uint16_t u11, + uint16_t u12, + uint16_t u13, + uint16_t u14, + uint16_t u15) { + this->u16[0] = u0; + this->u16[1] = u1; + this->u16[2] = u2; + this->u16[3] = u3; + this->u16[4] = u4; + this->u16[5] = u5; + this->u16[6] = u6; + this->u16[7] = u7; + this->u16[8] = u8; + this->u16[9] = u9; + this->u16[10] = u10; + this->u16[11] = u11; + this->u16[12] = u12; + this->u16[13] = u13; + this->u16[14] = u14; + this->u16[15] = u15; + } + + std::string elements_to_string(const char* fmt) const { + char res[1000], *ptr = res; + for (int i = 0; i < 16; i++) { + ptr += sprintf(ptr, fmt, u16[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } + + std::string hex() const { + return elements_to_string("%02x,"); + } + + std::string dec() const { + return elements_to_string("%3d,"); + } + + template + static simd16uint16 unary_func(const simd16uint16& a, F&& f) { + simd16uint16 c; + for (int j = 0; j < 16; j++) { + c.u16[j] = f(a.u16[j]); + } + return c; + } + + template + static simd16uint16 binary_func( + const simd16uint16& a, + const simd16uint16& b, + F&& f) { + simd16uint16 c; + for (int j = 0; j < 16; j++) { + c.u16[j] = f(a.u16[j], b.u16[j]); + } + return c; + } + + void set1(uint16_t x) { + for (int i = 0; i < 16; i++) { + u16[i] = x; + } + } + + simd16uint16 operator*(const simd16uint16& other) const { + return binary_func( + *this, other, [](uint16_t a, uint16_t b) { return a * b; }); + } + + // shift must be known at compile time + simd16uint16 operator>>(const int shift) const { + return unary_func(*this, [shift](uint16_t a) { return a >> shift; }); + } + + // shift must be known at compile time + simd16uint16 operator<<(const int shift) const { + return unary_func(*this, [shift](uint16_t a) { return a << shift; }); + } + + simd16uint16 operator+=(const simd16uint16& other) { + *this = *this + other; + return *this; + } + + simd16uint16 operator-=(const simd16uint16& other) { + *this = *this - other; + return *this; + } + + simd16uint16 operator+(const simd16uint16& other) const { + return binary_func( + *this, other, [](uint16_t a, uint16_t b) { return a + b; }); + } + + simd16uint16 operator-(const simd16uint16& other) const { + return binary_func( + *this, other, [](uint16_t a, uint16_t b) { return a - b; }); + } + + simd16uint16 operator&(const simd256bit& other) const { + return binary_func( + *this, simd16uint16(other), [](uint16_t a, uint16_t b) { + return a & b; + }); + } + + simd16uint16 operator|(const simd256bit& other) const { + return binary_func( + *this, simd16uint16(other), [](uint16_t a, uint16_t b) { + return a | b; + }); + } + + simd16uint16 operator^(const simd256bit& other) const { + return binary_func( + *this, simd16uint16(other), [](uint16_t a, uint16_t b) { + return a ^ b; + }); + } + + // returns binary masks + simd16uint16 operator==(const simd16uint16& other) const { + return binary_func(*this, other, [](uint16_t a, uint16_t b) { + return a == b ? 0xffff : 0; + }); + } + + simd16uint16 operator~() const { + return unary_func(*this, [](uint16_t a) { return ~a; }); + } + + // get scalar at index 0 + uint16_t get_scalar_0() const { + return u16[0]; + } + + // mask of elements where this >= thresh + // 2 bit per component: 16 * 2 = 32 bit + uint32_t ge_mask(const simd16uint16& thresh) const { + uint32_t gem = 0; + for (int j = 0; j < 16; j++) { + if (u16[j] >= thresh.u16[j]) { + gem |= 3 << (j * 2); + } + } + return gem; + } + + uint32_t le_mask(const simd16uint16& thresh) const { + return thresh.ge_mask(*this); + } + + uint32_t gt_mask(const simd16uint16& thresh) const { + return ~le_mask(thresh); + } + + bool all_gt(const simd16uint16& thresh) const { + return le_mask(thresh) == 0; + } + + // for debugging only + uint16_t operator[](int i) const { + return u16[i]; + } + + void accu_min(const simd16uint16& incoming) { + for (int j = 0; j < 16; j++) { + if (incoming.u16[j] < u16[j]) { + u16[j] = incoming.u16[j]; + } + } + } + + void accu_max(const simd16uint16& incoming) { + for (int j = 0; j < 16; j++) { + if (incoming.u16[j] > u16[j]) { + u16[j] = incoming.u16[j]; + } + } + } +}; + +// not really a std::min because it returns an elementwise min +inline simd16uint16 min(const simd16uint16& av, const simd16uint16& bv) { + return simd16uint16::binary_func( + av, bv, [](uint16_t a, uint16_t b) { return std::min(a, b); }); +} + +inline simd16uint16 max(const simd16uint16& av, const simd16uint16& bv) { + return simd16uint16::binary_func( + av, bv, [](uint16_t a, uint16_t b) { return std::max(a, b); }); +} + +// decompose in 128-lanes: a = (a0, a1), b = (b0, b1) +// return (a0 + a1, b0 + b1) +// TODO find a better name +inline simd16uint16 combine2x2(const simd16uint16& a, const simd16uint16& b) { + simd16uint16 c; + for (int j = 0; j < 8; j++) { + c.u16[j] = a.u16[j] + a.u16[j + 8]; + c.u16[j + 8] = b.u16[j] + b.u16[j + 8]; + } + return c; +} + +// compare d0 and d1 to thr, return 32 bits corresponding to the concatenation +// of d0 and d1 with thr +inline uint32_t cmp_ge32( + const simd16uint16& d0, + const simd16uint16& d1, + const simd16uint16& thr) { + uint32_t gem = 0; + for (int j = 0; j < 16; j++) { + if (d0.u16[j] >= thr.u16[j]) { + gem |= 1 << j; + } + if (d1.u16[j] >= thr.u16[j]) { + gem |= 1 << (j + 16); + } + } + return gem; +} + +inline uint32_t cmp_le32( + const simd16uint16& d0, + const simd16uint16& d1, + const simd16uint16& thr) { + uint32_t gem = 0; + for (int j = 0; j < 16; j++) { + if (d0.u16[j] <= thr.u16[j]) { + gem |= 1 << j; + } + if (d1.u16[j] <= thr.u16[j]) { + gem |= 1 << (j + 16); + } + } + return gem; +} + +// hadd does not cross lanes +inline simd16uint16 hadd(const simd16uint16& a, const simd16uint16& b) { + simd16uint16 c; + c.u16[0] = a.u16[0] + a.u16[1]; + c.u16[1] = a.u16[2] + a.u16[3]; + c.u16[2] = a.u16[4] + a.u16[5]; + c.u16[3] = a.u16[6] + a.u16[7]; + c.u16[4] = b.u16[0] + b.u16[1]; + c.u16[5] = b.u16[2] + b.u16[3]; + c.u16[6] = b.u16[4] + b.u16[5]; + c.u16[7] = b.u16[6] + b.u16[7]; + + c.u16[8] = a.u16[8] + a.u16[9]; + c.u16[9] = a.u16[10] + a.u16[11]; + c.u16[10] = a.u16[12] + a.u16[13]; + c.u16[11] = a.u16[14] + a.u16[15]; + c.u16[12] = b.u16[8] + b.u16[9]; + c.u16[13] = b.u16[10] + b.u16[11]; + c.u16[14] = b.u16[12] + b.u16[13]; + c.u16[15] = b.u16[14] + b.u16[15]; + + return c; +} + +// Vectorized version of the following code: +// for (size_t i = 0; i < n; i++) { +// bool flag = (candidateValues[i] < currentValues[i]); +// minValues[i] = flag ? candidateValues[i] : currentValues[i]; +// minIndices[i] = flag ? candidateIndices[i] : currentIndices[i]; +// maxValues[i] = !flag ? candidateValues[i] : currentValues[i]; +// maxIndices[i] = !flag ? candidateIndices[i] : currentIndices[i]; +// } +// Max indices evaluation is inaccurate in case of equal values (the index of +// the last equal value is saved instead of the first one), but this behavior +// saves instructions. +inline void cmplt_min_max_fast( + const simd16uint16 candidateValues, + const simd16uint16 candidateIndices, + const simd16uint16 currentValues, + const simd16uint16 currentIndices, + simd16uint16& minValues, + simd16uint16& minIndices, + simd16uint16& maxValues, + simd16uint16& maxIndices) { + for (size_t i = 0; i < 16; i++) { + bool flag = (candidateValues.u16[i] < currentValues.u16[i]); + minValues.u16[i] = flag ? candidateValues.u16[i] : currentValues.u16[i]; + minIndices.u16[i] = + flag ? candidateIndices.u16[i] : currentIndices.u16[i]; + maxValues.u16[i] = + !flag ? candidateValues.u16[i] : currentValues.u16[i]; + maxIndices.u16[i] = + !flag ? candidateIndices.u16[i] : currentIndices.u16[i]; + } +} + +// vector of 32 unsigned 8-bit integers +struct simd32uint8 : simd256bit { + simd32uint8() {} + + explicit simd32uint8(int x) { + set1(x); + } + + explicit simd32uint8(uint8_t x) { + set1(x); + } + template < + uint8_t _0, + uint8_t _1, + uint8_t _2, + uint8_t _3, + uint8_t _4, + uint8_t _5, + uint8_t _6, + uint8_t _7, + uint8_t _8, + uint8_t _9, + uint8_t _10, + uint8_t _11, + uint8_t _12, + uint8_t _13, + uint8_t _14, + uint8_t _15, + uint8_t _16, + uint8_t _17, + uint8_t _18, + uint8_t _19, + uint8_t _20, + uint8_t _21, + uint8_t _22, + uint8_t _23, + uint8_t _24, + uint8_t _25, + uint8_t _26, + uint8_t _27, + uint8_t _28, + uint8_t _29, + uint8_t _30, + uint8_t _31> + static simd32uint8 create() { + simd32uint8 ret; + ret.u8[0] = _0; + ret.u8[1] = _1; + ret.u8[2] = _2; + ret.u8[3] = _3; + ret.u8[4] = _4; + ret.u8[5] = _5; + ret.u8[6] = _6; + ret.u8[7] = _7; + ret.u8[8] = _8; + ret.u8[9] = _9; + ret.u8[10] = _10; + ret.u8[11] = _11; + ret.u8[12] = _12; + ret.u8[13] = _13; + ret.u8[14] = _14; + ret.u8[15] = _15; + ret.u8[16] = _16; + ret.u8[17] = _17; + ret.u8[18] = _18; + ret.u8[19] = _19; + ret.u8[20] = _20; + ret.u8[21] = _21; + ret.u8[22] = _22; + ret.u8[23] = _23; + ret.u8[24] = _24; + ret.u8[25] = _25; + ret.u8[26] = _26; + ret.u8[27] = _27; + ret.u8[28] = _28; + ret.u8[29] = _29; + ret.u8[30] = _30; + ret.u8[31] = _31; + return ret; + } + + explicit simd32uint8(const simd256bit& x) : simd256bit(x) {} + + explicit simd32uint8(const uint8_t* x) : simd256bit((const void*)x) {} + + std::string elements_to_string(const char* fmt) const { + char res[1000], *ptr = res; + for (int i = 0; i < 32; i++) { + ptr += sprintf(ptr, fmt, u8[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } + + std::string hex() const { + return elements_to_string("%02x,"); + } + + std::string dec() const { + return elements_to_string("%3d,"); + } + + void set1(uint8_t x) { + for (int j = 0; j < 32; j++) { + u8[j] = x; + } + } + + template + static simd32uint8 binary_func( + const simd32uint8& a, + const simd32uint8& b, + F&& f) { + simd32uint8 c; + for (int j = 0; j < 32; j++) { + c.u8[j] = f(a.u8[j], b.u8[j]); + } + return c; + } + + simd32uint8 operator&(const simd256bit& other) const { + return binary_func(*this, simd32uint8(other), [](uint8_t a, uint8_t b) { + return a & b; + }); + } + + simd32uint8 operator+(const simd32uint8& other) const { + return binary_func( + *this, other, [](uint8_t a, uint8_t b) { return a + b; }); + } + + // The very important operation that everything relies on + simd32uint8 lookup_2_lanes(const simd32uint8& idx) const { + simd32uint8 c; + // The original for loop: + // for (int j = 0; j < 32; j++) { + // if (idx.u8[j] & 0x80) { + // c.u8[j] = 0; + // } else { + // uint8_t i = idx.u8[j] & 15; + // if (j < 16) { + // c.u8[j] = u8[i]; + // } else { + // c.u8[j] = u8[16 + i]; + // } + // } + + // The following function was re-written for Power 10 + // The loop was unrolled to remove the if (j < 16) statement by doing + // the j and j + 16 iterations in parallel. The additional unrolling + // for j + 1 and j + 17, reduces the execution time on Power 10 by + // about 50% as the instruction scheduling allows on average 2X more + // instructions to be issued per cycle. + + for (int j = 0; j < 16; j = j + 2) { + // j < 16, unrolled to depth of 2 + if (idx.u8[j] & 0x80) { + c.u8[j] = 0; + } else { + uint8_t i = idx.u8[j] & 15; + c.u8[j] = u8[i]; + } + + if (idx.u8[j + 1] & 0x80) { + c.u8[j + 1] = 0; + } else { + uint8_t i = idx.u8[j + 1] & 15; + c.u8[j + 1] = u8[i]; + } + + // j >= 16, unrolled to depth of 2 + if (idx.u8[j + 16] & 0x80) { + c.u8[j + 16] = 0; + } else { + uint8_t i = idx.u8[j + 16] & 15; + c.u8[j + 16] = u8[i + 16]; + } + + if (idx.u8[j + 17] & 0x80) { + c.u8[j + 17] = 0; + } else { + uint8_t i = idx.u8[j + 17] & 15; + c.u8[j + 17] = u8[i + 16]; + } + } + return c; + } + + // extract + 0-extend lane + // this operation is slow (3 cycles) + + simd32uint8 operator+=(const simd32uint8& other) { + *this = *this + other; + return *this; + } + + // for debugging only + uint8_t operator[](int i) const { + return u8[i]; + } +}; + +// convert with saturation +// careful: this does not cross lanes, so the order is weird +inline simd32uint8 uint16_to_uint8_saturate( + const simd16uint16& a, + const simd16uint16& b) { + simd32uint8 c; + + auto saturate_16_to_8 = [](uint16_t x) { return x >= 256 ? 0xff : x; }; + + for (int i = 0; i < 8; i++) { + c.u8[i] = saturate_16_to_8(a.u16[i]); + c.u8[8 + i] = saturate_16_to_8(b.u16[i]); + c.u8[16 + i] = saturate_16_to_8(a.u16[8 + i]); + c.u8[24 + i] = saturate_16_to_8(b.u16[8 + i]); + } + return c; +} + +/// get most significant bit of each byte +inline uint32_t get_MSBs(const simd32uint8& a) { + uint32_t res = 0; + for (int i = 0; i < 32; i++) { + if (a.u8[i] & 0x80) { + res |= 1 << i; + } + } + return res; +} + +/// use MSB of each byte of mask to select a byte between a and b +inline simd32uint8 blendv( + const simd32uint8& a, + const simd32uint8& b, + const simd32uint8& mask) { + simd32uint8 c; + for (int i = 0; i < 32; i++) { + if (mask.u8[i] & 0x80) { + c.u8[i] = b.u8[i]; + } else { + c.u8[i] = a.u8[i]; + } + } + return c; +} + +/// vector of 8 unsigned 32-bit integers +struct simd8uint32 : simd256bit { + simd8uint32() {} + + explicit simd8uint32(uint32_t x) { + set1(x); + } + + explicit simd8uint32(const simd256bit& x) : simd256bit(x) {} + + explicit simd8uint32(const uint32_t* x) : simd256bit((const void*)x) {} + + explicit simd8uint32( + uint32_t u0, + uint32_t u1, + uint32_t u2, + uint32_t u3, + uint32_t u4, + uint32_t u5, + uint32_t u6, + uint32_t u7) { + u32[0] = u0; + u32[1] = u1; + u32[2] = u2; + u32[3] = u3; + u32[4] = u4; + u32[5] = u5; + u32[6] = u6; + u32[7] = u7; + } + + simd8uint32 operator+(simd8uint32 other) const { + simd8uint32 result; + for (int i = 0; i < 8; i++) { + result.u32[i] = u32[i] + other.u32[i]; + } + return result; + } + + simd8uint32 operator-(simd8uint32 other) const { + simd8uint32 result; + for (int i = 0; i < 8; i++) { + result.u32[i] = u32[i] - other.u32[i]; + } + return result; + } + + simd8uint32& operator+=(const simd8uint32& other) { + for (int i = 0; i < 8; i++) { + u32[i] += other.u32[i]; + } + return *this; + } + + bool operator==(simd8uint32 other) const { + for (size_t i = 0; i < 8; i++) { + if (u32[i] != other.u32[i]) { + return false; + } + } + + return true; + } + + bool operator!=(simd8uint32 other) const { + return !(*this == other); + } + + std::string elements_to_string(const char* fmt) const { + char res[1000], *ptr = res; + for (int i = 0; i < 8; i++) { + ptr += sprintf(ptr, fmt, u32[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } + + std::string hex() const { + return elements_to_string("%08x,"); + } + + std::string dec() const { + return elements_to_string("%10d,"); + } + + void set1(uint32_t x) { + for (int i = 0; i < 8; i++) { + u32[i] = x; + } + } + + simd8uint32 unzip() const { + const uint32_t ret[] = { + u32[0], u32[2], u32[4], u32[6], u32[1], u32[3], u32[5], u32[7]}; + return simd8uint32{ret}; + } +}; + +// Vectorized version of the following code: +// for (size_t i = 0; i < n; i++) { +// bool flag = (candidateValues[i] < currentValues[i]); +// minValues[i] = flag ? candidateValues[i] : currentValues[i]; +// minIndices[i] = flag ? candidateIndices[i] : currentIndices[i]; +// maxValues[i] = !flag ? candidateValues[i] : currentValues[i]; +// maxIndices[i] = !flag ? candidateIndices[i] : currentIndices[i]; +// } +// Max indices evaluation is inaccurate in case of equal values (the index of +// the last equal value is saved instead of the first one), but this behavior +// saves instructions. +inline void cmplt_min_max_fast( + const simd8uint32 candidateValues, + const simd8uint32 candidateIndices, + const simd8uint32 currentValues, + const simd8uint32 currentIndices, + simd8uint32& minValues, + simd8uint32& minIndices, + simd8uint32& maxValues, + simd8uint32& maxIndices) { + for (size_t i = 0; i < 8; i++) { + bool flag = (candidateValues.u32[i] < currentValues.u32[i]); + minValues.u32[i] = flag ? candidateValues.u32[i] : currentValues.u32[i]; + minIndices.u32[i] = + flag ? candidateIndices.u32[i] : currentIndices.u32[i]; + maxValues.u32[i] = + !flag ? candidateValues.u32[i] : currentValues.u32[i]; + maxIndices.u32[i] = + !flag ? candidateIndices.u32[i] : currentIndices.u32[i]; + } +} + +struct simd8float32 : simd256bit { + simd8float32() {} + + explicit simd8float32(const simd256bit& x) : simd256bit(x) {} + + explicit simd8float32(float x) { + set1(x); + } + + explicit simd8float32(const float* x) { + loadu((void*)x); + } + + void set1(float x) { + for (int i = 0; i < 8; i++) { + f32[i] = x; + } + } + + explicit simd8float32( + float f0, + float f1, + float f2, + float f3, + float f4, + float f5, + float f6, + float f7) { + f32[0] = f0; + f32[1] = f1; + f32[2] = f2; + f32[3] = f3; + f32[4] = f4; + f32[5] = f5; + f32[6] = f6; + f32[7] = f7; + } + + template + static simd8float32 binary_func( + const simd8float32& a, + const simd8float32& b, + F&& f) { + simd8float32 c; + for (int j = 0; j < 8; j++) { + c.f32[j] = f(a.f32[j], b.f32[j]); + } + return c; + } + + simd8float32 operator*(const simd8float32& other) const { + return binary_func( + *this, other, [](float a, float b) { return a * b; }); + } + + simd8float32 operator+(const simd8float32& other) const { + return binary_func( + *this, other, [](float a, float b) { return a + b; }); + } + + simd8float32 operator-(const simd8float32& other) const { + return binary_func( + *this, other, [](float a, float b) { return a - b; }); + } + + simd8float32& operator+=(const simd8float32& other) { + for (size_t i = 0; i < 8; i++) { + f32[i] += other.f32[i]; + } + + return *this; + } + + bool operator==(simd8float32 other) const { + for (size_t i = 0; i < 8; i++) { + if (f32[i] != other.f32[i]) { + return false; + } + } + + return true; + } + + bool operator!=(simd8float32 other) const { + return !(*this == other); + } + + std::string tostring() const { + char res[1000], *ptr = res; + for (int i = 0; i < 8; i++) { + ptr += sprintf(ptr, "%g,", f32[i]); + } + // strip last , + ptr[-1] = 0; + return std::string(res); + } +}; + +// hadd does not cross lanes +inline simd8float32 hadd(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + c.f32[0] = a.f32[0] + a.f32[1]; + c.f32[1] = a.f32[2] + a.f32[3]; + c.f32[2] = b.f32[0] + b.f32[1]; + c.f32[3] = b.f32[2] + b.f32[3]; + + c.f32[4] = a.f32[4] + a.f32[5]; + c.f32[5] = a.f32[6] + a.f32[7]; + c.f32[6] = b.f32[4] + b.f32[5]; + c.f32[7] = b.f32[6] + b.f32[7]; + + return c; +} + +inline simd8float32 unpacklo(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + c.f32[0] = a.f32[0]; + c.f32[1] = b.f32[0]; + c.f32[2] = a.f32[1]; + c.f32[3] = b.f32[1]; + + c.f32[4] = a.f32[4]; + c.f32[5] = b.f32[4]; + c.f32[6] = a.f32[5]; + c.f32[7] = b.f32[5]; + + return c; +} + +inline simd8float32 unpackhi(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + c.f32[0] = a.f32[2]; + c.f32[1] = b.f32[2]; + c.f32[2] = a.f32[3]; + c.f32[3] = b.f32[3]; + + c.f32[4] = a.f32[6]; + c.f32[5] = b.f32[6]; + c.f32[6] = a.f32[7]; + c.f32[7] = b.f32[7]; + + return c; +} + +// compute a * b + c +inline simd8float32 fmadd( + const simd8float32& a, + const simd8float32& b, + const simd8float32& c) { + simd8float32 res; + for (int i = 0; i < 8; i++) { + res.f32[i] = a.f32[i] * b.f32[i] + c.f32[i]; + } + return res; +} + +namespace { + +// get even float32's of a and b, interleaved +simd8float32 geteven(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + + c.f32[0] = a.f32[0]; + c.f32[1] = a.f32[2]; + c.f32[2] = b.f32[0]; + c.f32[3] = b.f32[2]; + + c.f32[4] = a.f32[4]; + c.f32[5] = a.f32[6]; + c.f32[6] = b.f32[4]; + c.f32[7] = b.f32[6]; + + return c; +} + +// get odd float32's of a and b, interleaved +simd8float32 getodd(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + + c.f32[0] = a.f32[1]; + c.f32[1] = a.f32[3]; + c.f32[2] = b.f32[1]; + c.f32[3] = b.f32[3]; + + c.f32[4] = a.f32[5]; + c.f32[5] = a.f32[7]; + c.f32[6] = b.f32[5]; + c.f32[7] = b.f32[7]; + + return c; +} + +// 3 cycles +// if the lanes are a = [a0 a1] and b = [b0 b1], return [a0 b0] +simd8float32 getlow128(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + + c.f32[0] = a.f32[0]; + c.f32[1] = a.f32[1]; + c.f32[2] = a.f32[2]; + c.f32[3] = a.f32[3]; + + c.f32[4] = b.f32[0]; + c.f32[5] = b.f32[1]; + c.f32[6] = b.f32[2]; + c.f32[7] = b.f32[3]; + + return c; +} + +simd8float32 gethigh128(const simd8float32& a, const simd8float32& b) { + simd8float32 c; + + c.f32[0] = a.f32[4]; + c.f32[1] = a.f32[5]; + c.f32[2] = a.f32[6]; + c.f32[3] = a.f32[7]; + + c.f32[4] = b.f32[4]; + c.f32[5] = b.f32[5]; + c.f32[6] = b.f32[6]; + c.f32[7] = b.f32[7]; + + return c; +} + +// The following primitive is a vectorized version of the following code +// snippet: +// float lowestValue = HUGE_VAL; +// uint lowestIndex = 0; +// for (size_t i = 0; i < n; i++) { +// if (values[i] < lowestValue) { +// lowestValue = values[i]; +// lowestIndex = i; +// } +// } +// Vectorized version can be implemented via two operations: cmp and blend +// with something like this: +// lowestValues = [HUGE_VAL; 8]; +// lowestIndices = {0, 1, 2, 3, 4, 5, 6, 7}; +// for (size_t i = 0; i < n; i += 8) { +// auto comparison = cmp(values + i, lowestValues); +// lowestValues = blend( +// comparison, +// values + i, +// lowestValues); +// lowestIndices = blend( +// comparison, +// i + {0, 1, 2, 3, 4, 5, 6, 7}, +// lowestIndices); +// lowestIndices += {8, 8, 8, 8, 8, 8, 8, 8}; +// } +// The problem is that blend primitive needs very different instruction +// order for AVX and ARM. +// So, let's introduce a combination of these two in order to avoid +// confusion for ppl who write in low-level SIMD instructions. Additionally, +// these two ops (cmp and blend) are very often used together. +inline void cmplt_and_blend_inplace( + const simd8float32 candidateValues, + const simd8uint32 candidateIndices, + simd8float32& lowestValues, + simd8uint32& lowestIndices) { + for (size_t j = 0; j < 8; j++) { + bool comparison = (candidateValues.f32[j] < lowestValues.f32[j]); + if (comparison) { + lowestValues.f32[j] = candidateValues.f32[j]; + lowestIndices.u32[j] = candidateIndices.u32[j]; + } + } +} + +// Vectorized version of the following code: +// for (size_t i = 0; i < n; i++) { +// bool flag = (candidateValues[i] < currentValues[i]); +// minValues[i] = flag ? candidateValues[i] : currentValues[i]; +// minIndices[i] = flag ? candidateIndices[i] : currentIndices[i]; +// maxValues[i] = !flag ? candidateValues[i] : currentValues[i]; +// maxIndices[i] = !flag ? candidateIndices[i] : currentIndices[i]; +// } +// Max indices evaluation is inaccurate in case of equal values (the index of +// the last equal value is saved instead of the first one), but this behavior +// saves instructions. +inline void cmplt_min_max_fast( + const simd8float32 candidateValues, + const simd8uint32 candidateIndices, + const simd8float32 currentValues, + const simd8uint32 currentIndices, + simd8float32& minValues, + simd8uint32& minIndices, + simd8float32& maxValues, + simd8uint32& maxIndices) { + for (size_t i = 0; i < 8; i++) { + bool flag = (candidateValues.f32[i] < currentValues.f32[i]); + minValues.f32[i] = flag ? candidateValues.f32[i] : currentValues.f32[i]; + minIndices.u32[i] = + flag ? candidateIndices.u32[i] : currentIndices.u32[i]; + maxValues.f32[i] = + !flag ? candidateValues.f32[i] : currentValues.f32[i]; + maxIndices.u32[i] = + !flag ? candidateIndices.u32[i] : currentIndices.u32[i]; + } +} + +} // namespace + +} // namespace faiss From 67574aabbcb76893498f3116509e90434db76379 Mon Sep 17 00:00:00 2001 From: Aditya Vidyadhar Kamath Date: Wed, 24 Apr 2024 05:40:49 -0700 Subject: [PATCH 132/206] Fix the endianness issue in AIX while running the benchmark. (#3345) Summary: This pull request is for issue https://github.com/facebookresearch/faiss/issues/3330. This patch makes sure that packed code arrays are in big endian format. Kindly let us know if we need any changes or if we can have a better approach. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3345 Reviewed By: junjieqi Differential Revision: D55957630 Pulled By: mdouze fbshipit-source-id: f728f9563f6b942af9d8899b54662d7ceb811206 --- contrib/vecs_io.py | 3 + faiss/cppcontrib/detail/UintReader.h | 112 +++++++++++++++++++---- faiss/cppcontrib/sa_decode/Level2-inl.h | 113 +++++++++++++++++------- faiss/impl/platform_macros.h | 14 +++ faiss/impl/pq4_fast_scan.cpp | 11 +++ faiss/python/CMakeLists.txt | 13 +++ 6 files changed, 219 insertions(+), 47 deletions(-) diff --git a/contrib/vecs_io.py b/contrib/vecs_io.py index ea75d5f94d..cd16a2b73d 100644 --- a/contrib/vecs_io.py +++ b/contrib/vecs_io.py @@ -3,6 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +import sys import numpy as np """ @@ -13,6 +14,8 @@ def ivecs_read(fname): a = np.fromfile(fname, dtype='int32') + if sys.byteorder == 'big': + a.byteswap(inplace=True) d = a[0] return a.reshape(-1, d + 1)[:, 1:].copy() diff --git a/faiss/cppcontrib/detail/UintReader.h b/faiss/cppcontrib/detail/UintReader.h index 81e600f410..4a64a1a254 100644 --- a/faiss/cppcontrib/detail/UintReader.h +++ b/faiss/cppcontrib/detail/UintReader.h @@ -7,6 +7,7 @@ #pragma once +#include #include namespace faiss { @@ -31,7 +32,11 @@ struct Uint8Reader { if (N_ELEMENTS > CPOS + 3) { const uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + return (code32) >> 24; +#else return (code32 & 0x000000FF); +#endif } else { return codes[CPOS]; } @@ -40,7 +45,11 @@ struct Uint8Reader { if (N_ELEMENTS > CPOS + 2) { const uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + return (code32 & 0x00FF0000) >> 16; +#else return (code32 & 0x0000FF00) >> 8; +#endif } else { return codes[CPOS]; } @@ -49,7 +58,11 @@ struct Uint8Reader { if (N_ELEMENTS > CPOS + 1) { const uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + return (code32 & 0x0000FF00) >> 8; +#else return (code32 & 0x00FF0000) >> 16; +#endif } else { return codes[CPOS]; } @@ -58,7 +71,11 @@ struct Uint8Reader { if (N_ELEMENTS > CPOS) { const uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + return (code32 & 0x000000FF); +#else return (code32) >> 24; +#endif } else { return codes[CPOS]; } @@ -87,40 +104,61 @@ struct Uint10Reader { switch (SUB_ELEMENT) { case 0: { if (N_ELEMENTS > CPOS + 2) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b0000001111111111); } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5 + 0); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b0000001111111111); } } case 1: { if (N_ELEMENTS > CPOS + 1) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b000011111111110000000000) >> 10; } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5 + 1); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b0000111111111100) >> 2; } } case 2: { if (N_ELEMENTS > CPOS) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b00111111111100000000000000000000) >> 20; } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5 + 2); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b0011111111110000) >> 4; } } case 3: { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 5 + 3); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b1111111111000000) >> 6; } } @@ -147,45 +185,69 @@ struct Uint12Reader { switch (SUB_ELEMENT) { case 0: { if (N_ELEMENTS > CPOS + 2) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b0000111111111111); } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 0); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b0000111111111111); } } case 1: { if (N_ELEMENTS > CPOS + 1) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b111111111111000000000000) >> 12; } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 1); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b1111111111110000) >> 4; } } case 2: { if (N_ELEMENTS > CPOS + 1) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 2); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b000011111111111100000000) >> 8; } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 3); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b0000111111111111); } } case 3: { if (N_ELEMENTS > CPOS) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 2); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0b11111111111100000000000000000000) >> 20; } else { - const uint16_t code16 = *reinterpret_cast( + uint16_t code16 = *reinterpret_cast( codes + ELEMENT_TO_READ * 6 + 4); +#ifdef FAISS_BIG_ENDIAN + code16 = Swap2Bytes(code16); +#endif return (code16 & 0b1111111111110000) >> 4; } } @@ -208,23 +270,39 @@ struct Uint16Reader { switch (SUB_ELEMENT) { case 0: { if (N_ELEMENTS > CPOS + 1) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return (code32 & 0x0000FFFF); } else { const uint16_t* const __restrict codesFp16 = reinterpret_cast(codes); +#ifdef FAISS_BIG_ENDIAN + uint16_t rt = codesFp16[CPOS]; + rt = Swap2Bytes(rt); + return rt; +#endif return codesFp16[CPOS]; } } case 1: { if (N_ELEMENTS > CPOS) { - const uint32_t code32 = *reinterpret_cast( + uint32_t code32 = *reinterpret_cast( codes + ELEMENT_TO_READ * 4); +#ifdef FAISS_BIG_ENDIAN + code32 = Swap4Bytes(code32); +#endif return code32 >> 16; } else { const uint16_t* const __restrict codesFp16 = reinterpret_cast(codes); +#ifdef FAISS_BIG_ENDIAN + uint16_t rt = codesFp16[CPOS]; + rt = Swap2Bytes(rt); + return rt; +#endif return codesFp16[CPOS]; } } diff --git a/faiss/cppcontrib/sa_decode/Level2-inl.h b/faiss/cppcontrib/sa_decode/Level2-inl.h index 36355af001..1eb7767ba8 100644 --- a/faiss/cppcontrib/sa_decode/Level2-inl.h +++ b/faiss/cppcontrib/sa_decode/Level2-inl.h @@ -12,10 +12,19 @@ #include #include +#include namespace faiss { namespace cppcontrib { +bool isBigEndian() { +#ifdef FAISS_BIG_ENDIAN + return true; +#else + return false; +#endif +} + //////////////////////////////////////////////////////////////////////////////////// /// Index2LevelDecoder //////////////////////////////////////////////////////////////////////////////////// @@ -72,9 +81,14 @@ struct Index2LevelDecoder { const intptr_t coarseCentroidOffset = i % COARSE_SIZE; const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - - const intptr_t coarseCode = coarse[coarseCentroidIdx]; - const intptr_t fineCode = fine[fineCentroidIdx]; + intptr_t coarseCode, fineCode; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode = Swap2Bytes(coarse[coarseCentroidIdx]); + fineCode = Swap2Bytes(fine[fineCentroidIdx]); + } else { + coarseCode = coarse[coarseCentroidIdx]; + fineCode = fine[fineCentroidIdx]; + } const float* const __restrict coarsePtr = pqCoarseCentroids + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode) * @@ -112,9 +126,14 @@ struct Index2LevelDecoder { const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - const intptr_t coarseCode = coarse[coarseCentroidIdx]; - const intptr_t fineCode = fine[fineCentroidIdx]; - + intptr_t coarseCode, fineCode; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode = Swap2Bytes(coarse[coarseCentroidIdx]); + fineCode = Swap2Bytes(fine[fineCentroidIdx]); + } else { + coarseCode = coarse[coarseCentroidIdx]; + fineCode = fine[fineCentroidIdx]; + } const float* const __restrict coarsePtr = pqCoarseCentroids + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode) * COARSE_SIZE + @@ -162,11 +181,18 @@ struct Index2LevelDecoder { const intptr_t coarseCentroidOffset = i % COARSE_SIZE; const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - - const intptr_t coarseCode0 = coarse0[coarseCentroidIdx]; - const intptr_t fineCode0 = fine0[fineCentroidIdx]; - const intptr_t coarseCode1 = coarse1[coarseCentroidIdx]; - const intptr_t fineCode1 = fine1[fineCentroidIdx]; + intptr_t coarseCode0, coarseCode1, fineCode0, fineCode1; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode0 = Swap2Bytes(coarse0[coarseCentroidIdx]); + fineCode0 = Swap2Bytes(fine0[fineCentroidIdx]); + coarseCode1 = Swap2Bytes(coarse1[coarseCentroidIdx]); + fineCode1 = Swap2Bytes(fine1[fineCentroidIdx]); + } else { + coarseCode0 = coarse0[coarseCentroidIdx]; + fineCode0 = fine0[fineCentroidIdx]; + coarseCode1 = coarse1[coarseCentroidIdx]; + fineCode1 = fine1[fineCentroidIdx]; + } const float* const __restrict coarsePtr0 = pqCoarseCentroids0 + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) * @@ -222,11 +248,18 @@ struct Index2LevelDecoder { const intptr_t coarseCentroidOffset = i % COARSE_SIZE; const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - - const intptr_t coarseCode0 = coarse0[coarseCentroidIdx]; - const intptr_t fineCode0 = fine0[fineCentroidIdx]; - const intptr_t coarseCode1 = coarse1[coarseCentroidIdx]; - const intptr_t fineCode1 = fine1[fineCentroidIdx]; + intptr_t coarseCode0, coarseCode1, fineCode0, fineCode1; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode0 = Swap2Bytes(coarse0[coarseCentroidIdx]); + fineCode0 = Swap2Bytes(fine0[fineCentroidIdx]); + coarseCode1 = Swap2Bytes(coarse1[coarseCentroidIdx]); + fineCode1 = Swap2Bytes(fine1[fineCentroidIdx]); + } else { + coarseCode0 = coarse0[coarseCentroidIdx]; + fineCode0 = fine0[fineCentroidIdx]; + coarseCode1 = coarse1[coarseCentroidIdx]; + fineCode1 = fine1[fineCentroidIdx]; + } const float* const __restrict coarsePtr0 = pqCoarseCentroids + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) * @@ -292,13 +325,23 @@ struct Index2LevelDecoder { const intptr_t coarseCentroidOffset = i % COARSE_SIZE; const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - - const intptr_t coarseCode0 = coarse0[coarseCentroidIdx]; - const intptr_t fineCode0 = fine0[fineCentroidIdx]; - const intptr_t coarseCode1 = coarse1[coarseCentroidIdx]; - const intptr_t fineCode1 = fine1[fineCentroidIdx]; - const intptr_t coarseCode2 = coarse2[coarseCentroidIdx]; - const intptr_t fineCode2 = fine2[fineCentroidIdx]; + intptr_t coarseCode0, coarseCode1, fineCode0, fineCode1; + intptr_t coarseCode2, fineCode2; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode0 = Swap2Bytes(coarse0[coarseCentroidIdx]); + fineCode0 = Swap2Bytes(fine0[fineCentroidIdx]); + coarseCode1 = Swap2Bytes(coarse1[coarseCentroidIdx]); + fineCode1 = Swap2Bytes(fine1[fineCentroidIdx]); + coarseCode2 = Swap2Bytes(coarse2[coarseCentroidIdx]); + fineCode2 = Swap2Bytes(fine2[fineCentroidIdx]); + } else { + coarseCode0 = coarse0[coarseCentroidIdx]; + fineCode0 = fine0[fineCentroidIdx]; + coarseCode1 = coarse1[coarseCentroidIdx]; + fineCode1 = fine1[fineCentroidIdx]; + coarseCode2 = coarse2[coarseCentroidIdx]; + fineCode2 = fine2[fineCentroidIdx]; + } const float* const __restrict coarsePtr0 = pqCoarseCentroids0 + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) * @@ -369,13 +412,23 @@ struct Index2LevelDecoder { const intptr_t coarseCentroidOffset = i % COARSE_SIZE; const intptr_t fineCentroidIdx = i / FINE_SIZE; const intptr_t fineCentroidOffset = i % FINE_SIZE; - - const intptr_t coarseCode0 = coarse0[coarseCentroidIdx]; - const intptr_t fineCode0 = fine0[fineCentroidIdx]; - const intptr_t coarseCode1 = coarse1[coarseCentroidIdx]; - const intptr_t fineCode1 = fine1[fineCentroidIdx]; - const intptr_t coarseCode2 = coarse2[coarseCentroidIdx]; - const intptr_t fineCode2 = fine2[fineCentroidIdx]; + intptr_t coarseCode0, fineCode0, coarseCode1, fineCode1; + intptr_t coarseCode2, fineCode2; + if (isBigEndian() && sizeof(coarse_storage_type) == 2) { + coarseCode0 = Swap2Bytes(coarse0[coarseCentroidIdx]); + fineCode0 = Swap2Bytes(fine0[fineCentroidIdx]); + coarseCode1 = Swap2Bytes(coarse1[coarseCentroidIdx]); + fineCode1 = Swap2Bytes(fine1[fineCentroidIdx]); + coarseCode2 = Swap2Bytes(coarse2[coarseCentroidIdx]); + fineCode2 = Swap2Bytes(fine2[fineCentroidIdx]); + } else { + coarseCode0 = coarse0[coarseCentroidIdx]; + fineCode0 = fine0[fineCentroidIdx]; + coarseCode1 = coarse1[coarseCentroidIdx]; + fineCode1 = fine1[fineCentroidIdx]; + coarseCode2 = coarse2[coarseCentroidIdx]; + fineCode2 = fine2[fineCentroidIdx]; + } const float* const __restrict coarsePtr0 = pqCoarseCentroids + (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) * diff --git a/faiss/impl/platform_macros.h b/faiss/impl/platform_macros.h index 2aecc51222..a0faea7cba 100644 --- a/faiss/impl/platform_macros.h +++ b/faiss/impl/platform_macros.h @@ -165,3 +165,17 @@ inline int __builtin_clzll(uint64_t x) { #endif // clang-format on + +/******************************************************* + * BIGENDIAN specific macros + *******************************************************/ +#if !defined(_MSC_VER) && \ + (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) +#define FAISS_BIG_ENDIAN +#endif + +#define Swap2Bytes(val) ((((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00)) + +#define Swap4Bytes(val) \ + ((((val) >> 24) & 0x000000FF) | (((val) >> 8) & 0x0000FF00) | \ + (((val) << 8) & 0x00FF0000) | (((val) << 24) & 0xFF000000)) diff --git a/faiss/impl/pq4_fast_scan.cpp b/faiss/impl/pq4_fast_scan.cpp index 6173ecef47..127646e0eb 100644 --- a/faiss/impl/pq4_fast_scan.cpp +++ b/faiss/impl/pq4_fast_scan.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -58,8 +59,13 @@ void pq4_pack_codes( return; } memset(blocks, 0, nb * nsq / 2); +#ifdef FAISS_BIG_ENDIAN + const uint8_t perm0[16] = { + 8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7}; +#else const uint8_t perm0[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}; +#endif uint8_t* codes2 = blocks; for (size_t i0 = 0; i0 < nb; i0 += bbs) { @@ -93,8 +99,13 @@ void pq4_pack_codes_range( size_t bbs, size_t nsq, uint8_t* blocks) { +#ifdef FAISS_BIG_ENDIAN + const uint8_t perm0[16] = { + 8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7}; +#else const uint8_t perm0[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}; +#endif // range of affected blocks size_t block0 = i0 / bbs; diff --git a/faiss/python/CMakeLists.txt b/faiss/python/CMakeLists.txt index 8bca710f5f..dee8c7762e 100644 --- a/faiss/python/CMakeLists.txt +++ b/faiss/python/CMakeLists.txt @@ -67,11 +67,20 @@ else() find_package(faiss REQUIRED) endif() +if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") +swig_add_library(swigfaiss + TYPE MODULE + LANGUAGE python + SOURCES swigfaiss.swig +) +else () swig_add_library(swigfaiss TYPE SHARED LANGUAGE python SOURCES swigfaiss.swig ) +endif() + set_property(TARGET swigfaiss PROPERTY SWIG_COMPILE_OPTIONS -doxygen) set_property(SOURCE swigfaiss_avx2.swig @@ -160,6 +169,10 @@ set_property(TARGET faiss_python_callbacks PROPERTY POSITION_INDEPENDENT_CODE ON ) +if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") +target_link_libraries(faiss_python_callbacks PRIVATE faiss) +endif() + # Hack so that python_callbacks.h can be included as # `#include `. target_include_directories(faiss_python_callbacks PRIVATE ${PROJECT_SOURCE_DIR}/../..) From 783e044a2dfb1f3cdd2c6e65362e496ed07b5e2c Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Wed, 24 Apr 2024 05:40:49 -0700 Subject: [PATCH 133/206] support big-endian machines (#3361) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3361 Fix a few issues in the PR. Normally all tests should pass on a litlle-endian machine Reviewed By: junjieqi Differential Revision: D56003181 fbshipit-source-id: 405dec8c71898494f5ddcd2718c35708a1abf9cb --- contrib/vecs_io.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/contrib/vecs_io.py b/contrib/vecs_io.py index cd16a2b73d..5d18c0b162 100644 --- a/contrib/vecs_io.py +++ b/contrib/vecs_io.py @@ -14,8 +14,8 @@ def ivecs_read(fname): a = np.fromfile(fname, dtype='int32') - if sys.byteorder == 'big': - a.byteswap(inplace=True) + if sys.big_endian: + a.byteswap(inplace=True) d = a[0] return a.reshape(-1, d + 1)[:, 1:].copy() @@ -25,6 +25,7 @@ def fvecs_read(fname): def ivecs_mmap(fname): + assert not sys.big_endian a = np.memmap(fname, dtype='int32', mode='r') d = a[0] return a.reshape(-1, d + 1)[:, 1:] @@ -36,7 +37,11 @@ def fvecs_mmap(fname): def bvecs_mmap(fname): x = np.memmap(fname, dtype='uint8', mode='r') - d = x[:4].view('int32')[0] + if sys.big_endian: + da = x[:4][::-1].copy() + d = da.view('int32')[0] + else: + d = x[:4].view('int32')[0] return x.reshape(-1, d + 4)[:, 4:] @@ -45,6 +50,8 @@ def ivecs_write(fname, m): m1 = np.empty((n, d + 1), dtype='int32') m1[:, 0] = d m1[:, 1:] = m + if sys.big_endian: + m1.byteswap(inplace=True) m1.tofile(fname) From 2379b45f827047182d424b76e7cb454a1929fa7a Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Wed, 24 Apr 2024 09:42:05 -0700 Subject: [PATCH 134/206] Few fixes in bench_fw to enable IndexFromCodec (#3383) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3383 In this diff, I am fixing minor issues in bench_fw where either certain fields are not accessible when index is build from codec. It also requires index to be discovered using codec alias as index factory is not always available. In subsequent diff internal to meta will have testcase that execute this path. Reviewed By: algoriddle Differential Revision: D56444641 fbshipit-source-id: b7af7e7bb47b20bbb5515a66f41dd24f42459d52 --- benchs/bench_fw/benchmark.py | 9 ++++++--- benchs/bench_fw/descriptors.py | 1 + benchs/bench_fw/index.py | 10 ++++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/benchs/bench_fw/benchmark.py b/benchs/bench_fw/benchmark.py index 1053f99388..8ca68c4cd8 100644 --- a/benchs/bench_fw/benchmark.py +++ b/benchs/bench_fw/benchmark.py @@ -208,9 +208,11 @@ def set_io(self, benchmark_io): self.io.distance_metric = self.distance_metric self.io.distance_metric_type = self.distance_metric_type - def get_index_desc(self, factory: str) -> Optional[IndexDescriptor]: + def get_index_desc(self, factory_or_codec: str) -> Optional[IndexDescriptor]: for desc in self.index_descs: - if desc.factory == factory: + if desc.factory == factory_or_codec: + return desc + if desc.codec_alias == factory_or_codec: return desc return None @@ -232,7 +234,7 @@ def range_search_reference(self, index, parameters, range_metric): parameters, radius=m_radius, ) - flat = index.factory == "Flat" + flat = index.is_flat_index() ( gt_radius, range_search_metric_function, @@ -650,6 +652,7 @@ def benchmark( f"Range index {index_desc.factory} has no radius_score" ) results["metrics"] = {} + self.build_index_wrapper(index_desc) for metric_key, range_metric in index_desc.range_metrics.items(): ( gt_radius, diff --git a/benchs/bench_fw/descriptors.py b/benchs/bench_fw/descriptors.py index f1dd7354c2..173b07ce16 100644 --- a/benchs/bench_fw/descriptors.py +++ b/benchs/bench_fw/descriptors.py @@ -20,6 +20,7 @@ class IndexDescriptor: # but not both at the same time. path: Optional[str] = None factory: Optional[str] = None + codec_alias: Optional[str] = None construction_params: Optional[List[Dict[str, int]]] = None search_params: Optional[Dict[str, int]] = None # range metric definitions diff --git a/benchs/bench_fw/index.py b/benchs/bench_fw/index.py index 14f2158e64..3deaa4afcf 100644 --- a/benchs/bench_fw/index.py +++ b/benchs/bench_fw/index.py @@ -495,7 +495,7 @@ def range_search( radius: Optional[float] = None, ): logger.info("range_search: begin") - if search_parameters is not None and search_parameters["snap"] == 1: + if search_parameters is not None and search_parameters.get("snap") == 1: query_vectors = self.snap(query_vectors) filename = ( self.get_range_search_name( @@ -776,6 +776,9 @@ def add_range_or_val(name, range): ) return op + def is_flat_index(self): + return self.get_index_name().startswith("Flat") + # IndexFromCodec, IndexFromQuantizer and IndexFromPreTransform # are used to wrap pre-trained Faiss indices (codecs) @@ -807,6 +810,9 @@ def get_codec_name(self): name += Index.param_dict_list_to_name(self.construction_params) return name + def fetch_meta(self, dry_run=False): + return None, None + def fetch_codec(self): codec = self.io.read_index( os.path.basename(self.path), @@ -911,7 +917,7 @@ def fetch_codec(self, dry_run=False): assert codec_size is not None meta = { "training_time": training_time, - "training_size": self.training_vectors.num_vectors, + "training_size": self.training_vectors.num_vectors if self.training_vectors else 0, "codec_size": codec_size, "sa_code_size": self.get_sa_code_size(codec), "code_size": self.get_code_size(codec), From 03750f51419e9a2c6b5c533c2e6fbc837bdb646a Mon Sep 17 00:00:00 2001 From: Amir Sadoughi Date: Wed, 24 Apr 2024 14:11:02 -0700 Subject: [PATCH 135/206] Fix IndexBinary.assign Python method Summary: Fixes #3343 Reviewed By: kuarora, junjieqi Differential Revision: D56526842 fbshipit-source-id: b7c4377495db4e68283cf4ce2b7c8fae008cd404 --- faiss/python/class_wrappers.py | 34 ++++++++++++++++++++++++++++++++++ tests/test_index_binary.py | 3 +++ 2 files changed, 37 insertions(+) diff --git a/faiss/python/class_wrappers.py b/faiss/python/class_wrappers.py index 4a6808d286..4af2345009 100644 --- a/faiss/python/class_wrappers.py +++ b/faiss/python/class_wrappers.py @@ -956,10 +956,44 @@ def replacement_remove_ids(self, x): sel = IDSelectorBatch(x.size, swig_ptr(x)) return self.remove_ids_c(sel) + def replacement_assign(self, x, k, labels=None): + """Find the k nearest neighbors of the set of vectors x in the index. + This is the same as the `search` method, but discards the distances. + + Parameters + ---------- + x : array_like + Query vectors, shape (n, d) where d is appropriate for the index. + `dtype` must be uint8. + k : int + Number of nearest neighbors. + labels : array_like, optional + Labels array to store the results. + + Returns + ------- + labels: array_like + Labels of the nearest neighbors, shape (n, k). + When not enough results are found, the label is set to -1 + """ + n, d = x.shape + x = _check_dtype_uint8(x) + assert d == self.code_size + assert k > 0 + + if labels is None: + labels = np.empty((n, k), dtype=np.int64) + else: + assert labels.shape == (n, k) + + self.assign_c(n, swig_ptr(x), swig_ptr(labels), k) + return labels + replace_method(the_class, 'add', replacement_add) replace_method(the_class, 'add_with_ids', replacement_add_with_ids) replace_method(the_class, 'train', replacement_train) replace_method(the_class, 'search', replacement_search) + replace_method(the_class, 'assign', replacement_assign) replace_method(the_class, 'range_search', replacement_range_search) replace_method(the_class, 'reconstruct', replacement_reconstruct) replace_method(the_class, 'reconstruct_n', replacement_reconstruct_n) diff --git a/tests/test_index_binary.py b/tests/test_index_binary.py index b505e0ba1c..3acf622fd4 100644 --- a/tests/test_index_binary.py +++ b/tests/test_index_binary.py @@ -100,6 +100,9 @@ def test_flat(self): index.add(self.xb) D, I = index.search(self.xq, 3) + I2 = index.assign(x=self.xq, k=3, labels=None) + assert np.all(I == I2) + for i in range(nq): for j, dj in zip(I[i], D[i]): ref_dis = binary_dis(self.xq[i], self.xb[j]) From bd22c936e108d4551648435764b126aef40b4530 Mon Sep 17 00:00:00 2001 From: Junjie Qi Date: Thu, 25 Apr 2024 02:51:55 -0700 Subject: [PATCH 136/206] Fix swig osx (#3357) Summary: The osx failed https://app.circleci.com/pipelines/github/facebookresearch/faiss/5698/workflows/4e029c32-8d8b-4db7-99e2-8e802aad6653/jobs/32701 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3357 Reviewed By: kuarora Differential Revision: D56039739 Pulled By: junjieqi fbshipit-source-id: dd434a8817148364797eae39c09e0e1e9edbe858 --- faiss/python/swigfaiss.swig | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/faiss/python/swigfaiss.swig b/faiss/python/swigfaiss.swig index 0ea93609e3..5c9a7b3fa7 100644 --- a/faiss/python/swigfaiss.swig +++ b/faiss/python/swigfaiss.swig @@ -1022,14 +1022,17 @@ PyObject *swig_ptr (PyObject *a) return SWIG_NewPointerObj(data, SWIGTYPE_p_bool, 0); } if(PyArray_TYPE(ao) == NPY_UINT64) { -#if (__SIZEOF_LONG__ == 8) + // Convert npy64 either long or long long and it depends on how compiler define int64_t. + // In the 64bit machine, typically the int64_t should be long but it is not hold for Apple osx. + // In this case, we want to convert npy64 to long_Long in osx +#if __SIZEOF_LONG__ == 8 && !defined(__APPLE__) return SWIG_NewPointerObj(data, SWIGTYPE_p_unsigned_long, 0); #else return SWIG_NewPointerObj(data, SWIGTYPE_p_unsigned_long_long, 0); #endif } if(PyArray_TYPE(ao) == NPY_INT64) { -#if (__SIZEOF_LONG__ == 8) +#if __SIZEOF_LONG__ == 8 && !defined(__APPLE__) return SWIG_NewPointerObj(data, SWIGTYPE_p_long, 0); #else return SWIG_NewPointerObj(data, SWIGTYPE_p_long_long, 0); @@ -1054,11 +1057,8 @@ struct PythonInterruptCallback: faiss::InterruptCallback { } }; - - %} - %init %{ /* needed, else crash at runtime */ import_array(); @@ -1121,15 +1121,8 @@ int * cast_integer_to_int_ptr (int64_t x) { void * cast_integer_to_void_ptr (int64_t x) { return (void*)x; } - %} - - - - - - %inline %{ void wait() { // in gdb, use return to get out of this function From 5cbff67c7b8e0086d17466e1fecca1c3799c6430 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 26 Apr 2024 06:32:34 -0700 Subject: [PATCH 137/206] fix raft log spew Summary: Remove debugging log lines Reviewed By: mlomeli1 Differential Revision: D56626636 fbshipit-source-id: 2721b84e4e1359d1372df2b2c95cc668c6a75c3f --- faiss/gpu/GpuDistance.cu | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/faiss/gpu/GpuDistance.cu b/faiss/gpu/GpuDistance.cu index a235404b14..38a62f03bb 100644 --- a/faiss/gpu/GpuDistance.cu +++ b/faiss/gpu/GpuDistance.cu @@ -327,7 +327,7 @@ void bfKnn(GpuResourcesProvider* prov, const GpuDistanceParams& args) { int64_t, raft::col_major>> index_vec = {index.view()}; - RAFT_LOG_INFO("Invoking flat bfknn"); + brute_force::knn( handle, index_vec, @@ -354,10 +354,7 @@ void bfKnn(GpuResourcesProvider* prov, const GpuDistanceParams& args) { [] __device__(const float& a) { return powf(a, 2); }); } - RAFT_LOG_INFO("Done."); - handle.sync_stream(); - RAFT_LOG_INFO("All synced."); } else #else if (should_use_raft(args)) { From a233bc93e3815b8803fc4361a1ce128c79063e4a Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Fri, 26 Apr 2024 09:52:23 -0700 Subject: [PATCH 138/206] Demo on how to address mulitple index contents Summary: This demonstrates how to query several independent IVF indexes with a trained index in common. This avoids to duplicate the coarse quantizer and metadata in memory. On the Faiss side, it also implements a InvertedListIterator on top of the flat inverted lists, which can prove useful. Reviewed By: junjieqi Differential Revision: D56575887 fbshipit-source-id: cc3b26e952ee21f24b10169b5b614066600cf4b8 --- faiss/invlists/InvertedLists.cpp | 72 ++++++++++--- faiss/invlists/InvertedLists.h | 27 +++-- tests/CMakeLists.txt | 1 + tests/test_common_ivf_empty_index.cpp | 144 ++++++++++++++++++++++++++ 4 files changed, 218 insertions(+), 26 deletions(-) create mode 100644 tests/test_common_ivf_empty_index.cpp diff --git a/faiss/invlists/InvertedLists.cpp b/faiss/invlists/InvertedLists.cpp index cc337d004b..c2bfa2cabc 100644 --- a/faiss/invlists/InvertedLists.cpp +++ b/faiss/invlists/InvertedLists.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -24,18 +22,10 @@ InvertedListsIterator::~InvertedListsIterator() {} ******************************************/ InvertedLists::InvertedLists(size_t nlist, size_t code_size) - : nlist(nlist), code_size(code_size), use_iterator(false) {} + : nlist(nlist), code_size(code_size) {} InvertedLists::~InvertedLists() {} -bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context) - const { - return use_iterator ? !std::unique_ptr( - get_iterator(list_no, inverted_list_context)) - ->is_available() - : list_size(list_no) == 0; -} - idx_t InvertedLists::get_single_id(size_t list_no, size_t offset) const { assert(offset < list_size(list_no)); const idx_t* ids = get_ids(list_no); @@ -78,12 +68,6 @@ void InvertedLists::reset() { } } -InvertedListsIterator* InvertedLists::get_iterator( - size_t /*list_no*/, - void* /*inverted_list_context*/) const { - FAISS_THROW_MSG("get_iterator is not supported"); -} - void InvertedLists::merge_from(InvertedLists* oivf, size_t add_id) { #pragma omp parallel for for (idx_t i = 0; i < nlist; i++) { @@ -233,6 +217,54 @@ size_t InvertedLists::compute_ntotal() const { return tot; } +bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context) + const { + if (use_iterator) { + return !std::unique_ptr( + get_iterator(list_no, inverted_list_context)) + ->is_available(); + } else { + FAISS_THROW_IF_NOT(inverted_list_context == nullptr); + return list_size(list_no) == 0; + } +} + +// implemnent iterator on top of get_codes / get_ids +namespace { + +struct CodeArrayIterator : InvertedListsIterator { + size_t list_size; + size_t code_size; + InvertedLists::ScopedCodes codes; + InvertedLists::ScopedIds ids; + size_t idx = 0; + + CodeArrayIterator(const InvertedLists* il, size_t list_no) + : list_size(il->list_size(list_no)), + code_size(il->code_size), + codes(il, list_no), + ids(il, list_no) {} + + bool is_available() const override { + return idx < list_size; + } + void next() override { + idx++; + } + std::pair get_id_and_codes() override { + return {ids[idx], codes.get() + code_size * idx}; + } +}; + +} // namespace + +InvertedListsIterator* InvertedLists::get_iterator( + size_t list_no, + void* inverted_list_context) const { + FAISS_THROW_IF_NOT(inverted_list_context == nullptr); + return new CodeArrayIterator(this, list_no); +} + /***************************************** * ArrayInvertedLists implementation ******************************************/ @@ -264,6 +296,12 @@ size_t ArrayInvertedLists::list_size(size_t list_no) const { return ids[list_no].size(); } +bool ArrayInvertedLists::is_empty(size_t list_no, void* inverted_list_context) + const { + FAISS_THROW_IF_NOT(inverted_list_context == nullptr); + return ids[list_no].size() == 0; +} + const uint8_t* ArrayInvertedLists::get_codes(size_t list_no) const { assert(list_no < nlist); return codes[list_no].data(); diff --git a/faiss/invlists/InvertedLists.h b/faiss/invlists/InvertedLists.h index 90a9d65411..b24700fad1 100644 --- a/faiss/invlists/InvertedLists.h +++ b/faiss/invlists/InvertedLists.h @@ -37,7 +37,9 @@ struct InvertedListsIterator { struct InvertedLists { size_t nlist; ///< number of possible key values size_t code_size; ///< code size per vector in bytes - bool use_iterator; + + /// request to use iterator rather than get_codes / get_ids + bool use_iterator = false; InvertedLists(size_t nlist, size_t code_size); @@ -50,17 +52,9 @@ struct InvertedLists { /************************* * Read only functions */ - // check if the list is empty - bool is_empty(size_t list_no, void* inverted_list_context) const; - /// get the size of a list virtual size_t list_size(size_t list_no) const = 0; - /// get iterable for lists that use_iterator - virtual InvertedListsIterator* get_iterator( - size_t list_no, - void* inverted_list_context) const; - /** get the codes for an inverted list * must be released by release_codes * @@ -92,6 +86,18 @@ struct InvertedLists { /// a list can be -1 hence the signed long virtual void prefetch_lists(const idx_t* list_nos, int nlist) const; + /***************************************** + * Iterator interface (with context) */ + + /// check if the list is empty + virtual bool is_empty(size_t list_no, void* inverted_list_context = nullptr) + const; + + /// get iterable for lists that use_iterator + virtual InvertedListsIterator* get_iterator( + size_t list_no, + void* inverted_list_context = nullptr) const; + /************************* * writing functions */ @@ -262,6 +268,9 @@ struct ArrayInvertedLists : InvertedLists { /// permute the inverted lists, map maps new_id to old_id void permute_invlists(const idx_t* map); + bool is_empty(size_t list_no, void* inverted_list_context = nullptr) + const override; + ~ArrayInvertedLists() override; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 66ec9f74a5..443195eecb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,6 +33,7 @@ set(FAISS_TEST_SRC test_partitioning.cpp test_fastscan_perf.cpp test_disable_pq_sdc_tables.cpp + test_common_ivf_empty_index.cpp ) add_executable(faiss_test ${FAISS_TEST_SRC}) diff --git a/tests/test_common_ivf_empty_index.cpp b/tests/test_common_ivf_empty_index.cpp new file mode 100644 index 0000000000..1a99b77141 --- /dev/null +++ b/tests/test_common_ivf_empty_index.cpp @@ -0,0 +1,144 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* This demonstrates how to query several independent IVF indexes with a trained + *index in common. This avoids to duplicate the coarse quantizer and metadata + *in memory. + **/ + +namespace { + +int d = 64; + +}; // namespace + +std::vector get_random_vectors(size_t n, int seed) { + std::vector x(n * d); + faiss::rand_smooth_vectors(n, d, x.data(), seed); + seed++; + return x; +} + +/** InvetedLists implementation that dispatches the search to an InvertedList + * object that is passed in at query time */ + +struct DispatchingInvertedLists : faiss::ReadOnlyInvertedLists { + DispatchingInvertedLists(size_t nlist, size_t code_size) + : faiss::ReadOnlyInvertedLists(nlist, code_size) { + use_iterator = true; + } + + faiss::InvertedListsIterator* get_iterator( + size_t list_no, + void* inverted_list_context = nullptr) const override { + assert(inverted_list_context); + auto il = + static_cast(inverted_list_context); + return il->get_iterator(list_no); + } + + using idx_t = faiss::idx_t; + + size_t list_size(size_t list_no) const override { + FAISS_THROW_MSG("use iterator interface"); + } + const uint8_t* get_codes(size_t list_no) const override { + FAISS_THROW_MSG("use iterator interface"); + } + const idx_t* get_ids(size_t list_no) const override { + FAISS_THROW_MSG("use iterator interface"); + } +}; + +TEST(COMMON, test_common_trained_index) { + int N = 3; // number of independent indexes + int nt = 500; // training vectors + int nb = 200; // nb database vectors per index + int nq = 10; // nb queries performed on each index + int k = 4; // restults requested per query + + // construct and build an "empty index": a trained index that does not + // itself hold any data + std::unique_ptr empty_index(dynamic_cast( + faiss::index_factory(d, "IVF32,PQ8np"))); + auto xt = get_random_vectors(nt, 123); + empty_index->train(nt, xt.data()); + empty_index->nprobe = 4; + + // reference run: build one index for each set of db / queries and record + // results + std::vector> ref_I(N); + + for (int i = 0; i < N; i++) { + // clone the empty index + std::unique_ptr index( + faiss::clone_index(empty_index.get())); + auto xb = get_random_vectors(nb, 1234 + i); + auto xq = get_random_vectors(nq, 12345 + i); + // add vectors and perform a search + index->add(nb, xb.data()); + std::vector D(k * nq); + std::vector I(k * nq); + index->search(nq, xq.data(), k, D.data(), I.data()); + // record result as reference + ref_I[i] = I; + } + + // build a set of inverted lists for each independent index + std::vector sub_invlists; + + for (int i = 0; i < N; i++) { + // swap in other inverted lists + sub_invlists.emplace_back(empty_index->nlist, empty_index->code_size); + faiss::InvertedLists* invlists = &sub_invlists.back(); + + // replace_invlists swaps in a new InvertedLists for an existing index + empty_index->replace_invlists(invlists, false); + empty_index->reset(); // reset id counter to 0 + // populate inverted lists + auto xb = get_random_vectors(nb, 1234 + i); + empty_index->add(nb, xb.data()); + } + + // perform search dispatching to the sub-invlists. At search time, we don't + // use replace_invlists because that would wreak havoc in a multithreaded + // context + DispatchingInvertedLists di(empty_index->nlist, empty_index->code_size); + empty_index->replace_invlists(&di, false); + + std::vector> new_I(N); + + // run searches in the independent indexes but with a common empty_index +#pragma omp parallel for + for (int i = 0; i < N; i++) { + auto xq = get_random_vectors(nq, 12345 + i); + std::vector D(k * nq); + std::vector I(k * nq); + + // here we set to what sub-index the queries should be directed + faiss::SearchParametersIVF params; + params.nprobe = empty_index->nprobe; + params.inverted_list_context = &sub_invlists[i]; + + empty_index->search(nq, xq.data(), k, D.data(), I.data(), ¶ms); + new_I[i] = I; + } + + // compare with reference reslt + for (int i = 0; i < N; i++) { + ASSERT_EQ(ref_I[i], new_I[i]); + } +} From c5599a06849b9c0ff0060915373e0b04bd360867 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sat, 27 Apr 2024 09:37:26 -0700 Subject: [PATCH 139/206] Fix deprecated use of 0/NULL in faiss/python/python_callbacks.cpp + 1 Summary: `nullptr` is typesafe. `0` and `NULL` are not. In the future, only `nullptr` will be allowed. This diff helps us embrace the future _now_ in service of enabling `-Wzero-as-null-pointer-constant`. Reviewed By: palmje Differential Revision: D56650318 fbshipit-source-id: 803ae62114c39143b65946f6f0387715eaf7f534 --- faiss/python/python_callbacks.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/faiss/python/python_callbacks.cpp b/faiss/python/python_callbacks.cpp index bfcf883aec..06b5c18cfc 100644 --- a/faiss/python/python_callbacks.cpp +++ b/faiss/python/python_callbacks.cpp @@ -46,7 +46,7 @@ size_t PyCallbackIOWriter::operator()( size_t wi = ws > bs ? bs : ws; PyObject* result = PyObject_CallFunction( callback, "(N)", PyBytes_FromStringAndSize(ptr, wi)); - if (result == NULL) { + if (result == nullptr) { FAISS_THROW_MSG("py err"); } // TODO check nb of bytes written @@ -77,7 +77,7 @@ size_t PyCallbackIOReader::operator()(void* ptrv, size_t size, size_t nitems) { while (rs > 0) { size_t ri = rs > bs ? bs : rs; PyObject* result = PyObject_CallFunction(callback, "(n)", ri); - if (result == NULL) { + if (result == nullptr) { FAISS_THROW_MSG("propagate py error"); } if (!PyBytes_Check(result)) { @@ -122,7 +122,7 @@ bool PyCallbackIDSelector::is_member(faiss::idx_t id) const { FAISS_THROW_IF_NOT((id >> 32) == 0); PyThreadLock gil; PyObject* result = PyObject_CallFunction(callback, "(n)", int(id)); - if (result == NULL) { + if (result == nullptr) { FAISS_THROW_MSG("propagate py error"); } bool b = PyObject_IsTrue(result); From 7e1d2b1f55efd53f2322570cf1d3bc74430da265 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 29 Apr 2024 10:48:52 -0700 Subject: [PATCH 140/206] Initial config and linux-x86_64-cmake build job only Summary: This commit is the first in a series in an attempt to incrementally enable all jobs currenlty performed by CircleCI. It includes the main configuration files provided by GitHub team + 1 build. Original PR: https://github.com/facebookresearch/faiss/pull/3325 Reviewed By: junjieqi Differential Revision: D56671582 fbshipit-source-id: c8a21cd69aabaf86134eb86753e90b1facf51bc3 --- .github/actions/build_cmake/action.yml | 103 +++++++++++++++++++++++++ .github/actions/build_conda/action.yml | 98 +++++++++++++++++++++++ .github/workflows/build.yml | 19 +++++ 3 files changed, 220 insertions(+) create mode 100644 .github/actions/build_cmake/action.yml create mode 100644 .github/actions/build_conda/action.yml create mode 100644 .github/workflows/build.yml diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml new file mode 100644 index 0000000000..5892b24dd2 --- /dev/null +++ b/.github/actions/build_cmake/action.yml @@ -0,0 +1,103 @@ +name: Build cmake +inputs: + opt_level: + description: 'The optimization level' + required: false + default: generic + gpu: + description: 'The GPU to use' + required: false + default: OFF + raft: + description: 'The raft to use' + required: false + default: OFF +runs: + using: composite + steps: + - name: Setup miniconda + uses: conda-incubator/setup-miniconda@v3.0.3 + with: + python-version: '3.11' + miniconda-version: latest + - name: Set up environment + shell: bash + run: | + conda config --set solver libmamba + conda update -y -q conda + - name: Install env using main channel + if: inputs.raft == 'OFF' + shell: bash + run: | + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64 + - name: Install env using conda-forge channel + if: inputs.raft == 'ON' + shell: bash + run: | + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + - name: Install CUDA + if: inputs.gpu == 'ON' && inputs.raft == 'OFF' + shell: bash + run: | + conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" + - name: Build all targets + shell: bash + run: | + eval "$(conda shell.bash hook)" + conda activate + cmake -B build \ + -DBUILD_TESTING=ON \ + -DBUILD_SHARED_LIBS=ON \ + -DFAISS_ENABLE_GPU=${{ inputs.gpu }} \ + -DFAISS_ENABLE_RAFT=${{ inputs.raft }} \ + -DFAISS_OPT_LEVEL=${{ inputs.opt_level }} \ + -DFAISS_ENABLE_C_API=ON \ + -DPYTHON_EXECUTABLE=$CONDA/bin/python \ + -DCMAKE_BUILD_TYPE=Release \ + -DBLA_VENDOR=Intel10_64_dyn \ + -DCMAKE_CUDA_FLAGS="-gencode arch=compute_75,code=sm_75" \ + . + make -k -C build -j$(nproc) + - name: C++ tests + shell: bash + run: | + export GTEST_OUTPUT="xml:$(realpath .)/test-results/googletest/" + make -C build test + - name: Install Python extension + shell: bash + working-directory: build/faiss/python + run: | + $CONDA/bin/python setup.py install + - name: Install pytest + shell: bash + run: | + conda install -y pytest + echo "$CONDA/bin" >> $GITHUB_PATH + - name: Python tests (CPU only) + if: inputs.gpu == 'OFF' + shell: bash + run: | + conda install -y -q pytorch -c pytorch + pytest --junitxml=test-results/pytest/results.xml tests/test_*.py + pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py + - name: Python tests (CPU + GPU) + if: inputs.gpu == 'ON' + shell: bash + run: | + conda install -y -q pytorch pytorch-cuda=11.8 -c pytorch -c nvidia/label/cuda-11.8.0 + pytest --junitxml=test-results/pytest/results.xml tests/test_*.py + pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py + cp tests/common_faiss_tests.py faiss/gpu/test + pytest --junitxml=test-results/pytest/results-gpu.xml faiss/gpu/test/test_*.py + pytest --junitxml=test-results/pytest/results-gpu-torch.xml faiss/gpu/test/torch_*.py + - name: Test avx2 loading + if: inputs.opt_level == 'avx2' + shell: bash + run: | + FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs $CONDA/bin/python -c "import faiss" 2>&1 | grep faiss.so + LD_DEBUG=libs $CONDA/bin/python -c "import faiss" 2>&1 | grep faiss_avx2.so + - name: Upload test results + uses: actions/upload-artifact@v4.3.1 + with: + name: test-results-${{ inputs.opt_level }}-${{ inputs.gpu }}-${{ inputs.raft }} + path: test-results diff --git a/.github/actions/build_conda/action.yml b/.github/actions/build_conda/action.yml new file mode 100644 index 0000000000..7e4510b4b2 --- /dev/null +++ b/.github/actions/build_conda/action.yml @@ -0,0 +1,98 @@ +name: Build conda +description: Build conda +inputs: + label: + description: "Label" + default: "" + required: false + cuda: + description: "cuda" + default: "" + required: false + raft: + description: "raft" + default: "" + required: false + compiler_version: + description: "compiler_version" + default: "" + required: false +runs: + using: composite + steps: + - name: Choose shell + shell: bash + id: choose_shell + run: | + # if runner.os != 'Windows' use bash, else use pwsh + if [ "${{ runner.os }}" != "Windows" ]; then + echo "shell=bash" >> "$GITHUB_OUTPUT" + else + echo "shell=pwsh" >> "$GITHUB_OUTPUT" + fi + - name: Setup miniconda + uses: conda-incubator/setup-miniconda@v3.0.3 + with: + python-version: '3.11' + miniconda-version: latest + - name: Install conda build tools + shell: ${{ steps.choose_shell.outputs.shell }} + run: | + # conda config --set solver libmamba + # conda config --set verbosity 3 + conda update -y -q conda + conda install -y -q conda-build + - name: Enable anaconda uploads + if: inputs.label != '' + shell: ${{ steps.choose_shell.outputs.shell }} + env: + PACKAGE_TYPE: inputs.label + run: | + conda install -y -q anaconda-client + conda config --set anaconda_upload yes + - name: Conda build (CPU) + if: inputs.label == '' && inputs.cuda == '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + run: | + conda build faiss --python 3.11 -c pytorch + - name: Conda build (CPU) w/ anaconda upload + if: inputs.label != '' && inputs.cuda == '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + env: + PACKAGE_TYPE: inputs.label + run: | + conda build faiss --user pytorch --label ${{ inputs.label }} -c pytorch + - name: Conda build (GPU) + if: inputs.label == '' && inputs.cuda != '' && inputs.raft == '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + run: | + conda build faiss-gpu --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ + -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia + - name: Conda build (GPU) w/ anaconda upload + if: inputs.label != '' && inputs.cuda != '' && inputs.raft == '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + env: + PACKAGE_TYPE: inputs.label + run: | + conda build faiss-gpu --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ + --user pytorch --label ${{ inputs.label }} -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia + - name: Conda build (GPU w/ RAFT) + if: inputs.label == '' && inputs.cuda != '' && inputs.raft != '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + run: | + conda build faiss-gpu-raft --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ + -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge + - name: Conda build (GPU w/ RAFT) w/ anaconda upload + if: inputs.label != '' && inputs.cuda != '' && inputs.raft != '' + shell: ${{ steps.choose_shell.outputs.shell }} + working-directory: conda + env: + PACKAGE_TYPE: inputs.label + run: | + conda build faiss-gpu-raft --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ + --user pytorch --label ${{ inputs.label }} -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..dc469b6694 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,19 @@ +name: Build +on: + workflow_dispatch: + pull_request: + branches: + - main + push: + tags: + - 'v*' +env: + OMP_NUM_THREADS: '10' + MKL_THREADING_LAYER: GNU +jobs: + linux-x86_64-cmake: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - uses: ./.github/actions/build_cmake From 825cbac467ed47f5fbf0841b8d6a7df05a5bb41c Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Tue, 30 Apr 2024 08:31:45 -0700 Subject: [PATCH 141/206] Add linux-x86_64-AVX2-cmake build Summary: GitHub checks Reviewed By: junjieqi Differential Revision: D56733297 fbshipit-source-id: fe5a2ca7c67f36a4fe986af78fb6dc8f4f843150 --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc469b6694..67130f252d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,3 +17,11 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.1 - uses: ./.github/actions/build_cmake + linux-x86_64-AVX2-cmake: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - uses: ./.github/actions/build_cmake + with: + opt_level: avx2 From 3121fc6175b6c183712da90ab6cead0ac736446a Mon Sep 17 00:00:00 2001 From: Jayjeet Chakraborty Date: Tue, 30 Apr 2024 12:23:58 -0700 Subject: [PATCH 142/206] Fix #3379: Add tutorial for HNSW index (#3381) Summary: Fixes https://github.com/facebookresearch/faiss/issues/3379 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3381 Reviewed By: junjieqi Differential Revision: D56570120 Pulled By: kuarora fbshipit-source-id: 758ea4ab866609d6dd5621e6e6ffda583ba52503 --- tutorial/cpp/6-HNSW.cpp | 76 +++++++++++++++++++++++++++++++++++++ tutorial/cpp/CMakeLists.txt | 3 ++ 2 files changed, 79 insertions(+) create mode 100644 tutorial/cpp/6-HNSW.cpp diff --git a/tutorial/cpp/6-HNSW.cpp b/tutorial/cpp/6-HNSW.cpp new file mode 100644 index 0000000000..d7c615328b --- /dev/null +++ b/tutorial/cpp/6-HNSW.cpp @@ -0,0 +1,76 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include + +#include + +using idx_t = faiss::idx_t; + +int main() { + int d = 64; // dimension + int nb = 100000; // database size + int nq = 10000; // nb of queries + + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + + float* xb = new float[d * nb]; + float* xq = new float[d * nq]; + + for (int i = 0; i < nb; i++) { + for (int j = 0; j < d; j++) + xb[d * i + j] = distrib(rng); + xb[d * i] += i / 1000.; + } + + for (int i = 0; i < nq; i++) { + for (int j = 0; j < d; j++) + xq[d * i + j] = distrib(rng); + xq[d * i] += i / 1000.; + } + + int nlist = 100; + int k = 4; + + faiss::IndexHNSWFlat index(d, 32); + index.add(nb, xb); + + { // search xq + idx_t* I = new idx_t[k * nq]; + float* D = new float[k * nq]; + + index.search(nq, xq, k, D, I); + + printf("I=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) + printf("%5zd ", I[i * k + j]); + printf("\n"); + } + + index.search(nq, xq, k, D, I); + + printf("I=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) + printf("%5zd ", I[i * k + j]); + printf("\n"); + } + + delete[] I; + delete[] D; + } + + delete[] xb; + delete[] xq; + + return 0; +} diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt index 7361b33a03..abcb253826 100644 --- a/tutorial/cpp/CMakeLists.txt +++ b/tutorial/cpp/CMakeLists.txt @@ -18,3 +18,6 @@ target_link_libraries(4-GPU PRIVATE faiss) add_executable(5-Multiple-GPUs EXCLUDE_FROM_ALL 5-Multiple-GPUs.cpp) target_link_libraries(5-Multiple-GPUs PRIVATE faiss) + +add_executable(6-HNSW EXCLUDE_FROM_ALL 6-HNSW.cpp) +target_link_libraries(6-HNSW PRIVATE faiss) From c92b4809ff4fb14d8157287ad4ef581b1b21f260 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Tue, 30 Apr 2024 14:34:15 -0700 Subject: [PATCH 143/206] Add format check Summary: Migration to GitHub actions Reviewed By: junjieqi Differential Revision: D56745520 fbshipit-source-id: 5311a549842f19672ae574edaa8be3ea5a580dbc --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67130f252d..91a8acb6fe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,31 @@ env: OMP_NUM_THREADS: '10' MKL_THREADING_LAYER: GNU jobs: + format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - name: Install clang-format + run: | + sudo apt-get update -y + sudo apt-get install -y wget + sudo apt install -y lsb-release wget software-properties-common gnupg + wget https://apt.llvm.org/llvm.sh + chmod u+x llvm.sh + sudo ./llvm.sh 18 + sudo apt-get install -y git-core clang-format-18 + - name: Verify clang-format + run: | + git ls-files | grep -E '\.(cpp|h|cu|cuh)$' | xargs clang-format-18 -i + if git diff --quiet; then + echo "Formatting OK!" + else + echo "Formatting not OK!" + echo "------------------" + git --no-pager diff --color + exit 1 + fi linux-x86_64-cmake: runs-on: ubuntu-latest steps: From 5fd8b810a493d7144b491d50b5cd82cb3e4fcf62 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 1 May 2024 14:39:09 -0700 Subject: [PATCH 144/206] Enable linux-x86_64-conda build via GitHub Actions (#3405) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3405 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D56843276 fbshipit-source-id: 3d5c7ee9a36a783407dfdcc3574c377da5f9db78 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91a8acb6fe..36f7220c3d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,3 +50,12 @@ jobs: - uses: ./.github/actions/build_cmake with: opt_level: avx2 + linux-x86_64-conda: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda From 74562b2a39bb424a7b7e0132271710d04660ecb1 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 1 May 2024 15:58:17 -0700 Subject: [PATCH 145/206] Enable windows-x86_64-conda build via GitHub Actions (#3406) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3406 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D56848895 fbshipit-source-id: 5a351534d9151369a9104314fee203657ac40043 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 36f7220c3d..b00d3b25eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,3 +59,12 @@ jobs: fetch-depth: 0 fetch-tags: true - uses: ./.github/actions/build_conda + windows-x86_64-conda: + runs-on: windows-2019 + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda From 96b88ac361058a8bcbfe9e745f24941b122c924d Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 1 May 2024 17:25:17 -0700 Subject: [PATCH 146/206] Enable linux-arm64-conda check via GitHub Actions (#3407) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3407 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D56856565 fbshipit-source-id: d7400eb9cb7bd68e93a712af81c6cbb7e76e2400 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b00d3b25eb..bc45474b23 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,3 +68,12 @@ jobs: fetch-depth: 0 fetch-tags: true - uses: ./.github/actions/build_conda + linux-arm64-conda: + runs-on: 2-core-ubuntu-arm + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda From 7b8b98131846847fb60a48f8ee3d135af1c3ee41 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 2 May 2024 20:49:59 -0700 Subject: [PATCH 147/206] Enable packages builds on main for windows, linux-arm64, linux-x86_64 via GitHub Actions (#3409) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3409 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D56917083 fbshipit-source-id: 93a2358ce5697b26aa40ced505f42c584fa8c46c --- .github/workflows/build.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc45474b23..16ffe51e18 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,3 +77,39 @@ jobs: fetch-depth: 0 fetch-tags: true - uses: ./.github/actions/build_conda + linux-x86_64-packages: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + windows-x86_64-packages: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: windows-2019 + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + linux-arm64-packages: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: 4-core-arm + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main From 1b1a403bb6ed210b7056dbbc6e743d1cf72f678c Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Fri, 3 May 2024 00:28:19 -0700 Subject: [PATCH 148/206] Change linux-arm64-packages build to use 2-core-ubuntu-arm for better availability (#3410) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3410 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D56921925 fbshipit-source-id: 64e7a636b47d828110a6d413c8645e5343b578cb --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16ffe51e18..bd9805b9d9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: label: main linux-arm64-packages: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') - runs-on: 4-core-arm + runs-on: 2-core-ubuntu-arm steps: - name: Checkout uses: actions/checkout@v4.1.1 From 0cc0e19f9e40d3e8eaf8ad00ea644051d3c5ee7a Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Fri, 3 May 2024 13:16:51 -0700 Subject: [PATCH 149/206] Enable osx-arm64-packages build via GitHub Actions (#3411) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3411 Migration to GitHub Reviewed By: kuarora Differential Revision: D56923116 fbshipit-source-id: 1e2b493b0dd81ce850f2970e6d28c713f6a9927b --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bd9805b9d9..e05645f3d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -101,6 +101,18 @@ jobs: - uses: ./.github/actions/build_conda with: label: main + osx-arm64-packages: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: macos-14 + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main linux-arm64-packages: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 2-core-ubuntu-arm From b3e3c2d38db4457209d3c3456baeccdcee8282b5 Mon Sep 17 00:00:00 2001 From: Amir Sadoughi Date: Wed, 8 May 2024 21:52:46 -0700 Subject: [PATCH 150/206] TimeoutCallback C++ and Python (#3417) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3417 https://github.com/facebookresearch/faiss/issues/3351 Reviewed By: junjieqi Differential Revision: D57120422 fbshipit-source-id: e2e446642e7be8647f5115f90916fad242e31286 --- faiss/gpu/perf/PerfClustering.cpp | 6 +++++ faiss/impl/AuxIndexStructures.cpp | 25 +++++++++++++++++++++ faiss/impl/AuxIndexStructures.h | 8 +++++++ faiss/python/__init__.py | 11 +++++++++ faiss/python/swigfaiss.swig | 9 ++++++-- tests/CMakeLists.txt | 1 + tests/test_callback.cpp | 37 +++++++++++++++++++++++++++++++ tests/test_callback_py.py | 32 ++++++++++++++++++++++++++ 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 tests/test_callback.cpp create mode 100644 tests/test_callback_py.py diff --git a/faiss/gpu/perf/PerfClustering.cpp b/faiss/gpu/perf/PerfClustering.cpp index 0322f0e490..532557fe20 100644 --- a/faiss/gpu/perf/PerfClustering.cpp +++ b/faiss/gpu/perf/PerfClustering.cpp @@ -17,6 +17,7 @@ #include #include +#include DEFINE_int32(num, 10000, "# of vecs"); DEFINE_int32(k, 100, "# of clusters"); @@ -34,6 +35,7 @@ DEFINE_int64( "minimum size to use CPU -> GPU paged copies"); DEFINE_int64(pinned_mem, -1, "pinned memory allocation to use"); DEFINE_int32(max_points, -1, "max points per centroid"); +DEFINE_double(timeout, 0, "timeout in seconds"); using namespace faiss::gpu; @@ -99,10 +101,14 @@ int main(int argc, char** argv) { cp.max_points_per_centroid = FLAGS_max_points; } + auto tc = new faiss::TimeoutCallback(); + faiss::InterruptCallback::instance.reset(tc); + faiss::Clustering kmeans(FLAGS_dim, FLAGS_k, cp); // Time k-means { + tc->set_timeout(FLAGS_timeout); CpuTimer timer; kmeans.train(FLAGS_num, vecs.data(), *(gpuIndex.getIndex())); diff --git a/faiss/impl/AuxIndexStructures.cpp b/faiss/impl/AuxIndexStructures.cpp index cebe8a1e23..e2b2791e55 100644 --- a/faiss/impl/AuxIndexStructures.cpp +++ b/faiss/impl/AuxIndexStructures.cpp @@ -236,4 +236,29 @@ size_t InterruptCallback::get_period_hint(size_t flops) { return std::max((size_t)10 * 10 * 1000 * 1000 / (flops + 1), (size_t)1); } +void TimeoutCallback::set_timeout(double timeout_in_seconds) { + timeout = timeout_in_seconds; + start = std::chrono::steady_clock::now(); +} + +bool TimeoutCallback::want_interrupt() { + if (timeout == 0) { + return false; + } + auto end = std::chrono::steady_clock::now(); + std::chrono::duration duration = end - start; + float elapsed_in_seconds = duration.count() / 1000.0; + if (elapsed_in_seconds > timeout) { + timeout = 0; + return true; + } + return false; +} + +void TimeoutCallback::reset(double timeout_in_seconds) { + auto tc(new faiss::TimeoutCallback()); + faiss::InterruptCallback::instance.reset(tc); + tc->set_timeout(timeout_in_seconds); +} + } // namespace faiss diff --git a/faiss/impl/AuxIndexStructures.h b/faiss/impl/AuxIndexStructures.h index f8b5cca842..7e12a1a3af 100644 --- a/faiss/impl/AuxIndexStructures.h +++ b/faiss/impl/AuxIndexStructures.h @@ -161,6 +161,14 @@ struct FAISS_API InterruptCallback { static size_t get_period_hint(size_t flops); }; +struct TimeoutCallback : InterruptCallback { + std::chrono::time_point start; + double timeout; + bool want_interrupt() override; + void set_timeout(double timeout_in_seconds); + static void reset(double timeout_in_seconds); +}; + /// set implementation optimized for fast access. struct VisitedTable { std::vector visited; diff --git a/faiss/python/__init__.py b/faiss/python/__init__.py index 95be4254dc..0562d1dd89 100644 --- a/faiss/python/__init__.py +++ b/faiss/python/__init__.py @@ -316,3 +316,14 @@ def deserialize_index_binary(data): reader = VectorIOReader() copy_array_to_vector(data, reader.data) return read_index_binary(reader) + + +class TimeoutGuard: + def __init__(self, timeout_in_seconds: float): + self.timeout = timeout_in_seconds + + def __enter__(self): + TimeoutCallback.reset(self.timeout) + + def __exit__(self, exc_type, exc_value, traceback): + PythonInterruptCallback.reset() diff --git a/faiss/python/swigfaiss.swig b/faiss/python/swigfaiss.swig index 5c9a7b3fa7..85e04d322c 100644 --- a/faiss/python/swigfaiss.swig +++ b/faiss/python/swigfaiss.swig @@ -1041,7 +1041,9 @@ PyObject *swig_ptr (PyObject *a) PyErr_SetString(PyExc_ValueError, "did not recognize array type"); return NULL; } +%} +%inline %{ struct PythonInterruptCallback: faiss::InterruptCallback { @@ -1056,15 +1058,18 @@ struct PythonInterruptCallback: faiss::InterruptCallback { return err == -1; } + static void reset() { + faiss::InterruptCallback::instance.reset(new PythonInterruptCallback()); + } }; + %} %init %{ /* needed, else crash at runtime */ import_array(); - faiss::InterruptCallback::instance.reset(new PythonInterruptCallback()); - + PythonInterruptCallback::reset(); %} // return a pointer usable as input for functions that expect pointers diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 443195eecb..3980d7dd7c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,6 +34,7 @@ set(FAISS_TEST_SRC test_fastscan_perf.cpp test_disable_pq_sdc_tables.cpp test_common_ivf_empty_index.cpp + test_callback.cpp ) add_executable(faiss_test ${FAISS_TEST_SRC}) diff --git a/tests/test_callback.cpp b/tests/test_callback.cpp new file mode 100644 index 0000000000..cdfadf1d39 --- /dev/null +++ b/tests/test_callback.cpp @@ -0,0 +1,37 @@ +/** + * 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. + */ + +#include + +#include +#include +#include +#include +#include + +TEST(TestCallback, timeout) { + int n = 1000; + int k = 100; + int d = 128; + int niter = 1000000000; + int seed = 42; + + std::vector vecs(n * d); + faiss::float_rand(vecs.data(), vecs.size(), seed); + + auto index(new faiss::IndexFlat(d)); + + faiss::ClusteringParameters cp; + cp.niter = niter; + cp.verbose = false; + + faiss::Clustering kmeans(d, k, cp); + + faiss::TimeoutCallback::reset(0.010); + EXPECT_THROW(kmeans.train(n, vecs.data(), *index), faiss::FaissException); + delete index; +} diff --git a/tests/test_callback_py.py b/tests/test_callback_py.py new file mode 100644 index 0000000000..0ec176dd86 --- /dev/null +++ b/tests/test_callback_py.py @@ -0,0 +1,32 @@ +# 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 unittest +import numpy as np +import faiss + + +class TestCallbackPy(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def test_timeout(self) -> None: + n = 1000 + k = 100 + d = 128 + niter = 1_000_000_000 + + x = np.random.rand(n, d).astype('float32') + index = faiss.IndexFlat(d) + + cp = faiss.ClusteringParameters() + cp.niter = niter + cp.verbose = False + + kmeans = faiss.Clustering(d, k, cp) + + with self.assertRaises(RuntimeError): + with faiss.TimeoutGuard(0.010): + kmeans.train(x, index) From 34fa2aeb72ff5c40b62410f121a6438ff15ccd76 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 9 May 2024 10:49:48 -0700 Subject: [PATCH 151/206] Enable linux-x86_64-GPU-w-RAFT-cmake build via GitHub Actions (#3418) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3418 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D57133934 fbshipit-source-id: 255b7afbbb90cc966916cd900174833416b0bc51 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e05645f3d3..888306d1d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,15 @@ jobs: - uses: ./.github/actions/build_cmake with: opt_level: avx2 + linux-x86_64-GPU-w-RAFT-cmake: + runs-on: 4-core-ubuntu-gpu-t4 + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - uses: ./.github/actions/build_cmake + with: + gpu: ON + raft: ON linux-x86_64-conda: runs-on: ubuntu-latest steps: From e1e4ad00831174d25bba5a157d26b428ae54b39d Mon Sep 17 00:00:00 2001 From: Carl Love Date: Fri, 10 May 2024 09:27:26 -0700 Subject: [PATCH 152/206] PowerPC, improve code generation for function fvec_L2sqr (#3416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The code generated for function fvec_L2sqr generated by OpenXL do not perform as good as the codes generated by gcc on Power. The macros to enable imprecise floating point operation don’t cover Power with OpenXL. This patch adds the OpenXL compiler options for the PowerPC macros to achieve better performance. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3416 Reviewed By: asadoughi Differential Revision: D57210015 Pulled By: mdouze fbshipit-source-id: 6b838a2fa4d4996fe52c9f1105827004626fe720 --- faiss/impl/platform_macros.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/faiss/impl/platform_macros.h b/faiss/impl/platform_macros.h index a0faea7cba..3fc328535b 100644 --- a/faiss/impl/platform_macros.h +++ b/faiss/impl/platform_macros.h @@ -127,6 +127,13 @@ inline int __builtin_clzll(uint64_t x) { __pragma(float_control(precise, off, push)) #define FAISS_PRAGMA_IMPRECISE_FUNCTION_END __pragma(float_control(pop)) #elif defined(__clang__) +#if defined(__PPC__) +#define FAISS_PRAGMA_IMPRECISE_LOOP \ + _Pragma("clang loop vectorize_width(4) interleave_count(8)") +#define FAISS_PRAGMA_IMPRECISE_FUNCTION_BEGIN \ + _Pragma("float_control(precise, off, push)") +#define FAISS_PRAGMA_IMPRECISE_FUNCTION_END _Pragma("float_control(pop)") +#else #define FAISS_PRAGMA_IMPRECISE_LOOP \ _Pragma("clang loop vectorize(enable) interleave(enable)") @@ -144,6 +151,7 @@ inline int __builtin_clzll(uint64_t x) { #define FAISS_PRAGMA_IMPRECISE_FUNCTION_BEGIN #define FAISS_PRAGMA_IMPRECISE_FUNCTION_END #endif +#endif #elif defined(__GNUC__) // Unfortunately, GCC does not provide a pragma for detecting it. // So, we have to stick to GNUC, which is defined by MANY compilers. From b487c62a1e164767ac4f73b2b2264a68570602c6 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 13 May 2024 09:54:41 -0700 Subject: [PATCH 153/206] Update system dependencies to enable CUDA builds on v6 kernel and newer libc (#3426) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3426 GitHub Actions only supports Ubuntu 22 and newer and this change is necessary to enable CUDA builds to complete the migration. Reviewed By: algoriddle Differential Revision: D57261685 fbshipit-source-id: 34467f57426864ffa8b32f6018ccdc7bb4424b57 --- .github/actions/build_cmake/action.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index 5892b24dd2..510d4c9dc3 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -25,21 +25,21 @@ runs: run: | conda config --set solver libmamba conda update -y -q conda - - name: Install env using main channel - if: inputs.raft == 'OFF' + - name: Configure conda environment shell: bash run: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64 - - name: Install env using conda-forge channel - if: inputs.raft == 'ON' - shell: bash - run: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + conda install -y -q -c conda-forge gxx_linux-64=11.2 sysroot_linux-64=2.28 + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest - name: Install CUDA if: inputs.gpu == 'ON' && inputs.raft == 'OFF' shell: bash run: | conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" + - name: Install RAFT + if: inputs.raft == 'ON' + shell: bash + run: | + conda install -y -q libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - name: Build all targets shell: bash run: | From 2e04533fe17658a0e424e25cd5c85ff3259ba71e Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 13 May 2024 09:54:41 -0700 Subject: [PATCH 154/206] Enable linux-x86_64-GPU-cmake build on GitHub Actions (#3427) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3427 Migration to GitHub Actions Reviewed By: algoriddle Differential Revision: D57261696 fbshipit-source-id: d7b8c26259fd3de1cf59fc460f6af20185ceacfe --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 888306d1d3..5ee3c67d6e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,15 @@ jobs: - uses: ./.github/actions/build_cmake with: opt_level: avx2 + linux-x86_64-GPU-cmake: + needs: linux-x86_64-AVX2-cmake + runs-on: 4-core-ubuntu-gpu-t4 + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - uses: ./.github/actions/build_cmake + with: + gpu: ON linux-x86_64-GPU-w-RAFT-cmake: runs-on: 4-core-ubuntu-gpu-t4 steps: From 4d06d7069fca2359e5b56d33c762ab91d015ee9d Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 13 May 2024 09:54:41 -0700 Subject: [PATCH 155/206] Add disabled linux-x86_64-AVX512-cmake build on GitHub Actions (#3428) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3428 GitHub Actions currently does not support runners with AVX-512 but committed to add this support in early 2025. We will be running these on CircleCI until then. This placeholder build configuration will allow us to enable it with a 1-liner when the hosts are available. Reviewed By: algoriddle Differential Revision: D57261783 fbshipit-source-id: 1fb985a0c3dbb11851af63c95bde6494d25d0ac2 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5ee3c67d6e..dc7f73c147 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,15 @@ jobs: - uses: ./.github/actions/build_cmake with: opt_level: avx2 + linux-x86_64-AVX512-cmake: + if: false # TODO: enable when GitHub Actions adds AVX-512 hosts + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - uses: ./.github/actions/build_cmake + with: + opt_level: avx512 linux-x86_64-GPU-cmake: needs: linux-x86_64-AVX2-cmake runs-on: 4-core-ubuntu-gpu-t4 From 83df64cd7f3d34bad29051cf637c56b952b839c3 Mon Sep 17 00:00:00 2001 From: Alexandr Guzhva Date: Wed, 15 May 2024 01:48:49 -0700 Subject: [PATCH 156/206] Get rid of redundant instructions in ScalarQuantizer (#3430) Summary: This PR removes unneeded ARM NEON SIMD instructions for ScalarQuantizer. The removed instructions are completely redundant, and I believe that it is a funky way of converting two `float32x4_t` variables (which hold 4 float values in a single SIMD register) into a single `float32x4x2_t` variable (two SIMD registers packed together). Clang compiler is capable of eliminating these instructions. The only GCC that can eliminate these unneeded instructions is GCC 14, which was released very recently (Apr-May 2024). mdouze Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3430 Reviewed By: mlomeli1 Differential Revision: D57369849 Pulled By: mdouze fbshipit-source-id: 09d7cf16e113df3eb9ddbfa54d074b58b452ba7f --- faiss/impl/ScalarQuantizer.cpp | 58 +++++++++++++--------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/faiss/impl/ScalarQuantizer.cpp b/faiss/impl/ScalarQuantizer.cpp index 07d77d5622..e3b29e621d 100644 --- a/faiss/impl/ScalarQuantizer.cpp +++ b/faiss/impl/ScalarQuantizer.cpp @@ -101,8 +101,7 @@ struct Codec8bit { } float32x4_t res1 = vld1q_f32(result); float32x4_t res2 = vld1q_f32(result + 4); - float32x4x2_t res = vzipq_f32(res1, res2); - return vuzpq_f32(res.val[0], res.val[1]); + return {res1, res2}; } #endif }; @@ -153,8 +152,7 @@ struct Codec4bit { } float32x4_t res1 = vld1q_f32(result); float32x4_t res2 = vld1q_f32(result + 4); - float32x4x2_t res = vzipq_f32(res1, res2); - return vuzpq_f32(res.val[0], res.val[1]); + return {res1, res2}; } #endif }; @@ -266,8 +264,7 @@ struct Codec6bit { } float32x4_t res1 = vld1q_f32(result); float32x4_t res2 = vld1q_f32(result + 4); - float32x4x2_t res = vzipq_f32(res1, res2); - return vuzpq_f32(res.val[0], res.val[1]); + return {res1, res2}; } #endif }; @@ -345,16 +342,14 @@ struct QuantizerTemplate : QuantizerTemplate { FAISS_ALWAYS_INLINE float32x4x2_t reconstruct_8_components(const uint8_t* code, int i) const { float32x4x2_t xi = Codec::decode_8_components(code, i); - float32x4x2_t res = vzipq_f32( - vfmaq_f32( + return {vfmaq_f32( vdupq_n_f32(this->vmin), xi.val[0], vdupq_n_f32(this->vdiff)), vfmaq_f32( vdupq_n_f32(this->vmin), xi.val[1], - vdupq_n_f32(this->vdiff))); - return vuzpq_f32(res.val[0], res.val[1]); + vdupq_n_f32(this->vdiff))}; } }; @@ -431,10 +426,8 @@ struct QuantizerTemplate : QuantizerTemplate { float32x4x2_t vmin_8 = vld1q_f32_x2(this->vmin + i); float32x4x2_t vdiff_8 = vld1q_f32_x2(this->vdiff + i); - float32x4x2_t res = vzipq_f32( - vfmaq_f32(vmin_8.val[0], xi.val[0], vdiff_8.val[0]), - vfmaq_f32(vmin_8.val[1], xi.val[1], vdiff_8.val[1])); - return vuzpq_f32(res.val[0], res.val[1]); + return {vfmaq_f32(vmin_8.val[0], xi.val[0], vdiff_8.val[0]), + vfmaq_f32(vmin_8.val[1], xi.val[1], vdiff_8.val[1])}; } }; @@ -496,10 +489,9 @@ struct QuantizerFP16<8> : QuantizerFP16<1> { FAISS_ALWAYS_INLINE float32x4x2_t reconstruct_8_components(const uint8_t* code, int i) const { - uint16x4x2_t codei = vld2_u16((const uint16_t*)(code + 2 * i)); - return vzipq_f32( - vcvt_f32_f16(vreinterpret_f16_u16(codei.val[0])), - vcvt_f32_f16(vreinterpret_f16_u16(codei.val[1]))); + uint16x4x2_t codei = vld1_u16_x2((const uint16_t*)(code + 2 * i)); + return {vcvt_f32_f16(vreinterpret_f16_u16(codei.val[0])), + vcvt_f32_f16(vreinterpret_f16_u16(codei.val[1]))}; } }; #endif @@ -568,8 +560,7 @@ struct Quantizer8bitDirect<8> : Quantizer8bitDirect<1> { } float32x4_t res1 = vld1q_f32(result); float32x4_t res2 = vld1q_f32(result + 4); - float32x4x2_t res = vzipq_f32(res1, res2); - return vuzpq_f32(res.val[0], res.val[1]); + return {res1, res2}; } }; @@ -868,7 +859,7 @@ struct SimilarityL2<8> { float32x4x2_t accu8; FAISS_ALWAYS_INLINE void begin_8() { - accu8 = vzipq_f32(vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)); + accu8 = {vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)}; yi = y; } @@ -882,8 +873,7 @@ struct SimilarityL2<8> { float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], sub0, sub0); float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], sub1, sub1); - float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); - accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + accu8 = {accu8_0, accu8_1}; } FAISS_ALWAYS_INLINE void add_8_components_2( @@ -895,8 +885,7 @@ struct SimilarityL2<8> { float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], sub0, sub0); float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], sub1, sub1); - float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); - accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + accu8 = {accu8_0, accu8_1}; } FAISS_ALWAYS_INLINE float result_8() { @@ -996,7 +985,7 @@ struct SimilarityIP<8> { float32x4x2_t accu8; FAISS_ALWAYS_INLINE void begin_8() { - accu8 = vzipq_f32(vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)); + accu8 = {vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)}; yi = y; } @@ -1006,8 +995,7 @@ struct SimilarityIP<8> { float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], yiv.val[0], x.val[0]); float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], yiv.val[1], x.val[1]); - float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); - accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + accu8 = {accu8_0, accu8_1}; } FAISS_ALWAYS_INLINE void add_8_components_2( @@ -1015,19 +1003,17 @@ struct SimilarityIP<8> { float32x4x2_t x2) { float32x4_t accu8_0 = vfmaq_f32(accu8.val[0], x1.val[0], x2.val[0]); float32x4_t accu8_1 = vfmaq_f32(accu8.val[1], x1.val[1], x2.val[1]); - float32x4x2_t accu8_temp = vzipq_f32(accu8_0, accu8_1); - accu8 = vuzpq_f32(accu8_temp.val[0], accu8_temp.val[1]); + accu8 = {accu8_0, accu8_1}; } FAISS_ALWAYS_INLINE float result_8() { - float32x4x2_t sum_tmp = vzipq_f32( + float32x4x2_t sum = { vpaddq_f32(accu8.val[0], accu8.val[0]), - vpaddq_f32(accu8.val[1], accu8.val[1])); - float32x4x2_t sum = vuzpq_f32(sum_tmp.val[0], sum_tmp.val[1]); - float32x4x2_t sum2_tmp = vzipq_f32( + vpaddq_f32(accu8.val[1], accu8.val[1])}; + + float32x4x2_t sum2 = { vpaddq_f32(sum.val[0], sum.val[0]), - vpaddq_f32(sum.val[1], sum.val[1])); - float32x4x2_t sum2 = vuzpq_f32(sum2_tmp.val[0], sum2_tmp.val[1]); + vpaddq_f32(sum.val[1], sum.val[1])}; return vgetq_lane_f32(sum2.val[0], 0) + vgetq_lane_f32(sum2.val[1], 0); } }; From 509f4c1320c5990096a202e210f5107a1ca8dd71 Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Wed, 15 May 2024 06:24:23 -0700 Subject: [PATCH 157/206] fix install instructions (#3442) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3442 fix install instruction for GPU + pytorch Reviewed By: mlomeli1 Differential Revision: D57376959 fbshipit-source-id: 74caff960be7dbf8102e7593ce1485452a18de6e --- INSTALL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 45e2c9341b..5bd4f6d448 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -40,11 +40,11 @@ conda install -c pytorch -c nvidia -c rapidsai -c conda-forge faiss-gpu-raft=1.8 ``` In the above commands, pytorch-cuda=11 or pytorch-cuda=12 would select a specific CUDA version, if it’s required. -A combination of versions that installs GPU Faiss with CUDA and Pytorch (as of 2024-03-01): +A combination of versions that installs GPU Faiss with CUDA and Pytorch (as of 2024-05-15): ``` conda create --name faiss_1.8.0 conda activate faiss_1.8.0 -conda install -c pytorch -c nvidia faiss-gpu=1.8.0 pytorch pytorch-cuda numpy +conda install -c pytorch -c nvidia faiss-gpu=1.8.0 pytorch=*=*cuda* pytorch-cuda=11 numpy ``` ## Installing from conda-forge From 558a7c3fbc37e1bbf02dec99d47b60f75d824d76 Mon Sep 17 00:00:00 2001 From: Mengdi Lin Date: Wed, 15 May 2024 09:17:10 -0700 Subject: [PATCH 158/206] interrupt for NNDescent (#3432) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3432 Addresses the issue in https://github.com/facebookresearch/faiss/issues/3173 for `IndexNNDescent`, I see that there is already interrupt implemented for it's [search](https://fburl.com/code/iwn3tqic) API, so I looked into it's `add` API. For a given dataset nb = 10 mil, iter = 10, K = 32, d = 32 on a CPU only machine reveals that bulk of the cost comes from [nndescent](https://fburl.com/code/5rdb1p5o). For every iteration of `nndescent` takes around ~12 seconds, ~70-80% of the time is spent on `join` method (~10 seconds per iteration) and ~20-30% spent on `update` (~2 second per iteration). Adding the interrupt on the `join` should suffice on quickly terminating the program when users hit ctrl+C (happy to move the interrupt elsewhere if we think otherwise) Reviewed By: junjieqi, mdouze Differential Revision: D57300514 fbshipit-source-id: d343e0a292c35027ffdb8cbd0131e945b9881d63 --- faiss/impl/NNDescent.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/faiss/impl/NNDescent.cpp b/faiss/impl/NNDescent.cpp index b609aba390..5afcdaf5b7 100644 --- a/faiss/impl/NNDescent.cpp +++ b/faiss/impl/NNDescent.cpp @@ -154,15 +154,20 @@ NNDescent::NNDescent(const int d, const int K) : K(K), d(d) { NNDescent::~NNDescent() {} void NNDescent::join(DistanceComputer& qdis) { + idx_t check_period = InterruptCallback::get_period_hint(d * search_L); + for (idx_t i0 = 0; i0 < (idx_t)ntotal; i0 += check_period) { + idx_t i1 = std::min(i0 + check_period, (idx_t)ntotal); #pragma omp parallel for default(shared) schedule(dynamic, 100) - for (int n = 0; n < ntotal; n++) { - graph[n].join([&](int i, int j) { - if (i != j) { - float dist = qdis.symmetric_dis(i, j); - graph[i].insert(j, dist); - graph[j].insert(i, dist); - } - }); + for (idx_t n = i0; n < i1; n++) { + graph[n].join([&](int i, int j) { + if (i != j) { + float dist = qdis.symmetric_dis(i, j); + graph[i].insert(j, dist); + graph[j].insert(i, dist); + } + }); + } + InterruptCallback::check(); } } From b8e4489b98b5b8f9a84e61cbc84812280954514e Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Wed, 15 May 2024 11:45:48 -0700 Subject: [PATCH 159/206] Remove unused variables in faiss/IndexIVFFastScan.cpp (#3439) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3439 LLVM-15 has a warning `-Wunused-but-set-variable` which we treat as an error because it's so often diagnostic of a code issue. Unused variables can compromise readability or, worse, performance. This diff either (a) removes an unused variable and, possibly, it's associated code, or (b) qualifies the variable with `[[maybe_unused]]`, mostly in cases where the variable _is_ used, but, eg, in an `assert` statement that isn't present in production code. - If you approve of this diff, please use the "Accept & Ship" button :-) Reviewed By: palmje, junjieqi Differential Revision: D57344013 fbshipit-source-id: adf410139d2e6ca69a26ccdbff8511c9b7620489 --- faiss/IndexIVFFastScan.cpp | 4 ---- tutorial/cpp/6-HNSW.cpp | 1 - 2 files changed, 5 deletions(-) diff --git a/faiss/IndexIVFFastScan.cpp b/faiss/IndexIVFFastScan.cpp index 19828753d2..3e40f7a3da 100644 --- a/faiss/IndexIVFFastScan.cpp +++ b/faiss/IndexIVFFastScan.cpp @@ -914,10 +914,6 @@ void IndexIVFFastScan::search_implem_10( size_t* nlist_out, const NormTableScaler* scaler, const IVFSearchParameters* params) const { - const size_t max_codes = params ? params->max_codes : this->max_codes; - const SearchParameters* quantizer_params = - params ? params->quantizer_params : nullptr; - size_t dim12 = ksub * M2; AlignedTable dis_tables; AlignedTable biases; diff --git a/tutorial/cpp/6-HNSW.cpp b/tutorial/cpp/6-HNSW.cpp index d7c615328b..1b3434a433 100644 --- a/tutorial/cpp/6-HNSW.cpp +++ b/tutorial/cpp/6-HNSW.cpp @@ -37,7 +37,6 @@ int main() { xq[d * i] += i / 1000.; } - int nlist = 100; int k = 4; faiss::IndexHNSWFlat index(d, 32); From 2050a0309043469c14546532f18e49222e6c73c9 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 15 May 2024 13:06:00 -0700 Subject: [PATCH 160/206] Add cuda-toolkit package dependency to faiss-gpu and faiss-gpu-raft conda build recipes (#3440) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3440 This change is required to unblock the migration to GitHub Actions. `cuda-toolkit` was only specified in the `libfaiss` package and it was not available in `faiss-gpu` or `faiss-gpu-raft`. This currently works on CircleCI because the runner image has CUDA toolkit of the needed version installed on the system and the build logic falls back to that but breaks on GitHub Actions because their runner images do not come with CUDA toolkit pre-installed. Reviewed By: junjieqi Differential Revision: D57371597 fbshipit-source-id: 8bededd53e2528f033fac797b296d74b47f9403e --- conda/faiss-gpu-raft/meta.yaml | 1 + conda/faiss-gpu/meta.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 3eebc9876b..23e4835032 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -87,6 +87,7 @@ outputs: - swig - cmake >=3.24.0 - make # [not win] + - cuda-toolkit {{ cudatoolkit }} host: - python {{ python }} - numpy >=1.19,<2 diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index 7ac24e785d..3d614df1bf 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -83,6 +83,7 @@ outputs: - swig - cmake >=3.24.0 - make # [not win] + - cuda-toolkit {{ cudatoolkit }} host: - python {{ python }} - numpy >=1.19,<2 From 745bca88e3053a2e53bb6fe2b98b0bbb98470b2c Mon Sep 17 00:00:00 2001 From: Mengdi Lin Date: Wed, 15 May 2024 13:39:18 -0700 Subject: [PATCH 161/206] stabilize formatting for bench_cppcontrib_sa_decode.cpp (#3443) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3443 Stabilize this file for clang-formatting versions 18.1.3 (VSCode) and 18.1.5 (our Github CI) Reviewed By: junjieqi Differential Revision: D57393650 fbshipit-source-id: 15170436bbd03194dbeaac1ef1130e20adc8c23e --- benchs/bench_cppcontrib_sa_decode.cpp | 175 +++++++++++++------------- 1 file changed, 88 insertions(+), 87 deletions(-) diff --git a/benchs/bench_cppcontrib_sa_decode.cpp b/benchs/bench_cppcontrib_sa_decode.cpp index f0266172a8..b960fb7c6a 100644 --- a/benchs/bench_cppcontrib_sa_decode.cpp +++ b/benchs/bench_cppcontrib_sa_decode.cpp @@ -213,9 +213,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_seq\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -261,10 +261,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error = getError(n, d, outputFaiss, outputKernel1); - - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -324,9 +323,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error1 = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel1 << "\t" << error1 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel1 + << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -353,9 +352,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error2 = getError(n, d, outputFaiss, outputKernel2); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2 << "\t" << error2 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2 + << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -384,9 +383,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error2u = getError(n, d, outputFaiss, outputKernel2u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2u << "\t" << error2u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2u + << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -418,9 +417,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error3 = getError(n, d, outputFaiss, outputKernel3); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3 << "\t" << error3 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3 + << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -456,9 +455,9 @@ static void verifyIndex2LevelDecoder( // evaluate the error const double error3u = getError(n, d, outputFaiss, outputKernel3u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3u << "\t" << error3u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3u + << "\t" << error3u << std::endl; } } @@ -524,9 +523,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_seq\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -573,9 +572,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -641,9 +640,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error1 = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel1 << "\t" << error1 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel1 + << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -675,9 +674,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error2 = getError(n, d, outputFaiss, outputKernel2); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2 << "\t" << error2 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2 + << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -711,9 +710,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error2u = getError(n, d, outputFaiss, outputKernel2u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2u << "\t" << error2u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2u + << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -750,9 +749,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error3 = getError(n, d, outputFaiss, outputKernel3); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3 << "\t" << error3 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3 + << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -793,9 +792,9 @@ static void verifyMinMaxIndex2LevelDecoder( // evaluate the error const double error3u = getError(n, d, outputFaiss, outputKernel3u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3u << "\t" << error3u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3u + << "\t" << error3u << std::endl; } } @@ -851,9 +850,9 @@ static void verifyIndexPQDecoder( // evaluate the error double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_seq\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -899,9 +898,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -961,9 +960,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error1 = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel1 << "\t" << error1 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel1 + << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -989,9 +988,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error2 = getError(n, d, outputFaiss, outputKernel2); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2 << "\t" << error2 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2 + << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -1018,9 +1017,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error2u = getError(n, d, outputFaiss, outputKernel2u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2u << "\t" << error2u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2u + << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -1051,9 +1050,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error3 = getError(n, d, outputFaiss, outputKernel3); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3 << "\t" << error3 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3 + << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -1086,9 +1085,9 @@ static void verifyIndexPQDecoder( // evaluate the error const double error3u = getError(n, d, outputFaiss, outputKernel3u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3u << "\t" << error3u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3u + << "\t" << error3u << std::endl; } } @@ -1149,9 +1148,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_seq" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_seq\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1197,9 +1196,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "store_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel << "\t" << error << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\tstore_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel + << "\t" << error << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1264,9 +1263,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error1 = getError(n, d, outputFaiss, outputKernel1); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel1 << "\t" << error1 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel1 + << "\t" << error1 << std::endl; // kernels: accum 2 points, shared centroids StopWatch swKernel2; @@ -1297,9 +1296,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error2 = getError(n, d, outputFaiss, outputKernel2); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2 << "\t" << error2 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2 + << "\t" << error2 << std::endl; // kernels: accum 2 points, unique centroids StopWatch swKernel2u; @@ -1331,9 +1330,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error2u = getError(n, d, outputFaiss, outputKernel2u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum2u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel2u << "\t" << error2u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum2u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel2u + << "\t" << error2u << std::endl; // kernels: accum 3 points, shared centroids StopWatch swKernel3; @@ -1369,9 +1368,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error3 = getError(n, d, outputFaiss, outputKernel3); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3 << "\t" << error3 << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3 + << "\t" << error3 << std::endl; // kernels: accum 3 points, unique centroids StopWatch swKernel3u; @@ -1409,9 +1408,9 @@ static void verifyMinMaxIndexPQDecoder( // evaluate the error const double error3u = getError(n, d, outputFaiss, outputKernel3u); - std::cout << description << "\t" << n << "\t" << d << "\t" - << "accum3u_rnd" << "\t" << nIterations << "\t" << timeFaiss - << "\t" << timeKernel3u << "\t" << error3u << std::endl; + std::cout << description << "\t" << n << "\t" << d << "\taccum3u_rnd\t" + << nIterations << "\t" << timeFaiss << "\t" << timeKernel3u + << "\t" << error3u << std::endl; } } @@ -1484,8 +1483,10 @@ int main(int argc, char** argv) { (N_ITERATIONS % 6) == 0, "Number of iterations should be 6*x"); // print the header - std::cout << "Codec\t" << "n\t" << "d\t" << "Experiment\t" << "Iterations\t" - << "Faiss time\t" << "SADecodeKernel time\t" << "Error" + auto delim = "\t"; + std::cout << "Codec" << delim << "n" << delim << "d" << delim + << "Experiment" << delim << "Iterations" << delim << "Faiss time" + << delim << "SADecodeKernel time" << delim << "Error" << std::endl; // The following experiment types are available: From 72571c767d5f263bf92b5b20930f9403b6f88d0d Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 15 May 2024 13:42:27 -0700 Subject: [PATCH 162/206] Enable both RAFT package builds and CUDA 12.1.1 GPU package build (#3441) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3441 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D57372738 fbshipit-source-id: 745b3c3f43c49045f8f5035e2af302ffa30d7755 --- .github/workflows/build.yml | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc7f73c147..6a9114628c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,6 +116,56 @@ jobs: - uses: ./.github/actions/build_conda with: label: main + linux-x86_64-GPU-RAFT-packages-CUDA11-8-0: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + raft: "ON" + cuda: "11.8.0" + compiler_version: "11.2" + linux-x86_64-GPU-packages-CUDA-12-1-1: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + cuda: "12.1.1" + compiler_version: "11.2" + linux-x86_64-GPU-RAFT-packages-CUDA12-1-1: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + raft: "ON" + cuda: "12.1.1" + compiler_version: "11.2" windows-x86_64-packages: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: windows-2019 From 1876925e84be6c75cb5c42fc9b2c50a39782d821 Mon Sep 17 00:00:00 2001 From: Amir Sadoughi Date: Wed, 15 May 2024 17:53:30 -0700 Subject: [PATCH 163/206] Implement METRIC.NaNEuclidean (#3414) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3414 https://github.com/facebookresearch/faiss/issues/3355 A couple open questions: - Given L2 was squared, I figured I would leave this one as squared as well? - Also, wasn't sure if we wanted to return nan when present == 0 or -1? Reviewed By: mdouze Differential Revision: D57017608 fbshipit-source-id: ba14458b92c8b055f3bf2a871565175935c8333a --- faiss/MetricType.h | 1 + faiss/utils/extra_distances-inl.h | 20 ++++++++++++++++++++ faiss/utils/extra_distances.cpp | 3 +++ tests/test_extra_distances.py | 20 ++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/faiss/MetricType.h b/faiss/MetricType.h index 538b0a8e72..4689d4d018 100644 --- a/faiss/MetricType.h +++ b/faiss/MetricType.h @@ -33,6 +33,7 @@ enum MetricType { METRIC_JensenShannon, METRIC_Jaccard, ///< defined as: sum_i(min(a_i, b_i)) / sum_i(max(a_i, b_i)) ///< where a_i, b_i > 0 + METRIC_NaNEuclidean, }; /// all vector indices are this type diff --git a/faiss/utils/extra_distances-inl.h b/faiss/utils/extra_distances-inl.h index d3768df668..5b21482d18 100644 --- a/faiss/utils/extra_distances-inl.h +++ b/faiss/utils/extra_distances-inl.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace faiss { @@ -130,4 +131,23 @@ inline float VectorDistance::operator()( return accu_num / accu_den; } +template <> +inline float VectorDistance::operator()( + const float* x, + const float* y) const { + // https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.nan_euclidean_distances.html + float accu = 0; + size_t present = 0; + for (size_t i = 0; i < d; i++) { + if (!std::isnan(x[i]) && !std::isnan(y[i])) { + float diff = x[i] - y[i]; + accu += diff * diff; + present++; + } + } + if (present == 0) { + return NAN; + } + return float(d) / float(present) * accu; +} } // namespace faiss diff --git a/faiss/utils/extra_distances.cpp b/faiss/utils/extra_distances.cpp index 8c0699880d..fb225e7c9e 100644 --- a/faiss/utils/extra_distances.cpp +++ b/faiss/utils/extra_distances.cpp @@ -164,6 +164,7 @@ void pairwise_extra_distances( HANDLE_VAR(JensenShannon); HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); + HANDLE_VAR(NaNEuclidean); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); @@ -195,6 +196,7 @@ void knn_extra_metrics( HANDLE_VAR(JensenShannon); HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); + HANDLE_VAR(NaNEuclidean); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); @@ -242,6 +244,7 @@ FlatCodesDistanceComputer* get_extra_distance_computer( HANDLE_VAR(JensenShannon); HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); + HANDLE_VAR(NaNEuclidean); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); diff --git a/tests/test_extra_distances.py b/tests/test_extra_distances.py index a474dd6ba7..66318f76c5 100644 --- a/tests/test_extra_distances.py +++ b/tests/test_extra_distances.py @@ -94,6 +94,26 @@ def test_jaccard(self): new_dis = faiss.pairwise_distances(xq, yb, faiss.METRIC_Jaccard) self.assertTrue(np.allclose(ref_dis, new_dis)) + def test_nan_euclidean(self): + xq, yb = self.make_example() + ref_dis = np.array([ + [scipy.spatial.distance.sqeuclidean(x, y) for y in yb] + for x in xq + ]) + new_dis = faiss.pairwise_distances(xq, yb, faiss.METRIC_NaNEuclidean) + self.assertTrue(np.allclose(ref_dis, new_dis)) + + x = [[3, np.nan, np.nan, 6]] + q = [[1, np.nan, np.nan, 5]] + dis = [(4 / 2 * ((3 - 1)**2 + (6 - 5)**2))] + new_dis = faiss.pairwise_distances(x, q, faiss.METRIC_NaNEuclidean) + self.assertTrue(np.allclose(new_dis, dis)) + + x = [[np.nan] * 4] + q = [[np.nan] * 4] + new_dis = faiss.pairwise_distances(x, q, faiss.METRIC_NaNEuclidean) + self.assertTrue(np.isnan(new_dis[0])) + class TestKNN(unittest.TestCase): """ test that the knn search gives the same as distance matrix + argmin """ From 4972abd36ca78ff66aba171cbfaa5a001e2ca090 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Thu, 16 May 2024 14:22:08 -0700 Subject: [PATCH 164/206] Improve testing code step 1 (#3451) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3451 This is a first step to clean up the faiss codebase following T187322081 Reviewed By: junjieqi Differential Revision: D57448335 fbshipit-source-id: c9760d01479d3352b786bbcf2015251e7a7168d6 --- tests/test_index_binary.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_index_binary.py b/tests/test_index_binary.py index 3acf622fd4..7820cb6627 100644 --- a/tests/test_index_binary.py +++ b/tests/test_index_binary.py @@ -142,7 +142,6 @@ def test_range_search(self): self.assertTrue(set(range_res) <= set(I[i])) nt2 += 1 # in case of equality we have a problem with ties - print('nb tests', nt1, nt2) # nb tests is actually low... self.assertTrue(nt1 > 19 and nt2 > 19) @@ -287,8 +286,6 @@ def test_ivf_nprobe(self): ref_index.add(xb) ref_D, ref_I = ref_index.search(xq, k) - print(D[0], ref_D[0]) - print(I[0], ref_I[0]) assert np.all(D == ref_D) # assert np.all(I == ref_I) # id may be different From bf8bd6b689f25a1a13c09f4363d8ea9bf6bf7a3a Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Thu, 16 May 2024 19:51:07 -0700 Subject: [PATCH 165/206] Delete all remaining print (#3452) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3452 Delete all remaining print within the Tests to improve the readability and effectiveness of the codebase. Reviewed By: junjieqi Differential Revision: D57466393 fbshipit-source-id: 6ebd66ae2e769894d810d4ba7a5f69fc865b797d --- tests/common_faiss_tests.py | 1 - tests/test_RCQ_cropping.cpp | 2 -- tests/test_clustering.py | 3 --- tests/test_contrib.py | 2 -- tests/test_contrib_with_scipy.py | 2 -- tests/test_fast_scan.py | 3 --- tests/test_index_composite.py | 3 --- tests/test_local_search_quantizer.py | 6 ------ tests/test_partition.py | 6 ------ tests/test_product_quantizer.py | 1 - tests/test_residual_quantizer.py | 14 -------------- tests/test_rowwise_minmax.py | 1 - tests/test_standalone_codec.py | 9 --------- 13 files changed, 53 deletions(-) diff --git a/tests/common_faiss_tests.py b/tests/common_faiss_tests.py index 8dc25edec0..a8afe344e4 100644 --- a/tests/common_faiss_tests.py +++ b/tests/common_faiss_tests.py @@ -49,7 +49,6 @@ def evalres(self, DI): for rank in 1, 10, 100: e[rank] = ((I[:, :rank] == self.gt.reshape(-1, 1)).sum() / float(self.nq)) - # print("1-recalls: %s" % e) return e diff --git a/tests/test_RCQ_cropping.cpp b/tests/test_RCQ_cropping.cpp index 4dd3470885..4463c256ed 100644 --- a/tests/test_RCQ_cropping.cpp +++ b/tests/test_RCQ_cropping.cpp @@ -28,7 +28,6 @@ TEST(RCQCropping, test_cropping) { faiss::ResidualCoarseQuantizer rcq(d, nbits); rcq.train(nt, xt); - // fprintf(stderr, "nb centroids: %zd\n", rcq.ntotal); // the test below works only for beam size == nprobe rcq.set_beam_factor(1.0); @@ -44,7 +43,6 @@ TEST(RCQCropping, test_cropping) { nbits.pop_back(); faiss::ResidualCoarseQuantizer rcq_cropped(d, nbits); rcq_cropped.initialize_from(rcq); - // fprintf(stderr, "cropped nb centroids: %zd\n", rcq_cropped.ntotal); EXPECT_EQ(rcq_cropped.ntotal, rcq.ntotal >> last_nbits); diff --git a/tests/test_clustering.py b/tests/test_clustering.py index 2b81fc3e35..b1afc8523f 100644 --- a/tests/test_clustering.py +++ b/tests/test_clustering.py @@ -110,9 +110,6 @@ def test_weighted(self): cdis2_first = cdis2[:5].sum() cdis2_last = cdis2[5:].sum() - print(cdis1_first, cdis1_last) - print(cdis2_first, cdis2_last) - # with the new clustering, the last should be much (*2) closer # to their centroids self.assertGreater(cdis1_last, cdis1_first * 2) diff --git a/tests/test_contrib.py b/tests/test_contrib.py index 0e7cbbfb03..05a2c4ac8b 100644 --- a/tests/test_contrib.py +++ b/tests/test_contrib.py @@ -147,7 +147,6 @@ def test_query_iterator(self, metric=faiss.METRIC_L2): xb = ds.get_database() D, I = faiss.knn(xq, xb, 10, metric=metric) threshold = float(D[:, -1].mean()) - print(threshold) index = faiss.IndexFlat(32, metric) index.add(xb) @@ -251,7 +250,6 @@ def test_precision_recall(self): Inew = np.hstack(Inew) precision, recall = evaluation.range_PR(lims_ref, Iref, lims_new, Inew) - print(precision, recall) self.assertEqual(precision, 0.6) self.assertEqual(recall, 0.6) diff --git a/tests/test_contrib_with_scipy.py b/tests/test_contrib_with_scipy.py index cb81bb623c..4f89e2fc1b 100644 --- a/tests/test_contrib_with_scipy.py +++ b/tests/test_contrib_with_scipy.py @@ -44,7 +44,6 @@ def test_sparse_routines(self): faiss.normalize_L2(xt) mask = np.abs(xt) > 0.045 - # print("fraction:", mask.sum() / mask.size) # around 10% non-zeros xt[np.logical_not(mask)] = 0 centroids = ds.get_queries() @@ -72,7 +71,6 @@ def test_sparse_kmeans(self): faiss.normalize_L2(xt) mask = np.abs(xt) > 0.045 - # print("fraction:", mask.sum() / mask.size) # around 10% non-zeros xt[np.logical_not(mask)] = 0 km = faiss.Kmeans(ds.d, 50) diff --git a/tests/test_fast_scan.py b/tests/test_fast_scan.py index b061ee3af0..cfe9636fee 100644 --- a/tests/test_fast_scan.py +++ b/tests/test_fast_scan.py @@ -34,7 +34,6 @@ def test_PQ4_accuracy(self): nq = Iref.shape[0] recall_at_1 = (Iref[:, 0] == Ia[:, 0]).sum() / nq assert recall_at_1 > 0.6 - # print(f'recall@1 = {recall_at_1:.3f}') # This is an experiment to see if we can catch performance @@ -498,7 +497,6 @@ def subtest_accuracy(self, aq, st, implem, metric_type='L2'): recall_ref = (Iref == gt).sum() / nq recall = (Ia == gt).sum() / nq - print(aq, st, implem, metric_type, recall_ref, recall) assert abs(recall_ref - recall) < 0.05 def xx_test_accuracy(self): @@ -531,7 +529,6 @@ def subtest_from_idxaq(self, implem, metric): nq = Iref.shape[0] recall_ref = (Iref == gt).sum() / nq recall1 = (I1 == gt).sum() / nq - print(recall_ref, recall1) assert abs(recall_ref - recall1) < 0.05 def xx_test_from_idxaq(self): diff --git a/tests/test_index_composite.py b/tests/test_index_composite.py index a760c0cf09..8d9b441adc 100644 --- a/tests/test_index_composite.py +++ b/tests/test_index_composite.py @@ -168,8 +168,6 @@ def test_remove_id_map_2(self): index.remove_ids(remove_set) index.add_with_ids(X[5:, :], idx[5:]) - print (index.search(X, 1)) - for i in range(10): _, searchres = index.search(X[i:i + 1, :], 1) if idx[i] in remove_set: @@ -954,7 +952,6 @@ def do_test(self, factory_string): index.nprobe = 10 Dref, Iref = index.search(ds.get_queries(), 10) - #print(index.search_and_return_codes) D, I, codes = index.search_and_return_codes( ds.get_queries(), 10, include_listnos=True) diff --git a/tests/test_local_search_quantizer.py b/tests/test_local_search_quantizer.py index 01fec70ccf..7975929811 100644 --- a/tests/test_local_search_quantizer.py +++ b/tests/test_local_search_quantizer.py @@ -196,7 +196,6 @@ def test_update_codebooks_with_double(self): err_float = eval_codec(lsq, xb) # 6533.377 vs 25457.99 - print(err_double, err_float) self.assertLess(err_double, err_float) def test_compute_binary_terms(self): @@ -348,7 +347,6 @@ def test_training(self): pq.train(xt) err_pq = eval_codec(pq, xb) - print(err_lsq, err_pq) self.assertLess(err_lsq, err_pq) @@ -463,7 +461,6 @@ def eval_index_accuracy(self, factory_key): index.nprobe = nprobe D, I = index.search(ds.get_queries(), 10) inter = faiss.eval_intersection(I, ds.get_groundtruth(10)) - # print("nprobe=", nprobe, "inter=", inter) inters.append(inter) inters = np.array(inters) @@ -528,7 +525,6 @@ def test_codec(self): pq.train(xt) err_pq = eval_codec(pq, xb) - print(err_plsq, err_pq) self.assertLess(err_plsq, err_pq) def test_with_lsq(self): @@ -549,7 +545,6 @@ def test_with_lsq(self): lsq.train(xt) err_lsq = eval_codec(lsq, xb) - print(err_plsq, err_lsq) self.assertEqual(err_plsq, err_lsq) def test_lut(self): @@ -664,7 +659,6 @@ def test_index_accuracy2(self): """check that the error is in the same ballpark as LSQ.""" inter1 = self.eval_index_accuracy("IVF32,PLSQ2x2x5_Nqint8") inter2 = self.eval_index_accuracy("IVF32,LSQ4x5_Nqint8") - # print(inter1, inter2) # 381 vs 374 self.assertGreaterEqual(inter1 * 1.1, inter2) def test_factory(self): diff --git a/tests/test_partition.py b/tests/test_partition.py index 02de7e8c2c..fd41eabe1f 100644 --- a/tests/test_partition.py +++ b/tests/test_partition.py @@ -49,7 +49,6 @@ def do_partition(self, n, q, maxval=None, seed=None): if seed is None: for i in range(50): self.do_partition(n, q, maxval, i + 1234) - # print("seed=", seed) rs = np.random.RandomState(seed) if maxval is None: vals = rs.rand(n).astype('float32') @@ -95,7 +94,6 @@ def do_partition(self, n, q, maxval=None, seed=None): if seed is None: for i in range(50): self.do_partition(n, q, maxval, i + 1234) - # print("seed=", seed) rs = np.random.RandomState(seed) if maxval is None: vals = rs.rand(n).astype('float32') @@ -148,7 +146,6 @@ def do_partition(self, n, q, maxval=65536, seed=None): for i in range(50): self.do_partition(n, q, maxval, i + 1234) - # print("seed=", seed) rs = np.random.RandomState(seed) vals = rs.randint(maxval, size=n).astype('uint16') ids = (rs.permutation(n) + 12345).astype('int64') @@ -160,7 +157,6 @@ def do_partition(self, n, q, maxval=65536, seed=None): tab_a = faiss.AlignedTableUint16() faiss.copy_array_to_AlignedTable(vals, tab_a) - # print("tab a type", tab_a.get()) if type(q) == int: faiss.CMax_uint16_partition_fuzzy( tab_a.get(), sp(ids), n, q, q, None) @@ -196,7 +192,6 @@ def do_partition(self, n, q, maxval=65536, seed=None): if seed is None: for i in range(50): self.do_partition(n, q, maxval, i + 1234) - # print("seed=", seed) rs = np.random.RandomState(seed) vals = rs.randint(maxval, size=n).astype('uint16') ids = (rs.permutation(n) + 12345).astype('int64') @@ -209,7 +204,6 @@ def do_partition(self, n, q, maxval=65536, seed=None): vals_inv = (65535 - vals).astype('uint16') faiss.copy_array_to_AlignedTable(vals_inv, tab_a) - # print("tab a type", tab_a.get()) if type(q) == int: faiss.CMin_uint16_partition_fuzzy( tab_a.get(), sp(ids), n, q, q, None) diff --git a/tests/test_product_quantizer.py b/tests/test_product_quantizer.py index 1cdee7f144..e05426b129 100644 --- a/tests/test_product_quantizer.py +++ b/tests/test_product_quantizer.py @@ -26,7 +26,6 @@ def test_pq(self): x2 = pq.decode(codes) diff = ((x - x2)**2).sum() - # print("diff=", diff) # diff= 4418.0562 self.assertGreater(5000, diff) diff --git a/tests/test_residual_quantizer.py b/tests/test_residual_quantizer.py index e37ee3efe2..f87e7650d9 100644 --- a/tests/test_residual_quantizer.py +++ b/tests/test_residual_quantizer.py @@ -211,7 +211,6 @@ def test_training(self): # in practice RQ is often better than PQ but it does not the case here, so just check # that we are within some factor. - # print(err_pq, err_rq) self.assertLess(err_rq, err_pq * 1.2) def test_beam_size(self): @@ -321,10 +320,8 @@ def retrain_AQ_codebook(index, xt): x_decoded = index.sa_decode(codes_packed) MSE = ((xt - x_decoded) ** 2).sum() / n - # print(f"Initial MSE on training set: {MSE:g}") codes = unpack_codes(index.rq, codes_packed) - # print("ref codes", codes[0]) codebook_offsets = faiss.vector_to_array(rq.codebook_offsets) # build sparse code matrix (represented as a dense matrix) @@ -343,7 +340,6 @@ def retrain_AQ_codebook(index, xt): B, residuals, rank, singvals = scipy.linalg.lstsq(C, xt, ) MSE = ((C @ B - xt) ** 2).sum() / n - # print(f"MSE after retrainining: {MSE:g}") # replace codebook # faiss.copy_array_to_vector(B.astype('float32').ravel(), index.rq.codebooks) @@ -503,7 +499,6 @@ def test_reestimate_codebook_2(self): xt_decoded = ir.sa_decode(ir.sa_encode(xt)) err_after_refined = ((xt - xt_decoded) ** 2).sum() - # print(err_before, err_after_refined) # ref run 7474.98 / 7006.1777 self.assertGreater(err_before, err_after_refined * 1.06) @@ -781,7 +776,6 @@ def test_search_L2(self): else: inter_2 = faiss.eval_intersection(I2, gt) self.assertGreaterEqual(inter_ref, inter_2) - # print(st, inter_ref, inter_2) ########################################################### @@ -814,7 +808,6 @@ def do_test_accuracy(self, by_residual, st): index.nprobe = nprobe D, I = index.search(ds.get_queries(), 10) inter = faiss.eval_intersection(I, ds.get_groundtruth(10)) - # print(st, "nprobe=", nprobe, "inter=", inter) inters.append(inter) # do a little I/O test @@ -909,18 +902,13 @@ def do_test_accuracy_IP(self, by_residual): D, I = index.search(ds.get_queries(), 10) index.rq.search_type = faiss.AdditiveQuantizer.ST_LUT_nonorm D2, I2 = index.search(ds.get_queries(), 10) - # print(D[:5] - D2[:5]) - # print(I[:5]) np.testing.assert_array_almost_equal(D, D2, decimal=5) # there are many ties because the codes are so short self.assertLess((I != I2).sum(), I.size * 0.1) # D2, I2 = index2.search(ds.get_queries(), 10) - # print(D[:5]) - # print(D2[:5]) inter = faiss.eval_intersection(I, ds.get_groundtruth(10)) - # print("nprobe=", nprobe, "inter=", inter) inters.append(inter) self.assertTrue(np.all(inters[1:4] >= inters[:3])) @@ -1166,7 +1154,6 @@ def test_codec(self): pq.train(xt) err_pq = eval_codec(pq, xb) - # print(err_prq, err_pq) self.assertLess(err_prq, err_pq) def test_with_rq(self): @@ -1271,7 +1258,6 @@ def test_index_accuracy2(self): """check that the error is in the same ballpark as RQ.""" inter1 = self.eval_index_accuracy("IVF100,PRQ2x2x5_Nqint8") inter2 = self.eval_index_accuracy("IVF100,RQ4x5_Nqint8") - # print(inter1, inter2) # 392 vs 374 self.assertGreaterEqual(inter1 * 1.1, inter2) def test_factory(self): diff --git a/tests/test_rowwise_minmax.py b/tests/test_rowwise_minmax.py index dbd14de388..53e6c00b15 100644 --- a/tests/test_rowwise_minmax.py +++ b/tests/test_rowwise_minmax.py @@ -45,7 +45,6 @@ def compare_train_vs_train_inplace(self, factory_key): # make sure that the reconstruction error is not crazy reconstruction_err = ((x - decoded) ** 2).sum() - print(reconstruction_err) self.assertLess(reconstruction_err, 0.6) diff --git a/tests/test_standalone_codec.py b/tests/test_standalone_codec.py index 7fdcf6849f..2176a12e99 100644 --- a/tests/test_standalone_codec.py +++ b/tests/test_standalone_codec.py @@ -151,7 +151,6 @@ def compare_accuracy(self, lowac, highac, max_errs=(1e10, 1e10)): err = ((x - x2) ** 2).sum() errs.append(err) - print(errs) self.assertGreater(errs[0], errs[1]) self.assertGreater(max_errs[0], errs[0]) @@ -214,7 +213,6 @@ def test_repeats(self): code = repeats.encode(swig_ptr(vec)) vec2 = np.zeros(dim, dtype='float32') repeats.decode(code, swig_ptr(vec2)) - # print(vec2) assert np.all(vec == vec2) def test_ZnSphereCodec_encode_centroid(self): @@ -222,7 +220,6 @@ def test_ZnSphereCodec_encode_centroid(self): r2 = 5 ref_codec = faiss.ZnSphereCodec(dim, r2) codec = faiss.ZnSphereCodecRec(dim, r2) - # print(ref_codec.nv, codec.nv) assert ref_codec.nv == codec.nv s = set() for i in range(ref_codec.nv): @@ -237,7 +234,6 @@ def test_ZnSphereCodecRec(self): dim = 16 r2 = 6 codec = faiss.ZnSphereCodecRec(dim, r2) - # print("nv=", codec.nv) for i in range(codec.nv): c = np.zeros(dim, dtype='float32') codec.decode(i, swig_ptr(c)) @@ -300,15 +296,10 @@ def test_rw(self): for i in range(nbyte): self.assertTrue(((bignum >> (i * 8)) & 255) == bs[i]) - #for i in range(nbyte): - # print(bin(bs[i] + 256)[3:], end=' ') - # print() - br = faiss.BitstringReader(swig_ptr(bs), nbyte) for nbit, xref in ctrl: xnew = br.read(nbit) - # print('nbit %d xref %x xnew %x' % (nbit, xref, xnew)) self.assertTrue(xnew == xref) def test_arrays(self): From e822a8c152374c318ca1ae43f06a49af456f18c3 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Fri, 17 May 2024 12:02:55 -0700 Subject: [PATCH 166/206] GitHub Actions files cleanup (#3454) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3454 Removing commented out lines and adding proper descriptions and comments where appropriate. Reviewed By: junjieqi Differential Revision: D57501602 fbshipit-source-id: 0202ff73b7a83158808affba9b98b96dff569457 --- .github/actions/build_cmake/action.yml | 10 +++++----- .github/actions/build_conda/action.yml | 16 +++++++--------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index 510d4c9dc3..a46462c8d9 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -1,15 +1,15 @@ name: Build cmake inputs: opt_level: - description: 'The optimization level' + description: 'Compile options / optimization level.' required: false default: generic gpu: - description: 'The GPU to use' + description: 'Enable GPU support.' required: false default: OFF raft: - description: 'The raft to use' + description: 'Enable RAFT support.' required: false default: OFF runs: @@ -20,12 +20,12 @@ runs: with: python-version: '3.11' miniconda-version: latest - - name: Set up environment + - name: Initialize Conda environment shell: bash run: | conda config --set solver libmamba conda update -y -q conda - - name: Configure conda environment + - name: Configure Conda environment shell: bash run: | conda install -y -q -c conda-forge gxx_linux-64=11.2 sysroot_linux-64=2.28 diff --git a/.github/actions/build_conda/action.yml b/.github/actions/build_conda/action.yml index 7e4510b4b2..ec407e6569 100644 --- a/.github/actions/build_conda/action.yml +++ b/.github/actions/build_conda/action.yml @@ -1,21 +1,21 @@ -name: Build conda -description: Build conda +name: Conda build +description: Builds FAISS inside a Conda environment and uploads to repository when label is provided. inputs: label: - description: "Label" + description: "The label to be used for uploads to Conda." default: "" required: false cuda: - description: "cuda" + description: "CUDA toolkit version to use." default: "" required: false raft: - description: "raft" + description: "Enable RAFT support." default: "" required: false compiler_version: description: "compiler_version" - default: "" + default: "Compiler version for C/C++/CUDA." required: false runs: using: composite @@ -24,7 +24,7 @@ runs: shell: bash id: choose_shell run: | - # if runner.os != 'Windows' use bash, else use pwsh + # Use pwsh on Windows; bash everywhere else if [ "${{ runner.os }}" != "Windows" ]; then echo "shell=bash" >> "$GITHUB_OUTPUT" else @@ -38,8 +38,6 @@ runs: - name: Install conda build tools shell: ${{ steps.choose_shell.outputs.shell }} run: | - # conda config --set solver libmamba - # conda config --set verbosity 3 conda update -y -q conda conda install -y -q conda-build - name: Enable anaconda uploads From 5e452ed52a976226e33eb9c90c34b3ede0193f3a Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Fri, 17 May 2024 16:59:36 -0700 Subject: [PATCH 167/206] Cleaning up more unnecessary print (#3455) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3455 Code quality control by reducing the number of prints Reviewed By: junjieqi Differential Revision: D57502194 fbshipit-source-id: a6cd65ed4cc49590ce73d2978d41b640b5259c17 --- tests/test_binary_hashindex.py | 10 ---------- tests/test_build_blocks.py | 15 --------------- tests/test_graph_based.py | 7 ------- tests/test_index.py | 5 ----- tests/test_index_accuracy.py | 24 ------------------------ tests/test_io.py | 1 - tests/test_ivflib.py | 1 - tests/test_lowlevel_ivf.cpp | 13 ------------- tests/test_merge_index.py | 1 - tests/test_meta_index.py | 7 ------- tests/test_product_quantizer.py | 1 - tests/test_residual_quantizer.py | 3 --- tests/test_search_params.py | 1 - tests/test_sliding_ivf.cpp | 16 ---------------- 14 files changed, 105 deletions(-) diff --git a/tests/test_binary_hashindex.py b/tests/test_binary_hashindex.py index 2d33050571..e9a6eaca49 100644 --- a/tests/test_binary_hashindex.py +++ b/tests/test_binary_hashindex.py @@ -58,8 +58,6 @@ def test_hash(self): Lref, Dref, Iref = index_ref.range_search(xq, radius) - print("nb res: ", Lref[-1]) - index = faiss.IndexBinaryHash(d, 10) index.add(xb) # index.display() @@ -80,8 +78,6 @@ def test_hash(self): self.assertTrue(snew <= set(ref)) nfound.append(Lnew[-1]) ndis.append(stats.ndis) - print('nfound=', nfound) - print('ndis=', ndis) nfound = np.array(nfound) self.assertTrue(nfound[-1] == Lref[-1]) self.assertTrue(np.all(nfound[1:] >= nfound[:-1])) @@ -100,8 +96,6 @@ def test_multihash(self): Lref, Dref, Iref = index_ref.range_search(xq, radius) - print("nb res: ", Lref[-1]) - nfound = [] ndis = [] @@ -123,8 +117,6 @@ def test_multihash(self): self.assertTrue(snew <= set(ref)) nfound.append(Lnew[-1]) ndis.append(stats.ndis) - print('nfound=', nfound) - print('ndis=', ndis) nfound = np.array(nfound) # self.assertTrue(nfound[-1] == Lref[-1]) self.assertTrue(np.all(nfound[1:] >= nfound[:-1])) @@ -163,7 +155,6 @@ def test_hash_and_multihash(self): # no duplicates self.assertTrue(len(new) == len(snew)) nf += len(set(ref) & snew) - print('nfound', nh, nbit, nf) nfound[(nh, nbit)] = nf self.assertGreater(nfound[(nh, 4)], nfound[(nh, 7)]) @@ -175,7 +166,6 @@ def test_hash_and_multihash(self): np.testing.assert_array_equal(Inew, I2) np.testing.assert_array_equal(Dnew, D2) - print('nfound=', nfound) self.assertGreater(3, abs(nfound[(0, 7)] - nfound[(1, 7)])) self.assertGreater(nfound[(3, 7)], nfound[(1, 7)]) self.assertGreater(nfound[(5, 7)], nfound[(3, 7)]) diff --git a/tests/test_build_blocks.py b/tests/test_build_blocks.py index 0a97e63185..fdf9ad8bd7 100644 --- a/tests/test_build_blocks.py +++ b/tests/test_build_blocks.py @@ -189,7 +189,6 @@ def test_l2(self): for d in 1, 2, 4, 8, 12, 16: x = rs.rand(d).astype('float32') for ny in 128, 129, 130: - print("d=%d ny=%d" % (d, ny)) y = rs.rand(ny, d).astype('float32') ref = ((x - y) ** 2).sum(1) new = np.zeros(ny, dtype='float32') @@ -204,7 +203,6 @@ def test_IP(self): for d in 1, 2, 4, 8, 12, 16: x = rs.rand(d).astype('float32') for ny in 128, 129, 130: - print("d=%d ny=%d" % (d, ny)) y = rs.rand(ny, d).astype('float32') ref = (x * y).sum(1) new = np.zeros(ny, dtype='float32') @@ -220,7 +218,6 @@ def test_0s(self): m = rs.rand(40, 20).astype('float32') m[5:10] = 0 comments = faiss.MatrixStats(m).comments - print(comments) assert 'has 5 copies' in comments assert '5 null vectors' in comments @@ -229,7 +226,6 @@ def test_copies(self): m = rs.rand(40, 20).astype('float32') m[::2] = m[1::2] comments = faiss.MatrixStats(m).comments - print(comments) assert '20 vectors are distinct' in comments def test_dead_dims(self): @@ -237,7 +233,6 @@ def test_dead_dims(self): m = rs.rand(40, 20).astype('float32') m[:, 5:10] = 0 comments = faiss.MatrixStats(m).comments - print(comments) assert '5 dimensions are constant' in comments def test_rogue_means(self): @@ -245,7 +240,6 @@ def test_rogue_means(self): m = rs.rand(40, 20).astype('float32') m[:, 5:10] += 12345 comments = faiss.MatrixStats(m).comments - print(comments) assert '5 dimensions are too large wrt. their variance' in comments def test_normalized(self): @@ -253,7 +247,6 @@ def test_normalized(self): m = rs.rand(40, 20).astype('float32') faiss.normalize_L2(m) comments = faiss.MatrixStats(m).comments - print(comments) assert 'vectors are normalized' in comments def test_hash(self): @@ -300,7 +293,6 @@ def test_8bit_equiv(self): D, I = index.search(x[3:], 1) # assert D[0, 0] == Dref[0, 0] - # print(D[0, 0], ((x[3] - x[2]) ** 2).sum()) assert D[0, 0] == ((x[3] - x[2]) ** 2).sum() def test_6bit_equiv(self): @@ -314,8 +306,6 @@ def test_6bit_equiv(self): d, faiss.ScalarQuantizer.QT_6bit) index.train(trainset) - print('cs=', index.code_size) - x = rs.randint(64, size=(100, d)).astype('float32') # verify encoder / decoder @@ -330,7 +320,6 @@ def test_6bit_equiv(self): for i in range(20): for j in range(10): dis = ((y[i] - x2[I[i, j]]) ** 2).sum() - # print(dis, D[i, j]) assert abs(D[i, j] - dis) / dis < 1e-5 def test_reconstruct(self): @@ -371,7 +360,6 @@ def test_randint(self): x = faiss.randint(20000, vmax=100) assert np.all(x >= 0) and np.all(x < 100) c = np.bincount(x, minlength=100) - print(c) assert c.max() - c.min() < 50 * 2 def test_rand_vector(self): @@ -473,7 +461,6 @@ def do_test_array_type(self, dtype): """ tests swig_ptr and rev_swig_ptr for this type of array """ a = np.arange(12).astype(dtype) ptr = faiss.swig_ptr(a) - print(ptr) a2 = faiss.rev_swig_ptr(ptr, 12) np.testing.assert_array_equal(a, a2) @@ -547,7 +534,6 @@ def subtest(self, d, K, metric): recalls += 1 break recall = 1.0 * recalls / (nb * K) - print('Metric: {}, knng accuracy: {}'.format(metric_names[metric], recall)) assert recall > 0.99 def test_small_nndescent(self): @@ -656,7 +642,6 @@ def do_test_bucket_sort_inplace( rows, _ = np.where(tab == b) rows.sort() tab2[lims[b]:lims[b + 1]].sort() - # print(rows, tab2[lims[b] : lims[b + 1]]) rows = set(rows) self.assertEqual(rows, set(tab2[lims[b]:lims[b + 1]])) diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py index dd4212d717..d5ddbeec37 100644 --- a/tests/test_graph_based.py +++ b/tests/test_graph_based.py @@ -209,7 +209,6 @@ def subtest_add(self, build_type, thresh, metric=faiss.METRIC_L2): Dnsg, Insg = index.search(self.xq, 1) recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) self.assertGreaterEqual(recalls, thresh) self.subtest_connectivity(index, self.xb.shape[0]) self.subtest_io_and_clone(index, Dnsg, Insg) @@ -230,7 +229,6 @@ def subtest_build(self, knn_graph, thresh, metric=faiss.METRIC_L2): Dnsg, Insg = index.search(self.xq, 1) recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) self.assertGreaterEqual(recalls, thresh) self.subtest_connectivity(index, self.xb.shape[0]) @@ -286,7 +284,6 @@ def test_reset(self): index.add(self.xb) Dnsg, Insg = index.search(self.xq, 1) recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) self.assertGreaterEqual(recalls, 475) self.subtest_connectivity(index, self.xb.shape[0]) @@ -294,7 +291,6 @@ def test_reset(self): index.add(self.xb) Dnsg, Insg = index.search(self.xq, 1) recalls = (Iref == Insg).sum() - print('metric: {}, nb equal: {}'.format(metrics[metric], recalls)) self.assertGreaterEqual(recalls, 475) self.subtest_connectivity(index, self.xb.shape[0]) @@ -335,7 +331,6 @@ def test_nsg_pq(self): # test accuracy recalls = (Iref == I).sum() - print("IndexNSGPQ", recalls) self.assertGreaterEqual(recalls, 190) # 193 # test I/O @@ -361,7 +356,6 @@ def test_nsg_sq(self): # test accuracy recalls = (Iref == I).sum() - print("IndexNSGSQ", recalls) self.assertGreaterEqual(recalls, 405) # 411 # test I/O @@ -395,7 +389,6 @@ def test_nndescentflat(self): # test accuracy recalls = (Iref == I).sum() - print("IndexNNDescentFlat", recalls) self.assertGreaterEqual(recalls, 450) # 462 # do some IO tests diff --git a/tests/test_index.py b/tests/test_index.py index f46c6a94bf..b9f3dbd46b 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -338,7 +338,6 @@ def test_4variants_ivf(self): D, I = index.search(xq, 10) nok[qname] = (I[:, 0] == I_ref[:, 0]).sum() - print(nok, nq) self.assertGreaterEqual(nok['flat'], nq * 0.6) # The tests below are a bit fragile, it happens that the @@ -373,8 +372,6 @@ def test_4variants(self): D, I = index.search(xq, 10) nok[qname] = (I[:, 0] == I_ref[:, 0]).sum() - print(nok, nq) - self.assertGreaterEqual(nok['QT_8bit'], nq * 0.9) self.assertGreaterEqual(nok['QT_8bit'], nok['QT_4bit']) self.assertGreaterEqual(nok['QT_8bit'], nok['QT_8bit_uniform']) @@ -442,7 +439,6 @@ def norm1(x): recons_err = np.mean(norm1(R_flat - xb[I_flat])) - print('Reconstruction error = %.3f' % recons_err) if eps is not None: self.assertLessEqual(recons_err, eps) @@ -638,7 +634,6 @@ def test_reconstuct_after_add(self): # should not raise an exception index.reconstruct(5) - print(index.ntotal) index.reconstruct(150) diff --git a/tests/test_index_accuracy.py b/tests/test_index_accuracy.py index 3f7bfbd303..8d8b4a28f6 100644 --- a/tests/test_index_accuracy.py +++ b/tests/test_index_accuracy.py @@ -56,7 +56,6 @@ def test_ivf_kmeans(self): Dref, Iref = ivfk.search(ev.xq, 100) ivfk.parallel_mode = 1 Dnew, Inew = ivfk.search(ev.xq, 100) - print((Iref != Inew).sum(), Iref.size) assert (Iref != Inew).sum() < Iref.size / 5000.0 assert np.all(Dref == Dnew) @@ -136,8 +135,6 @@ def test_polysemous(self): res = ev.launch("Polysemous ht=%d" % index.polysemous_ht, index) e_polysemous = ev.evalres(res) - print(e_baseline, e_polysemous, index.polysemous_ht) - print(stats.n_hamming_pass, stats.ncode) # The randu dataset is difficult, so we are not too picky on # the results. Here we assert that we have < 10 % loss when # computing full PQ on fewer than 20% of the data. @@ -248,7 +245,6 @@ def subtest(self, mt): index.nprobe = 4 # hopefully more robust than 1 D, I = index.search(xq, 10) ninter = faiss.eval_intersection(I, gt_I) - print("(%d, %s): %d, " % (mt, repr(qname), ninter)) assert abs(ninter - self.ref_results[(mt, qname)]) <= 10 if qname == "6bit": @@ -264,7 +260,6 @@ def subtest(self, mt): radius = float(D[:, -1].max()) else: radius = float(D[:, -1].min()) - # print("radius", radius) lims, D3, I3 = index.range_search(xq, radius) ntot = ndiff = 0 @@ -278,14 +273,11 @@ def subtest(self, mt): Iref = set(I2[i, mask]) ndiff += len(Inew ^ Iref) ntot += len(Iref) - # print("ndiff %d / %d" % (ndiff, ntot)) assert ndiff < ntot * 0.01 for pm in 1, 2: - # print("parallel_mode=%d" % pm) index.parallel_mode = pm lims4, D4, I4 = index.range_search(xq, radius) - # print("sizes", lims4[1:] - lims4[:-1]) for qno in range(len(lims) - 1): Iref = I3[lims[qno]: lims[qno + 1]] Inew = I4[lims4[qno]: lims4[qno + 1]] @@ -485,7 +477,6 @@ def subtest(self, mt): D, I = index.search(xq, 10) ninter = faiss.eval_intersection(I, gt_I) - print("(%d, %s): %d, " % (mt, by_residual, ninter)) assert abs(ninter - self.ref_results[mt, by_residual]) <= 3 @@ -499,10 +490,6 @@ def subtest(self, mt): index.polysemous_ht = 20 D, I = index.search(xq, 10) ninter = faiss.eval_intersection(I, gt_I) - print( - "(%d, %s, %d): %d, " - % (mt, by_residual, index.polysemous_ht, ninter) - ) # polysemous behaves bizarrely on ARM assert ( @@ -516,7 +503,6 @@ def subtest(self, mt): radius = float(D[:, -1].max()) else: radius = float(D[:, -1].min()) - print("radius", radius) lims, D3, I3 = index.range_search(xq, radius) ntot = ndiff = 0 @@ -530,7 +516,6 @@ def subtest(self, mt): Iref = set(I2[i, mask]) ndiff += len(Inew ^ Iref) ntot += len(Iref) - print("ndiff %d / %d" % (ndiff, ntot)) assert ndiff < ntot * 0.02 def test_IVFPQ_non8bit(self): @@ -555,7 +540,6 @@ def test_IVFPQ_non8bit(self): D, I = index.search(xq, 10) ninter[v] = faiss.eval_intersection(I, gt_I) - print("ninter=", ninter) # this should be the case but we don't observe # that... Probavly too few test points # assert ninter['2x8'] > ninter['8x2'] @@ -623,9 +607,6 @@ def test_OPQ(self): res = ev.launch("OPQ", index) e_opq = ev.evalres(res) - print("e_pq=%s" % e_pq) - print("e_opq=%s" % e_opq) - # verify that OPQ better than PQ for r in 1, 10, 100: assert e_opq[r] > e_pq[r] @@ -656,7 +637,6 @@ def test_OIVFPQ(self): # verify same on OIVFPQ for r in 1, 10, 100: - print(e_oivfpq[r], e_ivfpq[r]) assert e_oivfpq[r] >= e_ivfpq[r] @@ -758,9 +738,6 @@ def test_sh(self): ninter = faiss.eval_intersection(I, gt_I) key = (nbit, tt, period) - print("(%d, %s, %g): %d, " % (nbit, repr(tt), period, - ninter)) - print(abs(ninter - self.ref_results[key])) assert abs(ninter - self.ref_results[key]) <= 14 @@ -799,7 +776,6 @@ def do_test(self, metric): # check that with refinement, the recall@10 is the same as # the original recall@100 recall2 = (I2 == Iref[:, :1]).sum() - # print("recalls", recall1, recall2) self.assertEqual(recall1, recall2) def test_IP(self): diff --git a/tests/test_io.py b/tests/test_io.py index dc8ac3dcfb..99dfe60847 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -102,7 +102,6 @@ def test_buf_read(self): reader = faiss.BufferedIOReader(reader, bsz) y = np.zeros_like(x) - print('nbytes=', y.nbytes) reader(faiss.swig_ptr(y), y.nbytes, 1) np.testing.assert_array_equal(x, y) diff --git a/tests/test_ivflib.py b/tests/test_ivflib.py index f19c3da45b..0a3fb8c87e 100644 --- a/tests/test_ivflib.py +++ b/tests/test_ivflib.py @@ -125,7 +125,6 @@ def test_range_search_with_parameters(self): Dpre, _ = index.search(xq, 15) radius = float(np.median(Dpre[:, -1])) - print("Radius=", radius) stats = faiss.cvar.indexIVF_stats stats.reset() Lref, Dref, Iref = index.range_search(xq, radius) diff --git a/tests/test_lowlevel_ivf.cpp b/tests/test_lowlevel_ivf.cpp index e28e2a946f..7ce90a1d2d 100644 --- a/tests/test_lowlevel_ivf.cpp +++ b/tests/test_lowlevel_ivf.cpp @@ -364,22 +364,9 @@ void test_lowlevel_access_binary(const char* index_key) { } } - printf("new before reroder: ["); - for (int j = 0; j < k; j++) - printf("%" PRId64 ",%d ", I[j], D[j]); - printf("]\n"); - // re-order heap heap_reorder>(k, D.data(), I.data()); - printf("ref: ["); - for (int j = 0; j < k; j++) - printf("%" PRId64 ",%d ", I_ref[j], D_ref[j]); - printf("]\nnew: ["); - for (int j = 0; j < k; j++) - printf("%" PRId64 ",%d ", I[j], D[j]); - printf("]\n"); - // check that we have the same results as the reference search for (int j = 0; j < k; j++) { // here the order is not guaranteed to be the same diff --git a/tests/test_merge_index.py b/tests/test_merge_index.py index 4417f57fe7..bdcc813f1c 100644 --- a/tests/test_merge_index.py +++ b/tests/test_merge_index.py @@ -72,7 +72,6 @@ def do_test_merge(self, index_type): index.merge_from(indexes[i], index.ntotal) _D, I = index.search(xq, k) - print(I[:5, :6]) ndiff = (I != Iref).sum() print('%d / %d differences' % (ndiff, nq * k)) diff --git a/tests/test_meta_index.py b/tests/test_meta_index.py index d53cad48f7..d0896e8ba2 100644 --- a/tests/test_meta_index.py +++ b/tests/test_meta_index.py @@ -82,10 +82,8 @@ def test_shards(self): k = 32 ref_index = faiss.IndexFlatL2(d) - print('ref search') ref_index.add(xb) _Dref, Iref = ref_index.search(xq, k) - print(Iref[:5, :6]) shard_index = faiss.IndexShards(d) shard_index_2 = faiss.IndexShards(d, True, False) @@ -109,7 +107,6 @@ def test_shards(self): for test_no in range(3): with_threads = test_no == 1 - print('shard search test_no = %d' % test_no) if with_threads: remember_nt = faiss.omp_get_max_threads() faiss.omp_set_num_threads(1) @@ -122,14 +119,10 @@ def test_shards(self): else: _D, I = shard_index_2.search(xq, k) - print(I[:5, :6]) - if with_threads: faiss.omp_set_num_threads(remember_nt) ndiff = (I != Iref).sum() - - print('%d / %d differences' % (ndiff, nq * k)) assert (ndiff < nq * k / 1000.) def test_shards_ivf(self): diff --git a/tests/test_product_quantizer.py b/tests/test_product_quantizer.py index e05426b129..f531cab2a1 100644 --- a/tests/test_product_quantizer.py +++ b/tests/test_product_quantizer.py @@ -70,7 +70,6 @@ def do_test_codec(self, nbit): def test_codec(self): for i in range(16): - print("Testing nbits=%d" % (i + 1)) self.do_test_codec(i + 1) diff --git a/tests/test_residual_quantizer.py b/tests/test_residual_quantizer.py index f87e7650d9..f4381607e1 100644 --- a/tests/test_residual_quantizer.py +++ b/tests/test_residual_quantizer.py @@ -967,8 +967,6 @@ def beam_search_encode_step_tab(codes, L, distances, codebook_cross_prods_i, for b in range(beam_size): dotprods[i, b, :] += cb[codes[i, b, j]] - # print("dps", dotprods[:3, :2, :4]) - new_distances += 2 * dotprods cent_distances = new_distances @@ -1174,7 +1172,6 @@ def test_with_rq(self): rq.train(xt) err_rq = eval_codec(rq, xb) - # print(err_prq, err_rq) self.assertEqual(err_prq, err_rq) diff --git a/tests/test_search_params.py b/tests/test_search_params.py index 22b845c2ea..886ffc0c62 100644 --- a/tests/test_search_params.py +++ b/tests/test_search_params.py @@ -465,7 +465,6 @@ def test_12_92(self): sp = faiss.swig_ptr selr.find_sorted_ids_bounds( len(ids), sp(ids), sp(j01[:1]), sp(j01[1:])) - print(j01) assert j01[0] >= j01[1] diff --git a/tests/test_sliding_ivf.cpp b/tests/test_sliding_ivf.cpp index ea9e53d6b5..0214dd72e8 100644 --- a/tests/test_sliding_ivf.cpp +++ b/tests/test_sliding_ivf.cpp @@ -74,8 +74,6 @@ void make_index_slices( for (int i = 0; i < total_size; i++) { sub_indexes.emplace_back(clone_index(trained_index)); - printf("preparing sub-index # %d\n", i); - Index* index = sub_indexes.back().get(); auto xb = make_data(nb * d); @@ -122,13 +120,10 @@ int test_sliding_window(const char* index_key) { auto xq = make_data(nq * d); for (int i = 0; i < total_size + window_size; i++) { - printf("doing step %d / %d\n", i, total_size + window_size); - // update the index window.step( i < total_size ? sub_indexes[i].get() : nullptr, i >= window_size); - printf(" current n_slice = %d\n", window.n_slice); auto new_res = search_index(index.get(), xq.data()); @@ -159,8 +154,6 @@ int test_sliding_invlists(const char* index_key) { auto xq = make_data(nq * d); for (int i = 0; i < total_size + window_size; i++) { - printf("doing step %d / %d\n", i, total_size + window_size); - // update the index std::vector ils; for (int j = i - window_size + 1; j <= i; j++) { @@ -178,8 +171,6 @@ int test_sliding_invlists(const char* index_key) { // will be deleted by the index index_ivf->replace_invlists(ci, true); - printf(" nb invlists = %zd\n", ils.size()); - auto new_res = search_index(index.get(), xq.data()); std::unique_ptr merged_index( @@ -188,13 +179,6 @@ int test_sliding_invlists(const char* index_key) { auto ref_res = search_index(merged_index.get(), xq.data()); EXPECT_EQ(ref_res.size(), new_res.size()); - - size_t ndiff = 0; - for (size_t j = 0; j < ref_res.size(); j++) { - if (ref_res[j] != new_res[j]) - ndiff++; - } - printf(" nb differences: %zd / %zd\n", ndiff, ref_res.size()); EXPECT_EQ(ref_res, new_res); } return 0; From 0c983f361ba0af23b7a1c434dcc042ac0c24b454 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 20 May 2024 12:50:08 -0700 Subject: [PATCH 168/206] Workaround for CUDA 11.4.4 build in Conda on Ubuntu 22 / v6 kernel (#3459) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3459 When building with CUDA 11.4.4, CMake does not properly include files under Conda environment. This workaround flattens the include sub-directories in to the include root. It will unblock us for now while we are looking for a fix through CMakeLists files or figure out if it's a CMake bug and it gets fixed. Reviewed By: junjieqi Differential Revision: D57545169 fbshipit-source-id: 9cbdd0866e00e899cc889930a59448da55d873c2 --- conda/faiss-gpu/build-lib.sh | 6 ++++++ conda/faiss-gpu/meta.yaml | 3 +++ 2 files changed, 9 insertions(+) diff --git a/conda/faiss-gpu/build-lib.sh b/conda/faiss-gpu/build-lib.sh index 2d25e9c5e6..41f4f02bbc 100755 --- a/conda/faiss-gpu/build-lib.sh +++ b/conda/faiss-gpu/build-lib.sh @@ -6,6 +6,12 @@ set -e +# Workaround for CUDA 11.4.4 builds. Moves all necessary headers to include root. +if [[ -n "$FAISS_FLATTEN_CONDA_INCLUDES" && "$FAISS_FLATTEN_CONDA_INCLUDES" == "1" ]]; then + cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/sysroot/usr/include/* $CONDA_PREFIX/include/ + cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/* $CONDA_PREFIX/include/ + cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/x86_64-conda-linux-gnu/* $CONDA_PREFIX/include/ +fi # Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so cmake -B _build \ diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index 3d614df1bf..db6b4e243f 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -43,6 +43,9 @@ outputs: - {{ pin_compatible('libfaiss', exact=True) }} script_env: - CUDA_ARCHS + {% if cudatoolkit == '11.4.4' %} + - FAISS_FLATTEN_CONDA_INCLUDES=1 + {% endif %} requirements: build: - {{ compiler('cxx') }} From 86bf74dc0c7e9d9d3b7a3f56fa8c4ef9b740b4cd Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 20 May 2024 12:50:08 -0700 Subject: [PATCH 169/206] Enable linux-x86_64-GPU-packages-CUDA-11-4-4 build via GitHub Actions (#3460) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3460 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D57545637 fbshipit-source-id: 8ee970e5642ae9354455d60d84019d4217884d3a --- .github/workflows/build.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6a9114628c..3ba83c7735 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,6 +116,22 @@ jobs: - uses: ./.github/actions/build_conda with: label: main + linux-x86_64-GPU-packages-CUDA-11-4-4: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + with: + label: main + cuda: "11.4.4" + compiler_version: "11.2" linux-x86_64-GPU-RAFT-packages-CUDA11-8-0: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 4-core-ubuntu-gpu-t4 From 7fc81841a2730b24e799ff299f6080f489e272cf Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 20 May 2024 12:50:08 -0700 Subject: [PATCH 170/206] Relax version requirements for action steps (#3461) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3461 Migration to GitHub Actions Reviewed By: junjieqi Differential Revision: D57545814 fbshipit-source-id: a3d08f8cf516ce26f8f16892eceef9e36bfe9f05 --- .github/actions/build_cmake/action.yml | 4 +-- .github/actions/build_conda/action.yml | 2 +- .github/workflows/build.yml | 34 +++++++++++++------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index a46462c8d9..cd023aaca7 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -16,7 +16,7 @@ runs: using: composite steps: - name: Setup miniconda - uses: conda-incubator/setup-miniconda@v3.0.3 + uses: conda-incubator/setup-miniconda@v3 with: python-version: '3.11' miniconda-version: latest @@ -97,7 +97,7 @@ runs: FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs $CONDA/bin/python -c "import faiss" 2>&1 | grep faiss.so LD_DEBUG=libs $CONDA/bin/python -c "import faiss" 2>&1 | grep faiss_avx2.so - name: Upload test results - uses: actions/upload-artifact@v4.3.1 + uses: actions/upload-artifact@v4 with: name: test-results-${{ inputs.opt_level }}-${{ inputs.gpu }}-${{ inputs.raft }} path: test-results diff --git a/.github/actions/build_conda/action.yml b/.github/actions/build_conda/action.yml index ec407e6569..4658f13a8f 100644 --- a/.github/actions/build_conda/action.yml +++ b/.github/actions/build_conda/action.yml @@ -31,7 +31,7 @@ runs: echo "shell=pwsh" >> "$GITHUB_OUTPUT" fi - name: Setup miniconda - uses: conda-incubator/setup-miniconda@v3.0.3 + uses: conda-incubator/setup-miniconda@v3 with: python-version: '3.11' miniconda-version: latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ba83c7735..3f31ae3b96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Install clang-format run: | sudo apt-get update -y @@ -40,13 +40,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake linux-x86_64-AVX2-cmake: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake with: opt_level: avx2 @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake with: opt_level: avx512 @@ -64,7 +64,7 @@ jobs: runs-on: 4-core-ubuntu-gpu-t4 steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake with: gpu: ON @@ -72,7 +72,7 @@ jobs: runs-on: 4-core-ubuntu-gpu-t4 steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake with: gpu: ON @@ -81,7 +81,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -90,7 +90,7 @@ jobs: runs-on: windows-2019 steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -99,7 +99,7 @@ jobs: runs-on: 2-core-ubuntu-arm steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -109,7 +109,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -123,7 +123,7 @@ jobs: CUDA_ARCHS: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -139,7 +139,7 @@ jobs: CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -156,7 +156,7 @@ jobs: CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -172,7 +172,7 @@ jobs: CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -187,7 +187,7 @@ jobs: runs-on: windows-2019 steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -199,7 +199,7 @@ jobs: runs-on: macos-14 steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true @@ -211,7 +211,7 @@ jobs: runs-on: 2-core-ubuntu-arm steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true From 8c95c6943bd21af530342e9d540f12dadc6fd28d Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 20 May 2024 14:30:36 -0700 Subject: [PATCH 171/206] Fix linter warnings in faiss-gpu Conda build script (#3463) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3463 Satisfying linter warnings from a previous change Reviewed By: junjieqi Differential Revision: D57581364 fbshipit-source-id: 9e9b7f963a27d2da54d0e85390cce2f9f773c502 --- conda/faiss-gpu/build-lib.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/conda/faiss-gpu/build-lib.sh b/conda/faiss-gpu/build-lib.sh index 41f4f02bbc..9957be96ea 100755 --- a/conda/faiss-gpu/build-lib.sh +++ b/conda/faiss-gpu/build-lib.sh @@ -7,10 +7,10 @@ set -e # Workaround for CUDA 11.4.4 builds. Moves all necessary headers to include root. -if [[ -n "$FAISS_FLATTEN_CONDA_INCLUDES" && "$FAISS_FLATTEN_CONDA_INCLUDES" == "1" ]]; then - cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/sysroot/usr/include/* $CONDA_PREFIX/include/ - cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/* $CONDA_PREFIX/include/ - cp -r -n $CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/x86_64-conda-linux-gnu/* $CONDA_PREFIX/include/ +if [ -n "$FAISS_FLATTEN_CONDA_INCLUDES" ] && [ "$FAISS_FLATTEN_CONDA_INCLUDES" = "1" ]; then + cp -r -n "$CONDA_PREFIX/x86_64-conda-linux-gnu/sysroot/usr/include/"* "$CONDA_PREFIX/include/" + cp -r -n "$CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/"* "$CONDA_PREFIX/include/" + cp -r -n "$CONDA_PREFIX/x86_64-conda-linux-gnu/include/c++/11.2.0/x86_64-conda-linux-gnu/"* "$CONDA_PREFIX/include/" fi # Build libfaiss.so/libfaiss_avx2.so/libfaiss_avx512.so From 0698ac72eff28406c40e0f1738dac39951cba74b Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Tue, 21 May 2024 09:07:47 -0700 Subject: [PATCH 172/206] Properly pass the label for conda upload steps (#3464) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3464 Migration to GitHub Reviewed By: algoriddle Differential Revision: D57593494 fbshipit-source-id: 726159b553d5544efcdfa064f5a82fd51ed793e9 --- .github/actions/build_conda/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/build_conda/action.yml b/.github/actions/build_conda/action.yml index 4658f13a8f..982430c351 100644 --- a/.github/actions/build_conda/action.yml +++ b/.github/actions/build_conda/action.yml @@ -44,7 +44,7 @@ runs: if: inputs.label != '' shell: ${{ steps.choose_shell.outputs.shell }} env: - PACKAGE_TYPE: inputs.label + PACKAGE_TYPE: ${{ inputs.label }} run: | conda install -y -q anaconda-client conda config --set anaconda_upload yes @@ -59,7 +59,7 @@ runs: shell: ${{ steps.choose_shell.outputs.shell }} working-directory: conda env: - PACKAGE_TYPE: inputs.label + PACKAGE_TYPE: ${{ inputs.label }} run: | conda build faiss --user pytorch --label ${{ inputs.label }} -c pytorch - name: Conda build (GPU) @@ -74,7 +74,7 @@ runs: shell: ${{ steps.choose_shell.outputs.shell }} working-directory: conda env: - PACKAGE_TYPE: inputs.label + PACKAGE_TYPE: ${{ inputs.label }} run: | conda build faiss-gpu --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ --user pytorch --label ${{ inputs.label }} -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia @@ -90,7 +90,7 @@ runs: shell: ${{ steps.choose_shell.outputs.shell }} working-directory: conda env: - PACKAGE_TYPE: inputs.label + PACKAGE_TYPE: ${{ inputs.label }} run: | conda build faiss-gpu-raft --variants '{ "cudatoolkit": "${{ inputs.cuda }}", "c_compiler_version": "${{ inputs.compiler_version }}", "cxx_compiler_version": "${{ inputs.compiler_version }}" }' \ --user pytorch --label ${{ inputs.label }} -c pytorch -c nvidia/label/cuda-${{ inputs.cuda }} -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge From a60a9e56c66ec4370ec6e32597927ede441ad611 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Tue, 21 May 2024 09:07:47 -0700 Subject: [PATCH 173/206] Fix CUDA 11.4.4 builds under CircleCI (#3466) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3466 Flattening Conda include directories breaks CUDA 11.4.4 build on Ubuntu 20 / v5 kernel. This change updates the logic to only flatten includes on Ubuntu 22 / v6 kernel (aka as running on GitHub Actions runners). Reviewed By: algoriddle Differential Revision: D57602154 fbshipit-source-id: 00c14ca7c64644b8b86483ac6b4d40c6d8f12372 --- .github/workflows/build.yml | 1 + conda/faiss-gpu/meta.yaml | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f31ae3b96..39f865bc4a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -121,6 +121,7 @@ jobs: runs-on: 4-core-ubuntu-gpu-t4 env: CUDA_ARCHS: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + FAISS_FLATTEN_CONDA_INCLUDES: "1" steps: - name: Checkout uses: actions/checkout@v4 diff --git a/conda/faiss-gpu/meta.yaml b/conda/faiss-gpu/meta.yaml index db6b4e243f..05f7b59008 100644 --- a/conda/faiss-gpu/meta.yaml +++ b/conda/faiss-gpu/meta.yaml @@ -43,9 +43,7 @@ outputs: - {{ pin_compatible('libfaiss', exact=True) }} script_env: - CUDA_ARCHS - {% if cudatoolkit == '11.4.4' %} - - FAISS_FLATTEN_CONDA_INCLUDES=1 - {% endif %} + - FAISS_FLATTEN_CONDA_INCLUDES requirements: build: - {{ compiler('cxx') }} From c1528b55b70099e79f6fb5a59004ce5761eabe5a Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Tue, 21 May 2024 09:07:47 -0700 Subject: [PATCH 174/206] Enable nightly builds via GitHub Actions (#3467) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3467 1. Cron is scheduled to execute at 1:10am UTC. This is per GitHub's recommendation to avoid hotspots. The docs mention that when GH backend gets overloaded, they can drop scheduled jobs which we want to avoid so we scheduled off hour, off midnight. 2. The plan is to let these nightlies run once and, if successful, then disable them in GitHub UI to perform validation. Also disable if things break and need to be fixed of course. Reviewed By: algoriddle Differential Revision: D57602833 fbshipit-source-id: 4f4d9abbaa5ed3d1edb024ea4dd3f87aa78dd9b5 --- .github/workflows/nightly.yml | 138 ++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000000..9b0d2d0d31 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,138 @@ +name: Nightly +on: + schedule: + - cron: '1 10 * * *' +env: + OMP_NUM_THREADS: '10' + MKL_THREADING_LAYER: GNU +jobs: + linux-x86_64-nightly: + name: Linux x86_64 nightlies + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + linux-x86_64-GPU-CUDA-11-4-4-nightly: + name: Linux x86_64 GPU nightlies (CUDA 11.4.4) + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + cuda: "11.4.4" + compiler_version: "11.2" + linux-x86_64-GPU-RAFT-CUDA11-8-0-nightly: + name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 11.8.0) + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + raft: "ON" + cuda: "11.8.0" + compiler_version: "11.2" + linux-x86_64-GPU-CUDA-12-1-1-nightly: + name: Linux x86_64 GPU nightlies (CUDA 12.1.1) + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + cuda: "12.1.1" + compiler_version: "11.2" + linux-x86_64-GPU-RAFT-CUDA12-1-1-nightly: + name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 12.1.1) + runs-on: 4-core-ubuntu-gpu-t4 + env: + CUDA_ARCHS: "70-real;72-real;75-real;80;86-real" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + raft: "ON" + cuda: "12.1.1" + compiler_version: "11.2" + windows-x86_64-nightly: + name: Windows x86_64 nightlies + runs-on: windows-2019 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + osx-arm64-nightly: + name: OSX arm64 nightlies + runs-on: macos-14 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly + linux-arm64-nightly: + name: Linux arm64 nightlies + runs-on: 2-core-ubuntu-arm + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - uses: ./.github/actions/build_conda + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + with: + label: nightly From 4489773fd43165dc8b053c408ca1033eee9fa2b0 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Tue, 21 May 2024 09:50:41 -0700 Subject: [PATCH 175/206] Add tutorial for FastScan (#3465) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3465 This commit include python version of tutorial for FastScan. It includes all the parameters enabled within PQFastScan. Reviewed By: junjieqi Differential Revision: D57594044 fbshipit-source-id: cb12679b6fc241a654b9545c5bc7bd0517aa1813 --- tutorial/python/7-PQFastScan.py | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tutorial/python/7-PQFastScan.py diff --git a/tutorial/python/7-PQFastScan.py b/tutorial/python/7-PQFastScan.py new file mode 100644 index 0000000000..34d7a34ac1 --- /dev/null +++ b/tutorial/python/7-PQFastScan.py @@ -0,0 +1,35 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import faiss +import numpy as np + +d = 64 # dimension +nb = 100000 # database size +nq = 10000 # nb of queries +np.random.seed(1234) # make reproducible +xb = np.random.random((nb, d)).astype('float32') # 64-dim *nb queries +xb[:, 0] += np.arange(nb) / 1000. +xq = np.random.random((nq, d)).astype('float32') +xq[:, 0] += np.arange(nq) / 1000. + +m = 8 # 8 specifies that the number of sub-vector is 8 +k = 4 # number of dimension in etracted vector +n_bit = 4 # 4 specifies that each sub-vector is encoded as 4 bits +bbs = 32 # build block size ( bbs % 32 == 0 ) for PQ +index = faiss.IndexPQFastScan(d, m, n_bit, faiss.METRIC_L2, bbs) +# construct FastScan Index + +assert not index.is_trained +index.train(xb) # Train vectors data index within mockup database +assert index.is_trained + +index.add(xb) +D, I = index.search(xb[:5], k) # sanity check +print(I) +print(D) +index.nprobe = 10 # make comparable with experiment above +D, I = index.search(xq, k) # search +print(I[-5:]) # neighbors of the 5 last queries From 59e3ee1e30bd6586ba7bde9e3196b7ed676160e7 Mon Sep 17 00:00:00 2001 From: Saarth Deshpande Date: Tue, 21 May 2024 13:02:25 -0700 Subject: [PATCH 176/206] Missed printing 'D' (#3433) Summary: 'I' was printed twice and 'D' (distance vector) was not printed. Fixed. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3433 Reviewed By: fxdawnn Differential Revision: D57451544 Pulled By: junjieqi fbshipit-source-id: fc17b3b467f8b2c4ad7d80b44866456d9146e530 --- tutorial/cpp/1-Flat.cpp | 4 ++-- tutorial/cpp/2-IVFFlat.cpp | 7 ++----- tutorial/cpp/6-HNSW.cpp | 6 ++---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/tutorial/cpp/1-Flat.cpp b/tutorial/cpp/1-Flat.cpp index 819e419573..147fa89bc0 100644 --- a/tutorial/cpp/1-Flat.cpp +++ b/tutorial/cpp/1-Flat.cpp @@ -83,10 +83,10 @@ int main() { printf("\n"); } - printf("I (5 last results)=\n"); + printf("D (5 last results)=\n"); for (int i = nq - 5; i < nq; i++) { for (int j = 0; j < k; j++) - printf("%5zd ", I[i * k + j]); + printf("%5f ", D[i * k + j]); printf("\n"); } diff --git a/tutorial/cpp/2-IVFFlat.cpp b/tutorial/cpp/2-IVFFlat.cpp index febd5be049..86530ae985 100644 --- a/tutorial/cpp/2-IVFFlat.cpp +++ b/tutorial/cpp/2-IVFFlat.cpp @@ -61,13 +61,10 @@ int main() { printf("\n"); } - index.nprobe = 10; - index.search(nq, xq, k, D, I); - - printf("I=\n"); + printf("D=\n"); for (int i = nq - 5; i < nq; i++) { for (int j = 0; j < k; j++) - printf("%5zd ", I[i * k + j]); + printf("%5f ", D[i * k + j]); printf("\n"); } diff --git a/tutorial/cpp/6-HNSW.cpp b/tutorial/cpp/6-HNSW.cpp index 1b3434a433..9bd8cd3faa 100644 --- a/tutorial/cpp/6-HNSW.cpp +++ b/tutorial/cpp/6-HNSW.cpp @@ -55,12 +55,10 @@ int main() { printf("\n"); } - index.search(nq, xq, k, D, I); - - printf("I=\n"); + printf("D=\n"); for (int i = nq - 5; i < nq; i++) { for (int j = 0; j < k; j++) - printf("%5zd ", I[i * k + j]); + printf("%5f ", D[i * k + j]); printf("\n"); } From f38e52c1e2eed726dd435f10757280c9e8fe5b17 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Tue, 21 May 2024 16:42:15 -0700 Subject: [PATCH 177/206] Add tutorial on PQFastScan for cpp (#3468) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3468 This commit includes the tutorial for PQFastScan in the cpp environment. Reviewed By: junjieqi Differential Revision: D57631441 fbshipit-source-id: f5e17eee2a584ebfc9ff63868d741d0da6b3b413 --- tutorial/cpp/7-PQFastScan.cpp | 75 +++++++++++++++++++++++++++++++++++ tutorial/cpp/CMakeLists.txt | 3 ++ 2 files changed, 78 insertions(+) create mode 100644 tutorial/cpp/7-PQFastScan.cpp diff --git a/tutorial/cpp/7-PQFastScan.cpp b/tutorial/cpp/7-PQFastScan.cpp new file mode 100644 index 0000000000..4cdfea052e --- /dev/null +++ b/tutorial/cpp/7-PQFastScan.cpp @@ -0,0 +1,75 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include + +#include + +using idx_t = faiss::idx_t; + +int main() { + int d = 64; // dimension + int nb = 100000; // database size + int nq = 10000; // nb of queries + + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + + float* xb = new float[(int)(d * nb)]; + float* xq = new float[(int)(d * nq)]; + + for (int i = 0; i < nb; i++) { + for (int j = 0; j < d; j++) { + xb[d * i + j] = distrib(rng); + } + xb[d * i] += i / 1000.; + } + + for (int i = 0; i < nq; i++) { + for (int j = 0; j < d; j++) { + xq[d * i + j] = distrib(rng); + } + xq[d * i] += i / 1000.; + } + + int m = 8; + int n_bit = 4; + + faiss::IndexPQFastScan index(d, m, n_bit); + printf("Index is trained? %s\n", index.is_trained ? "true" : "false"); + index.train(nb, xb); + printf("Index is trained? %s\n", index.is_trained ? "true" : "false"); + index.add(nb, xb); + + int k = 4; + + { // search xq + idx_t* I = new idx_t[(int)(k * nq)]; + float* D = new float[(int)(k * nq)]; + + index.search(nq, xq, k, D, I); + + printf("I=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) { + printf("%5zd ", I[i * k + j]); + } + printf("\n"); + } + + delete[] I; + delete[] D; + } + + delete[] xb; + delete[] xq; + + return 0; +} // namespace facebook::detail diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt index abcb253826..894fb4168e 100644 --- a/tutorial/cpp/CMakeLists.txt +++ b/tutorial/cpp/CMakeLists.txt @@ -21,3 +21,6 @@ target_link_libraries(5-Multiple-GPUs PRIVATE faiss) add_executable(6-HNSW EXCLUDE_FROM_ALL 6-HNSW.cpp) target_link_libraries(6-HNSW PRIVATE faiss) + +add_executable(7-PQFastScan EXCLUDE_FROM_ALL 7-PQFastScan.cpp) +target_link_libraries(7-PQFastScan PRIVATE faiss) From 7d7fef0b5869b19e81a24c875808c0fa7bddacf7 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Wed, 22 May 2024 09:30:18 -0700 Subject: [PATCH 178/206] Add FastScan refinement tutorial for python (#3469) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3469 Reviewed By: junjieqi Differential Revision: D57650807 fbshipit-source-id: 5e642a8140455e4a3f1f21afe2f06771462e61f4 --- tutorial/python/8-PQFastScanRefine.py | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tutorial/python/8-PQFastScanRefine.py diff --git a/tutorial/python/8-PQFastScanRefine.py b/tutorial/python/8-PQFastScanRefine.py new file mode 100644 index 0000000000..115a036fa7 --- /dev/null +++ b/tutorial/python/8-PQFastScanRefine.py @@ -0,0 +1,38 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import faiss +import numpy as np + +d = 64 # dimension +nb = 100000 # database size +nq = 10000 # nb of queries +np.random.seed(1234) # make reproducible +xb = np.random.random((nb, d)).astype('float32') # 64-dim *nb queries +xb[:, 0] += np.arange(nb) / 1000. +xq = np.random.random((nq, d)).astype('float32') +xq[:, 0] += np.arange(nq) / 1000. + +m = 8 # 8 specifies that the number of sub-vector is 8 +k = 4 # number of dimension in etracted vector +n_bit = 4 # 4 specifies that each sub-vector is encoded as 4 bits +bbs = 32 # build block size ( bbs % 32 == 0 ) for PQ + +index = faiss.IndexPQFastScan(d, m, n_bit, faiss.METRIC_L2) +index_refine = faiss.IndexRefineFlat(index) +# construct FastScan and run index refinement + +assert not index_refine.is_trained +index_refine.train(xb) # Train vectors data index within mockup database +assert index_refine.is_trained + +index_refine.add(xb) +params = faiss.IndexRefineSearchParameters(k_factor=3) +D, I = index_refine.search(xq[:5], 10, params=params) +print(I) +print(D) +index.nprobe = 10 # make comparable with experiment above +D, I = index.search(xq[:5], k) # search +print(I[-5:]) From f352168c64c922bcccf7d70d8b04e84c10d4a7f8 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 22 May 2024 10:45:41 -0700 Subject: [PATCH 179/206] Fix cron schedule for nightlies via GitHub Actions (#3470) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3470 Hour and minute values are swapped, the goal is to run is at 1:10am UTC. Reviewed By: algoriddle Differential Revision: D57654059 fbshipit-source-id: 23bcb42e5c95f731cd4713ad4691d0f475ed8ad2 --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9b0d2d0d31..fcec4ba3c6 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,7 +1,7 @@ name: Nightly on: schedule: - - cron: '1 10 * * *' + - cron: '10 1 * * *' env: OMP_NUM_THREADS: '10' MKL_THREADING_LAYER: GNU From b39dd4dd57b08426eb3a0ea27ceba3063d823bcb Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Wed, 22 May 2024 11:50:25 -0700 Subject: [PATCH 180/206] Fix CUDA 11.4.4 nightly in GitHub Actions (#3473) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3473 Previous diff (D57602154) fixed the CircleCI version and the PR build version of GHA but not the nightly one. Reviewed By: junjieqi Differential Revision: D57680576 fbshipit-source-id: 39f49c20df824c915f536b1ed3ffc35db2907988 --- .github/workflows/nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index fcec4ba3c6..eabee07744 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -25,6 +25,7 @@ jobs: runs-on: 4-core-ubuntu-gpu-t4 env: CUDA_ARCHS: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" + FAISS_FLATTEN_CONDA_INCLUDES: "1" steps: - name: Checkout uses: actions/checkout@v4 From 414fd1e3b796a045271c545d071fbb8826ca23f0 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Wed, 22 May 2024 13:01:37 -0700 Subject: [PATCH 181/206] Add tutorial for FastScan with refinement for cpp (#3474) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3474 This commit focus on the cpp version of PQfastscan tutorial with index refinement by defining the k factor. Reviewed By: junjieqi Differential Revision: D57680905 fbshipit-source-id: 980c2990172f24ec9a4f870685e706195883408f --- tutorial/cpp/8-PQFastScanRefine.cpp | 84 +++++++++++++++++++++++++++++ tutorial/cpp/CMakeLists.txt | 3 ++ 2 files changed, 87 insertions(+) create mode 100644 tutorial/cpp/8-PQFastScanRefine.cpp diff --git a/tutorial/cpp/8-PQFastScanRefine.cpp b/tutorial/cpp/8-PQFastScanRefine.cpp new file mode 100644 index 0000000000..2435d94d2c --- /dev/null +++ b/tutorial/cpp/8-PQFastScanRefine.cpp @@ -0,0 +1,84 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include + +#include +#include + +using idx_t = faiss::idx_t; + +int main() { + int d = 64; // dimension + int nb = 100000; // database size + int nq = 10000; // nb of queries + + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + + float* xb = new float[(int)(d * nb)]; + float* xq = new float[(int)(d * nq)]; + + for (int i = 0; i < nb; i++) { + for (int j = 0; j < d; j++) { + xb[d * i + j] = distrib(rng); + } + xb[d * i] += i / 1000.; + } + + for (int i = 0; i < nq; i++) { + for (int j = 0; j < d; j++) { + xq[d * i + j] = distrib(rng); + } + xq[d * i] += i / 1000.; + } + + int m = 8; + int n_bit = 4; + + faiss::IndexPQFastScan index(d, m, n_bit); + faiss::IndexRefineFlat index_refine(&index); + // refine index after PQFastScan + + printf("Index is trained? %s\n", + index_refine.is_trained ? "true" : "false"); + index_refine.train(nb, xb); + printf("Index is trained? %s\n", + index_refine.is_trained ? "true" : "false"); + index_refine.add(nb, xb); + + int k = 4; + { // search xq + idx_t* I = new idx_t[(int)(k * nq)]; + float* D = new float[(int)(k * nq)]; + float k_factor = 3; + faiss::IndexRefineSearchParameters* params = + new faiss::IndexRefineSearchParameters(); + params->k_factor = k_factor; + index_refine.search(nq, xq, k, D, I, params); + + printf("I=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) { + printf("%5zd ", I[i * k + j]); + } + printf("\n"); + } + + delete[] I; + delete[] D; + delete params; + } + + delete[] xb; + delete[] xq; + + return 0; +} diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt index 894fb4168e..ad152c499d 100644 --- a/tutorial/cpp/CMakeLists.txt +++ b/tutorial/cpp/CMakeLists.txt @@ -24,3 +24,6 @@ target_link_libraries(6-HNSW PRIVATE faiss) add_executable(7-PQFastScan EXCLUDE_FROM_ALL 7-PQFastScan.cpp) target_link_libraries(7-PQFastScan PRIVATE faiss) + +add_executable(8-PQFastScanRefine EXCLUDE_FROM_ALL 8-PQFastScanRefine.cpp) +target_link_libraries(8-PQFastScanRefine PRIVATE faiss) From 6a94c67a2fa87af1f108fe5fa1d307f44509d729 Mon Sep 17 00:00:00 2001 From: Alexandr Guzhva Date: Thu, 23 May 2024 02:59:15 -0700 Subject: [PATCH 182/206] QT_bf16 for scalar quantizer for bfloat16 (#3444) Summary: mdouze Please let me know if any additional unit tests are needed Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3444 Reviewed By: algoriddle Differential Revision: D57665641 Pulled By: mdouze fbshipit-source-id: 9bec91306a1c31ea4f1f1d726c9d60ac6415fdfc --- benchs/bench_fw/optimize.py | 1 + c_api/IndexScalarQuantizer_c.h | 1 + contrib/factory_tools.py | 3 ++ faiss/CMakeLists.txt | 1 + faiss/IndexScalarQuantizer.cpp | 3 +- faiss/impl/ScalarQuantizer.cpp | 83 ++++++++++++++++++++++++++++++++++ faiss/impl/ScalarQuantizer.h | 1 + faiss/index_factory.cpp | 3 +- faiss/utils/bf16.h | 36 +++++++++++++++ tests/test_index.py | 6 ++- tests/test_standalone_codec.py | 3 ++ 11 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 faiss/utils/bf16.h diff --git a/benchs/bench_fw/optimize.py b/benchs/bench_fw/optimize.py index 473436ea68..a2653b7144 100644 --- a/benchs/bench_fw/optimize.py +++ b/benchs/bench_fw/optimize.py @@ -226,6 +226,7 @@ def optimize_codec( [ (None, "Flat"), (None, "SQfp16"), + (None, "SQbf16"), (None, "SQ8"), ] + [ (f"OPQ{M}_{M * dim}", f"PQ{M}x{b}") diff --git a/c_api/IndexScalarQuantizer_c.h b/c_api/IndexScalarQuantizer_c.h index 2c5e3f2942..87fe6d3415 100644 --- a/c_api/IndexScalarQuantizer_c.h +++ b/c_api/IndexScalarQuantizer_c.h @@ -26,6 +26,7 @@ typedef enum FaissQuantizerType { QT_fp16, QT_8bit_direct, ///< fast indexing of uint8s QT_6bit, ///< 6 bits per component + QT_bf16, } FaissQuantizerType; // forward declaration diff --git a/contrib/factory_tools.py b/contrib/factory_tools.py index 745dc7f7ff..cfad7c7b5c 100644 --- a/contrib/factory_tools.py +++ b/contrib/factory_tools.py @@ -56,6 +56,8 @@ def get_code_size(d, indexkey): return (d * 6 + 7) // 8 elif indexkey == 'SQfp16': return d * 2 + elif indexkey == 'SQbf16': + return d * 2 mo = re.match('PCAR?(\\d+),(.*)$', indexkey) if mo: @@ -140,6 +142,7 @@ def reverse_index_factory(index): faiss.ScalarQuantizer.QT_4bit: "4", faiss.ScalarQuantizer.QT_6bit: "6", faiss.ScalarQuantizer.QT_fp16: "fp16", + faiss.ScalarQuantizer.QT_bf16: "bf16", } return f"SQ{sqtypes[index.sq.qtype]}" diff --git a/faiss/CMakeLists.txt b/faiss/CMakeLists.txt index 33e1849568..1b0860f3fb 100644 --- a/faiss/CMakeLists.txt +++ b/faiss/CMakeLists.txt @@ -183,6 +183,7 @@ set(FAISS_HEADERS invlists/InvertedLists.h invlists/InvertedListsIOHook.h utils/AlignedTable.h + utils/bf16.h utils/Heap.h utils/WorkerThread.h utils/distances.h diff --git a/faiss/IndexScalarQuantizer.cpp b/faiss/IndexScalarQuantizer.cpp index 9203a98932..7ce838db5e 100644 --- a/faiss/IndexScalarQuantizer.cpp +++ b/faiss/IndexScalarQuantizer.cpp @@ -32,7 +32,8 @@ IndexScalarQuantizer::IndexScalarQuantizer( MetricType metric) : IndexFlatCodes(0, d, metric), sq(d, qtype) { is_trained = qtype == ScalarQuantizer::QT_fp16 || - qtype == ScalarQuantizer::QT_8bit_direct; + qtype == ScalarQuantizer::QT_8bit_direct || + qtype == ScalarQuantizer::QT_bf16; code_size = sq.code_size; } diff --git a/faiss/impl/ScalarQuantizer.cpp b/faiss/impl/ScalarQuantizer.cpp index e3b29e621d..7ad50189e4 100644 --- a/faiss/impl/ScalarQuantizer.cpp +++ b/faiss/impl/ScalarQuantizer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -496,6 +497,72 @@ struct QuantizerFP16<8> : QuantizerFP16<1> { }; #endif +/******************************************************************* + * BF16 quantizer + *******************************************************************/ + +template +struct QuantizerBF16 {}; + +template <> +struct QuantizerBF16<1> : ScalarQuantizer::SQuantizer { + const size_t d; + + QuantizerBF16(size_t d, const std::vector& /* unused */) : d(d) {} + + void encode_vector(const float* x, uint8_t* code) const final { + for (size_t i = 0; i < d; i++) { + ((uint16_t*)code)[i] = encode_bf16(x[i]); + } + } + + void decode_vector(const uint8_t* code, float* x) const final { + for (size_t i = 0; i < d; i++) { + x[i] = decode_bf16(((uint16_t*)code)[i]); + } + } + + FAISS_ALWAYS_INLINE float reconstruct_component(const uint8_t* code, int i) + const { + return decode_bf16(((uint16_t*)code)[i]); + } +}; + +#ifdef __AVX2__ + +template <> +struct QuantizerBF16<8> : QuantizerBF16<1> { + QuantizerBF16(size_t d, const std::vector& trained) + : QuantizerBF16<1>(d, trained) {} + + FAISS_ALWAYS_INLINE __m256 + reconstruct_8_components(const uint8_t* code, int i) const { + __m128i code_128i = _mm_loadu_si128((const __m128i*)(code + 2 * i)); + __m256i code_256i = _mm256_cvtepu16_epi32(code_128i); + code_256i = _mm256_slli_epi32(code_256i, 16); + return _mm256_castsi256_ps(code_256i); + } +}; + +#endif + +#ifdef __aarch64__ + +template <> +struct QuantizerBF16<8> : QuantizerBF16<1> { + QuantizerBF16(size_t d, const std::vector& trained) + : QuantizerBF16<1>(d, trained) {} + + FAISS_ALWAYS_INLINE float32x4x2_t + reconstruct_8_components(const uint8_t* code, int i) const { + uint16x4x2_t codei = vld1_u16_x2((const uint16_t*)(code + 2 * i)); + return {vreinterpretq_f32_u32(vshlq_n_u32(vmovl_u16(codei.val[0]), 16)), + vreinterpretq_f32_u32( + vshlq_n_u32(vmovl_u16(codei.val[1]), 16))}; + } +}; +#endif + /******************************************************************* * 8bit_direct quantizer *******************************************************************/ @@ -589,6 +656,8 @@ ScalarQuantizer::SQuantizer* select_quantizer_1( d, trained); case ScalarQuantizer::QT_fp16: return new QuantizerFP16(d, trained); + case ScalarQuantizer::QT_bf16: + return new QuantizerBF16(d, trained); case ScalarQuantizer::QT_8bit_direct: return new Quantizer8bitDirect(d, trained); } @@ -1378,6 +1447,10 @@ SQDistanceComputer* select_distance_computer( return new DCTemplate, Sim, SIMDWIDTH>( d, trained); + case ScalarQuantizer::QT_bf16: + return new DCTemplate, Sim, SIMDWIDTH>( + d, trained); + case ScalarQuantizer::QT_8bit_direct: if (d % 16 == 0) { return new DistanceComputerByte(d, trained); @@ -1426,6 +1499,10 @@ void ScalarQuantizer::set_derived_sizes() { code_size = d * 2; bits = 16; break; + case QT_bf16: + code_size = d * 2; + bits = 16; + break; } } @@ -1462,6 +1539,7 @@ void ScalarQuantizer::train(size_t n, const float* x) { break; case QT_fp16: case QT_8bit_direct: + case QT_bf16: // no training necessary break; } @@ -1791,6 +1869,11 @@ InvertedListScanner* sel1_InvertedListScanner( QuantizerFP16, Similarity, SIMDWIDTH>>(sq, quantizer, store_pairs, sel, r); + case ScalarQuantizer::QT_bf16: + return sel2_InvertedListScanner, + Similarity, + SIMDWIDTH>>(sq, quantizer, store_pairs, sel, r); case ScalarQuantizer::QT_8bit_direct: if (sq->d % 16 == 0) { return sel2_InvertedListScanner< diff --git a/faiss/impl/ScalarQuantizer.h b/faiss/impl/ScalarQuantizer.h index 550a979092..49fd42cc31 100644 --- a/faiss/impl/ScalarQuantizer.h +++ b/faiss/impl/ScalarQuantizer.h @@ -32,6 +32,7 @@ struct ScalarQuantizer : Quantizer { QT_fp16, QT_8bit_direct, ///< fast indexing of uint8s QT_6bit, ///< 6 bits per component + QT_bf16, }; QuantizerType qtype = QT_8bit; diff --git a/faiss/index_factory.cpp b/faiss/index_factory.cpp index 0d61b73ecd..d88fe7b393 100644 --- a/faiss/index_factory.cpp +++ b/faiss/index_factory.cpp @@ -140,8 +140,9 @@ std::map sq_types = { {"SQ4", ScalarQuantizer::QT_4bit}, {"SQ6", ScalarQuantizer::QT_6bit}, {"SQfp16", ScalarQuantizer::QT_fp16}, + {"SQbf16", ScalarQuantizer::QT_bf16}, }; -const std::string sq_pattern = "(SQ4|SQ8|SQ6|SQfp16)"; +const std::string sq_pattern = "(SQ4|SQ8|SQ6|SQfp16|SQbf16)"; std::map aq_search_type = { {"_Nfloat", AdditiveQuantizer::ST_norm_float}, diff --git a/faiss/utils/bf16.h b/faiss/utils/bf16.h new file mode 100644 index 0000000000..ff0fbe898b --- /dev/null +++ b/faiss/utils/bf16.h @@ -0,0 +1,36 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace faiss { + +namespace { + +union fp32_bits { + uint32_t as_u32; + float as_f32; +}; + +} // namespace + +inline uint16_t encode_bf16(const float f) { + // Round off + fp32_bits fp; + fp.as_f32 = f; + return static_cast((fp.as_u32 + 0x8000) >> 16); +} + +inline float decode_bf16(const uint16_t v) { + fp32_bits fp; + fp.as_u32 = (uint32_t(v) << 16); + return fp.as_f32; +} + +} // namespace faiss diff --git a/tests/test_index.py b/tests/test_index.py index b9f3dbd46b..43db906e47 100644 --- a/tests/test_index.py +++ b/tests/test_index.py @@ -327,7 +327,7 @@ def test_4variants_ivf(self): D, I = index.search(xq, 10) nok['flat'] = (I[:, 0] == I_ref[:, 0]).sum() - for qname in "QT_4bit QT_4bit_uniform QT_8bit QT_8bit_uniform QT_fp16".split(): + for qname in "QT_4bit QT_4bit_uniform QT_8bit QT_8bit_uniform QT_fp16 QT_bf16".split(): qtype = getattr(faiss.ScalarQuantizer, qname) index = faiss.IndexIVFScalarQuantizer(quantizer, d, ncent, qtype, faiss.METRIC_L2) @@ -349,6 +349,7 @@ def test_4variants_ivf(self): self.assertGreaterEqual(nok['QT_8bit'], nok['QT_8bit_uniform']) self.assertGreaterEqual(nok['QT_4bit'], nok['QT_4bit_uniform']) self.assertGreaterEqual(nok['QT_fp16'], nok['QT_8bit']) + self.assertGreaterEqual(nok['QT_bf16'], nok['QT_8bit']) def test_4variants(self): d = 32 @@ -364,7 +365,7 @@ def test_4variants(self): nok = {} - for qname in "QT_4bit QT_4bit_uniform QT_8bit QT_8bit_uniform QT_fp16".split(): + for qname in "QT_4bit QT_4bit_uniform QT_8bit QT_8bit_uniform QT_fp16 QT_bf16".split(): qtype = getattr(faiss.ScalarQuantizer, qname) index = faiss.IndexScalarQuantizer(d, qtype, faiss.METRIC_L2) index.train(xt) @@ -377,6 +378,7 @@ def test_4variants(self): self.assertGreaterEqual(nok['QT_8bit'], nok['QT_8bit_uniform']) self.assertGreaterEqual(nok['QT_4bit'], nok['QT_4bit_uniform']) self.assertGreaterEqual(nok['QT_fp16'], nok['QT_8bit']) + self.assertGreaterEqual(nok['QT_bf16'], nq * 0.9) class TestRangeSearch(unittest.TestCase): diff --git a/tests/test_standalone_codec.py b/tests/test_standalone_codec.py index 2176a12e99..391b88b9dd 100644 --- a/tests/test_standalone_codec.py +++ b/tests/test_standalone_codec.py @@ -173,6 +173,9 @@ def test_SQ2(self): def test_SQ3(self): self.compare_accuracy('SQ8', 'SQfp16') + def test_SQ4(self): + self.compare_accuracy('SQ8', 'SQbf16') + def test_PQ(self): self.compare_accuracy('PQ6x8np', 'PQ8x8np') From ee7ce21acd00ee9d4f84091647de376a80074df2 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 23 May 2024 06:42:48 -0700 Subject: [PATCH 183/206] Add display names to all PR build jobs on GitHub Actions (#3475) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3475 Migration to GitHub Reviewed By: algoriddle Differential Revision: D57707064 fbshipit-source-id: 17f0a97028007f3664faa5b6b2c269f50bcdf39e --- .github/workflows/build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 39f865bc4a..b16dee9f2b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,6 +12,7 @@ env: MKL_THREADING_LAYER: GNU jobs: format: + name: Format runs-on: ubuntu-latest steps: - name: Checkout @@ -37,12 +38,14 @@ jobs: exit 1 fi linux-x86_64-cmake: + name: Linux x86_64 (cmake) runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - uses: ./.github/actions/build_cmake linux-x86_64-AVX2-cmake: + name: Linux x86_64 AVX2 (cmake) runs-on: ubuntu-latest steps: - name: Checkout @@ -51,6 +54,7 @@ jobs: with: opt_level: avx2 linux-x86_64-AVX512-cmake: + name: Linux x86_64 AVX512 (cmake) if: false # TODO: enable when GitHub Actions adds AVX-512 hosts runs-on: ubuntu-latest steps: @@ -60,6 +64,7 @@ jobs: with: opt_level: avx512 linux-x86_64-GPU-cmake: + name: Linux x86_64 GPU (cmake) needs: linux-x86_64-AVX2-cmake runs-on: 4-core-ubuntu-gpu-t4 steps: @@ -69,6 +74,7 @@ jobs: with: gpu: ON linux-x86_64-GPU-w-RAFT-cmake: + name: Linux x86_64 GPU w/ RAFT (cmake) runs-on: 4-core-ubuntu-gpu-t4 steps: - name: Checkout @@ -78,6 +84,7 @@ jobs: gpu: ON raft: ON linux-x86_64-conda: + name: Linux x86_64 (conda) runs-on: ubuntu-latest steps: - name: Checkout @@ -87,6 +94,7 @@ jobs: fetch-tags: true - uses: ./.github/actions/build_conda windows-x86_64-conda: + name: Windows x86_64 (conda) runs-on: windows-2019 steps: - name: Checkout @@ -96,6 +104,7 @@ jobs: fetch-tags: true - uses: ./.github/actions/build_conda linux-arm64-conda: + name: Linux arm64 (conda) runs-on: 2-core-ubuntu-arm steps: - name: Checkout @@ -105,6 +114,7 @@ jobs: fetch-tags: true - uses: ./.github/actions/build_conda linux-x86_64-packages: + name: Linux x86_64 packages if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest steps: @@ -117,6 +127,7 @@ jobs: with: label: main linux-x86_64-GPU-packages-CUDA-11-4-4: + name: Linux x86_64 GPU packages (CUDA 11.4.4) if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 4-core-ubuntu-gpu-t4 env: @@ -134,6 +145,7 @@ jobs: cuda: "11.4.4" compiler_version: "11.2" linux-x86_64-GPU-RAFT-packages-CUDA11-8-0: + name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.8.0) if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 4-core-ubuntu-gpu-t4 env: @@ -151,6 +163,7 @@ jobs: cuda: "11.8.0" compiler_version: "11.2" linux-x86_64-GPU-packages-CUDA-12-1-1: + name: Linux x86_64 GPU packages (CUDA 12.1.1) if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 4-core-ubuntu-gpu-t4 env: @@ -167,6 +180,7 @@ jobs: cuda: "12.1.1" compiler_version: "11.2" linux-x86_64-GPU-RAFT-packages-CUDA12-1-1: + name: Linux x86_64 GPU w/ RAFT packages (CUDA 12.1.1) if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 4-core-ubuntu-gpu-t4 env: @@ -184,6 +198,7 @@ jobs: cuda: "12.1.1" compiler_version: "11.2" windows-x86_64-packages: + name: Windows x86_64 packages if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: windows-2019 steps: @@ -196,6 +211,7 @@ jobs: with: label: main osx-arm64-packages: + name: OSX arm64 packages if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: macos-14 steps: @@ -208,6 +224,7 @@ jobs: with: label: main linux-arm64-packages: + name: Linux arm64 packages if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: 2-core-ubuntu-arm steps: From 93bc9b6470f3576f798e9a25e7879debb9676fe3 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 23 May 2024 06:42:48 -0700 Subject: [PATCH 184/206] Gate all PR builds behind linux-x86_64-cmake in GitHub Actions (#3476) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3476 The long tail will still be the RAFT build but we can save on cost if the build has errors by incurring ~10m penalty added by waiting for the basic cmake build to complete. Both GPU and RAFT builds will start together so this will take less time overall to complete. Reviewed By: algoriddle Differential Revision: D57707298 fbshipit-source-id: 3589842e9bda9ebca9b25e089e6177fe96b6a0f5 --- .github/workflows/build.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b16dee9f2b..bd415dfce8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,6 +46,7 @@ jobs: - uses: ./.github/actions/build_cmake linux-x86_64-AVX2-cmake: name: Linux x86_64 AVX2 (cmake) + needs: linux-x86_64-cmake runs-on: ubuntu-latest steps: - name: Checkout @@ -56,6 +57,7 @@ jobs: linux-x86_64-AVX512-cmake: name: Linux x86_64 AVX512 (cmake) if: false # TODO: enable when GitHub Actions adds AVX-512 hosts + needs: linux-x86_64-cmake runs-on: ubuntu-latest steps: - name: Checkout @@ -65,7 +67,7 @@ jobs: opt_level: avx512 linux-x86_64-GPU-cmake: name: Linux x86_64 GPU (cmake) - needs: linux-x86_64-AVX2-cmake + needs: linux-x86_64-cmake runs-on: 4-core-ubuntu-gpu-t4 steps: - name: Checkout @@ -75,6 +77,7 @@ jobs: gpu: ON linux-x86_64-GPU-w-RAFT-cmake: name: Linux x86_64 GPU w/ RAFT (cmake) + needs: linux-x86_64-cmake runs-on: 4-core-ubuntu-gpu-t4 steps: - name: Checkout @@ -85,6 +88,7 @@ jobs: raft: ON linux-x86_64-conda: name: Linux x86_64 (conda) + needs: linux-x86_64-cmake runs-on: ubuntu-latest steps: - name: Checkout @@ -95,6 +99,7 @@ jobs: - uses: ./.github/actions/build_conda windows-x86_64-conda: name: Windows x86_64 (conda) + needs: linux-x86_64-cmake runs-on: windows-2019 steps: - name: Checkout @@ -105,6 +110,7 @@ jobs: - uses: ./.github/actions/build_conda linux-arm64-conda: name: Linux arm64 (conda) + needs: linux-x86_64-cmake runs-on: 2-core-ubuntu-arm steps: - name: Checkout From eec4cba0253da49eee08d42d7181964c7d5ebe41 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 23 May 2024 06:42:48 -0700 Subject: [PATCH 185/206] Disable CircleCI builds (#3477) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3477 AVX-512 must remain on CircleCI until GitHub provides runners with AVX-512 support (ETA: Q1 2025). Reviewed By: algoriddle Differential Revision: D57707621 fbshipit-source-id: e8a0885f8363cf8f20854cccca3ec0adc946362b --- .circleci/config.yml | 433 ++----------------------------------------- 1 file changed, 12 insertions(+), 421 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7e8bd8170a..0330939153 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,190 +5,8 @@ executors: docker: - image: continuumio/miniconda3 resource_class: large - linux-x86_64-gpu: - environment: - CONDA_ARCH: Linux-x86_64 - machine: - image: linux-cuda-12:default - resource_class: gpu.nvidia.medium - linux-arm64-cpu: - environment: - CONDA_ARCH: Linux-aarch64 - machine: - image: ubuntu-2204:current - resource_class: arm.medium - macosx-arm64-cpu: - environment: - CONDA_ARCH: MacOSX-arm64 - macos: - xcode: 14.2.0 # minimum supported for M1 - resource_class: macos.m1.large.gen1 - windows-x86_64-cpu: - machine: - image: windows-server-2019-vs2019:2023.04.1 - shell: bash.exe - resource_class: windows.medium jobs: - format: - docker: - - image: ubuntu:22.04 - steps: - - checkout - - run: - name: Install clang-format - command: | - apt-get update -y - apt-get install -y wget - apt install -y lsb-release wget software-properties-common gnupg - wget https://apt.llvm.org/llvm.sh - chmod u+x llvm.sh - ./llvm.sh 18 - apt-get install -y git-core clang-format-18 - - run: - name: Verify clang-format - command: | - git ls-files | grep -E '\.(cpp|h|cu|cuh)$' | xargs clang-format-18 -i - if git diff --quiet; then - echo "Formatting OK!" - else - echo "Formatting not OK!" - echo "------------------" - git --no-pager diff --color - exit 1 - fi - - build_conda: - parameters: - label: - type: string - default: "" - cuda: - type: string - default: "" - raft: - type: string - default: "" - cuda_archs: - type: string - default: "" - compiler_version: - type: string - default: "" - exec: - type: executor - executor: << parameters.exec >> - environment: - OMP_NUM_THREADS: 10 - PACKAGE_TYPE: <> - CUDA_ARCHS: <> - steps: - - checkout - - run: - name: Install conda - command: | - if [ -n "${CONDA_ARCH}" ] - then - curl https://repo.anaconda.com/miniconda/Miniconda3-latest-${CONDA_ARCH}.sh --output miniconda.sh - bash miniconda.sh -b -p $HOME/miniconda - ~/miniconda/bin/conda init - fi - - run: - name: Install conda build tools - command: | - # conda config --set solver libmamba - # conda config --set verbosity 3 - conda update -y -q conda - conda install -y -q conda-build - - when: - condition: << parameters.label >> - steps: - - run: - name: Enable anaconda uploads - command: | - conda install -y -q anaconda-client - conda config --set anaconda_upload yes - - when: - condition: - and: - - not: << parameters.label >> - - not: << parameters.cuda >> - steps: - - run: - name: Conda build (CPU) - no_output_timeout: 30m - command: | - cd conda - conda build faiss --python 3.11 -c pytorch - - when: - condition: - and: - - << parameters.label >> - - not: << parameters.cuda >> - steps: - - run: - name: Conda build (CPU) w/ anaconda upload - no_output_timeout: 30m - command: | - cd conda - conda build faiss --user pytorch --label <> -c pytorch - - when: - condition: - and: - - not: << parameters.label >> - - << parameters.cuda >> - - not: << parameters.raft >> - steps: - - run: - name: Conda build (GPU) - no_output_timeout: 60m - command: | - cd conda - conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia/label/cuda-<> -c nvidia - - when: - condition: - and: - - << parameters.label >> - - << parameters.cuda >> - - not: << parameters.raft >> - steps: - - run: - name: Conda build (GPU) w/ anaconda upload - no_output_timeout: 60m - command: | - cd conda - conda build faiss-gpu --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia - - when: - condition: - and: - - not: << parameters.label >> - - << parameters.cuda >> - - << parameters.raft >> - steps: - - run: - name: Conda build (GPU w/ RAFT) - no_output_timeout: 60m - command: | - cd conda - conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge - - when: - condition: - and: - - << parameters.label >> - - << parameters.cuda >> - - << parameters.raft >> - steps: - - run: - name: Conda build (GPU w/ RAFT) w/ anaconda upload - no_output_timeout: 60m - command: | - cd conda - conda build faiss-gpu-raft --variants '{ "cudatoolkit": "<>", "c_compiler_version": "<>", "cxx_compiler_version": "<>" }' \ - --user pytorch --label <> -c pytorch -c nvidia/label/cuda-<> -c nvidia -c rapidsai -c rapidsai-nightly -c conda-forge - build_cmake: parameters: exec: @@ -196,12 +14,6 @@ jobs: opt_level: type: string default: generic - gpu: - type: string - default: "OFF" - raft: - type: string - default: "OFF" executor: << parameters.exec >> environment: OMP_NUM_THREADS: 10 @@ -222,32 +34,10 @@ jobs: command: | conda config --set solver libmamba conda update -y -q conda - - when: - condition: - equal: [ "OFF", << parameters.raft >> ] - steps: - - run: - name: Install env using main channel - command: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64 - - when: - condition: - equal: [ "ON", << parameters.raft >> ] - steps: - - run: - name: Install env using conda-forge channel - command: | - conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64=2.28 libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge - - when: - condition: - and: - - equal: [ "ON", << parameters.gpu >> ] - - equal: [ "OFF", << parameters.raft >> ] - steps: - - run: - name: Install CUDA - command: | - conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" + - run: + name: Install env using main channel + command: | + conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest gxx_linux-64=11.2 sysroot_linux-64 - run: name: Build all targets no_output_timeout: 30m @@ -257,8 +47,8 @@ jobs: cmake -B build \ -DBUILD_TESTING=ON \ -DBUILD_SHARED_LIBS=ON \ - -DFAISS_ENABLE_GPU=<< parameters.gpu >> \ - -DFAISS_ENABLE_RAFT=<< parameters.raft >> \ + -DFAISS_ENABLE_GPU=OFF \ + -DFAISS_ENABLE_RAFT=OFF \ -DFAISS_OPT_LEVEL=<< parameters.opt_level >> \ -DFAISS_ENABLE_C_API=ON \ -DPYTHON_EXECUTABLE=$(which python) \ @@ -277,38 +67,12 @@ jobs: command: | cd build/faiss/python python setup.py install - - when: - condition: - equal: [ "OFF", << parameters.gpu >> ] - steps: - - run: - name: Python tests (CPU only) - command: | - conda install -y -q pytorch -c pytorch - pytest --junitxml=test-results/pytest/results.xml tests/test_*.py - pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py - - when: - condition: - equal: [ "ON", << parameters.gpu >> ] - steps: - - run: - name: Python tests (CPU + GPU) - command: | - conda install -y -q pytorch pytorch-cuda=11.8 -c pytorch -c nvidia/label/cuda-11.8.0 - pytest --junitxml=test-results/pytest/results.xml tests/test_*.py - pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py - cp tests/common_faiss_tests.py faiss/gpu/test - pytest --junitxml=test-results/pytest/results-gpu.xml faiss/gpu/test/test_*.py - pytest --junitxml=test-results/pytest/results-gpu-torch.xml faiss/gpu/test/torch_*.py - - when: - condition: - equal: [ "avx2", << parameters.opt_level >> ] - steps: - - run: - name: Test avx2 loading - command: | - FAISS_DISABLE_CPU_FEATURES=AVX2 LD_DEBUG=libs python -c "import faiss" 2>&1 | grep faiss.so - LD_DEBUG=libs python -c "import faiss" 2>&1 | grep faiss_avx2.so + - run: + name: Python tests (CPU only) + command: | + conda install -y -q pytorch -c pytorch + pytest --junitxml=test-results/pytest/results.xml tests/test_*.py + pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py - store_test_results: path: test-results @@ -316,180 +80,7 @@ workflows: version: 2 build: jobs: - - format: - name: Format - - build_cmake: - name: Linux x86_64 (cmake) - exec: linux-x86_64-cpu - - build_cmake: - name: Linux x86_64 AVX2 (cmake) - exec: linux-x86_64-cpu - opt_level: "avx2" - build_cmake: name: Linux x86_64 AVX512 (cmake) exec: linux-x86_64-cpu opt_level: "avx512" - - build_cmake: - name: Linux x86_64 GPU (cmake) - exec: linux-x86_64-gpu - gpu: "ON" - requires: - - Linux x86_64 AVX2 (cmake) - - build_cmake: - name: Linux x86_64 GPU w/ RAFT (cmake) - exec: linux-x86_64-gpu - gpu: "ON" - raft: "ON" - requires: - - Linux x86_64 GPU (cmake) - - build_conda: - name: Linux x86_64 (conda) - exec: linux-x86_64-cpu - - build_conda: - name: Windows x86_64 (conda) - exec: windows-x86_64-cpu - - build_conda: - name: Linux arm64 (conda) - exec: linux-arm64-cpu - - build_conda: - name: Linux x86_64 packages - exec: linux-x86_64-cpu - label: main - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Linux x86_64 GPU packages (CUDA 11.4.4) - exec: linux-x86_64-gpu - label: main - cuda: "11.4.4" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Linux x86_64 GPU w/ RAFT packages (CUDA 11.8.0) - exec: linux-x86_64-gpu - label: main - raft: "ON" - cuda: "11.8.0" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Linux x86_64 GPU packages (CUDA 12.1.1) - exec: linux-x86_64-gpu - label: main - cuda: "12.1.1" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Linux x86_64 GPU w/ RAFT packages (CUDA 12.1.1) - exec: linux-x86_64-gpu - label: main - raft: "ON" - cuda: "12.1.1" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Windows x86_64 packages - exec: windows-x86_64-cpu - label: main - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: OSX arm64 packages - exec: macosx-arm64-cpu - label: main - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build_conda: - name: Linux arm64 packages - exec: linux-arm64-cpu - label: main - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - nightly: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - main - jobs: - - build_conda: - name: Linux x86_64 nightlies - exec: linux-x86_64-cpu - label: nightly - - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 11.4.4) - exec: linux-x86_64-gpu - label: nightly - cuda: "11.4.4" - cuda_archs: "60-real;61-real;62-real;70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - - build_conda: - name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 11.8.0) - exec: linux-x86_64-gpu - label: nightly - raft: "ON" - cuda: "11.8.0" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - - build_conda: - name: Linux x86_64 GPU nightlies (CUDA 12.1.1) - exec: linux-x86_64-gpu - label: nightly - cuda: "12.1.1" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - - build_conda: - name: Linux x86_64 GPU w/ RAFT nightlies (CUDA 12.1.1) - exec: linux-x86_64-gpu - label: nightly - raft: "ON" - cuda: "12.1.1" - cuda_archs: "70-real;72-real;75-real;80;86-real" - compiler_version: "11.2" - - build_conda: - name: Windows x86_64 nightlies - exec: windows-x86_64-cpu - label: nightly - - build_conda: - name: OSX arm64 nightlies - exec: macosx-arm64-cpu - label: nightly - - build_conda: - name: Linux arm64 nightlies - exec: linux-arm64-cpu - label: nightly From 729a66f0044f1a893bcb47c0ab429b4f0b52600d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Thu, 23 May 2024 07:47:33 -0700 Subject: [PATCH 186/206] Remove extra semi colon from deprecated/libmccpp/ThreadSafeClientPool.h (#3479) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3479 `-Wextra-semi` or `-Wextra-semi-stmt` If the code compiles, this is safe to land. Reviewed By: palmje Differential Revision: D57632759 fbshipit-source-id: 48bc23e87b3f518182085124c4c8e68ddbb3ca8f --- tests/test_common_ivf_empty_index.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_common_ivf_empty_index.cpp b/tests/test_common_ivf_empty_index.cpp index 1a99b77141..a3e33031bd 100644 --- a/tests/test_common_ivf_empty_index.cpp +++ b/tests/test_common_ivf_empty_index.cpp @@ -23,7 +23,7 @@ namespace { int d = 64; -}; // namespace +} // namespace std::vector get_random_vectors(size_t n, int seed) { std::vector x(n * d); From eb284811e093f8ddd18b0379a1be8fafc0cb7847 Mon Sep 17 00:00:00 2001 From: Alexandr Guzhva Date: Thu, 23 May 2024 09:19:24 -0700 Subject: [PATCH 187/206] Remove duplicate NegativeDistanceComputer instances (#3450) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3450 Reviewed By: mdouze Differential Revision: D57708412 Pulled By: junjieqi fbshipit-source-id: 9540b7e60d8b2b39e0ca92423d2a305fab2a17e6 --- faiss/IndexHNSW.cpp | 46 ----------------------------------- faiss/IndexNNDescent.cpp | 29 ---------------------- faiss/impl/DistanceComputer.h | 46 +++++++++++++++++++++++++++++++++++ faiss/impl/NSG.cpp | 29 ---------------------- 4 files changed, 46 insertions(+), 104 deletions(-) diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index 3325c8c0e1..0686917211 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -68,52 +68,6 @@ HNSWStats hnsw_stats; namespace { -/* Wrap the distance computer into one that negates the - distances. This makes supporting INNER_PRODUCE search easier */ - -struct NegativeDistanceComputer : DistanceComputer { - /// owned by this - DistanceComputer* basedis; - - explicit NegativeDistanceComputer(DistanceComputer* basedis) - : basedis(basedis) {} - - void set_query(const float* x) override { - basedis->set_query(x); - } - - /// compute distance of vector i to current query - float operator()(idx_t i) override { - return -(*basedis)(i); - } - - void distances_batch_4( - const idx_t idx0, - const idx_t idx1, - const idx_t idx2, - const idx_t idx3, - float& dis0, - float& dis1, - float& dis2, - float& dis3) override { - basedis->distances_batch_4( - idx0, idx1, idx2, idx3, dis0, dis1, dis2, dis3); - dis0 = -dis0; - dis1 = -dis1; - dis2 = -dis2; - dis3 = -dis3; - } - - /// compute distance between two stored vectors - float symmetric_dis(idx_t i, idx_t j) override { - return -basedis->symmetric_dis(i, j); - } - - virtual ~NegativeDistanceComputer() { - delete basedis; - } -}; - DistanceComputer* storage_distance_computer(const Index* storage) { if (is_similarity_metric(storage->metric_type)) { return new NegativeDistanceComputer(storage->get_distance_computer()); diff --git a/faiss/IndexNNDescent.cpp b/faiss/IndexNNDescent.cpp index 27bd6e33ee..382e9c41c6 100644 --- a/faiss/IndexNNDescent.cpp +++ b/faiss/IndexNNDescent.cpp @@ -58,35 +58,6 @@ using storage_idx_t = NNDescent::storage_idx_t; namespace { -/* Wrap the distance computer into one that negates the - distances. This makes supporting INNER_PRODUCE search easier */ - -struct NegativeDistanceComputer : DistanceComputer { - /// owned by this - DistanceComputer* basedis; - - explicit NegativeDistanceComputer(DistanceComputer* basedis) - : basedis(basedis) {} - - void set_query(const float* x) override { - basedis->set_query(x); - } - - /// compute distance of vector i to current query - float operator()(idx_t i) override { - return -(*basedis)(i); - } - - /// compute distance between two stored vectors - float symmetric_dis(idx_t i, idx_t j) override { - return -basedis->symmetric_dis(i, j); - } - - ~NegativeDistanceComputer() override { - delete basedis; - } -}; - DistanceComputer* storage_distance_computer(const Index* storage) { if (is_similarity_metric(storage->metric_type)) { return new NegativeDistanceComputer(storage->get_distance_computer()); diff --git a/faiss/impl/DistanceComputer.h b/faiss/impl/DistanceComputer.h index dc46d113fb..5ac3a702c9 100644 --- a/faiss/impl/DistanceComputer.h +++ b/faiss/impl/DistanceComputer.h @@ -59,6 +59,52 @@ struct DistanceComputer { virtual ~DistanceComputer() {} }; +/* Wrap the distance computer into one that negates the + distances. This makes supporting INNER_PRODUCE search easier */ + +struct NegativeDistanceComputer : DistanceComputer { + /// owned by this + DistanceComputer* basedis; + + explicit NegativeDistanceComputer(DistanceComputer* basedis) + : basedis(basedis) {} + + void set_query(const float* x) override { + basedis->set_query(x); + } + + /// compute distance of vector i to current query + float operator()(idx_t i) override { + return -(*basedis)(i); + } + + void distances_batch_4( + const idx_t idx0, + const idx_t idx1, + const idx_t idx2, + const idx_t idx3, + float& dis0, + float& dis1, + float& dis2, + float& dis3) override { + basedis->distances_batch_4( + idx0, idx1, idx2, idx3, dis0, dis1, dis2, dis3); + dis0 = -dis0; + dis1 = -dis1; + dis2 = -dis2; + dis3 = -dis3; + } + + /// compute distance between two stored vectors + float symmetric_dis(idx_t i, idx_t j) override { + return -basedis->symmetric_dis(i, j); + } + + virtual ~NegativeDistanceComputer() { + delete basedis; + } +}; + /************************************************************* * Specialized version of the DistanceComputer when we know that codes are * laid out in a flat index. diff --git a/faiss/impl/NSG.cpp b/faiss/impl/NSG.cpp index 1f30b576b9..c974943343 100644 --- a/faiss/impl/NSG.cpp +++ b/faiss/impl/NSG.cpp @@ -25,35 +25,6 @@ namespace { // It needs to be smaller than 0 constexpr int EMPTY_ID = -1; -/* Wrap the distance computer into one that negates the - distances. This makes supporting INNER_PRODUCE search easier */ - -struct NegativeDistanceComputer : DistanceComputer { - /// owned by this - DistanceComputer* basedis; - - explicit NegativeDistanceComputer(DistanceComputer* basedis) - : basedis(basedis) {} - - void set_query(const float* x) override { - basedis->set_query(x); - } - - /// compute distance of vector i to current query - float operator()(idx_t i) override { - return -(*basedis)(i); - } - - /// compute distance between two stored vectors - float symmetric_dis(idx_t i, idx_t j) override { - return -basedis->symmetric_dis(i, j); - } - - ~NegativeDistanceComputer() override { - delete basedis; - } -}; - } // namespace DistanceComputer* storage_distance_computer(const Index* storage) { From 6580156e9647ea8a6cdef1b49e6dd431bf3d0096 Mon Sep 17 00:00:00 2001 From: Tarang Jain Date: Thu, 23 May 2024 15:33:23 -0700 Subject: [PATCH 188/206] Delete Raft Handle (#3435) Summary: Small Raft related modification to StandardGpuResources: if the stream for a particular device is modified by a user, delete the Raft handle for that device. On any subsequent call to `getRaftHandle(device)`, a new raft handle with the updated stream will be created. Closes https://github.com/facebookresearch/faiss/issues/3424 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3435 Reviewed By: ramilbakhshyiev Differential Revision: D57640976 Pulled By: junjieqi fbshipit-source-id: 41e2898a39250b7e52e920b71e819fc21ca9fc85 --- faiss/gpu/StandardGpuResources.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/faiss/gpu/StandardGpuResources.cpp b/faiss/gpu/StandardGpuResources.cpp index 004f80a27e..78336b4994 100644 --- a/faiss/gpu/StandardGpuResources.cpp +++ b/faiss/gpu/StandardGpuResources.cpp @@ -257,6 +257,14 @@ void StandardGpuResourcesImpl::setDefaultStream( if (prevStream != stream) { streamWait({stream}, {prevStream}); } +#if defined USE_NVIDIA_RAFT + // delete the raft handle for this device, which will be initialized + // with the updated stream during any subsequent calls to getRaftHandle + auto it2 = raftHandles_.find(device); + if (it2 != raftHandles_.end()) { + raftHandles_.erase(it2); + } +#endif } userDefaultStreams_[device] = stream; @@ -275,6 +283,14 @@ void StandardGpuResourcesImpl::revertDefaultStream(int device) { streamWait({newStream}, {prevStream}); } +#if defined USE_NVIDIA_RAFT + // delete the raft handle for this device, which will be initialized + // with the updated stream during any subsequent calls to getRaftHandle + auto it2 = raftHandles_.find(device); + if (it2 != raftHandles_.end()) { + raftHandles_.erase(it2); + } +#endif } userDefaultStreams_.erase(device); From 6e423cc649168e61ec7614e838da9fbce21c0b15 Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Mon, 27 May 2024 11:55:06 -0700 Subject: [PATCH 189/206] Add python tutorial on different indexs refinement and respect accuracy measurement (#3480) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3480 This tutorial summarize the methods to construct different indexs for PQFastScan refinement. It shows how the choice can impact on accuracy. Reviewed By: junjieqi Differential Revision: D57799598 fbshipit-source-id: a75c52c60a5217366f3361676da8f03f0c4a9feb --- tutorial/python/9-RefineComparison.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tutorial/python/9-RefineComparison.py diff --git a/tutorial/python/9-RefineComparison.py b/tutorial/python/9-RefineComparison.py new file mode 100644 index 0000000000..6fa69f33d9 --- /dev/null +++ b/tutorial/python/9-RefineComparison.py @@ -0,0 +1,42 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import faiss + +from faiss.contrib.evaluation import knn_intersection_measure +from faiss.contrib import datasets + +# 64-dim vectors, 50000 vectors in the training, 100000 in database, +# 10000 in queries, dtype ('float32') +ds = datasets.SyntheticDataset(64, 50000, 100000, 10000) +d = 64 # dimension + +# Constructing the refine PQ index with SQfp16 with index factory +index_fp16 = faiss.index_factory(d, 'PQ32x4fs,Refine(SQfp16)') +index_fp16.train(ds.get_train()) +index_fp16.add(ds.get_database()) + +# Constructing the refine PQ index with SQ8 +index_sq8 = faiss.index_factory(d, 'PQ32x4fs,Refine(SQ8)') +index_sq8.train(ds.get_train()) +index_sq8.add(ds.get_database()) + +# Parameterization on k factor while doing search for index refinement +k_factor = 3.0 +params = faiss.IndexRefineSearchParameters(k_factor=k_factor) + +# Perform index search using different index refinement +D_fp16, I_fp16 = index_fp16.search(ds.get_queries(), 100, params=params) +D_sq8, I_sq8 = index_sq8.search(ds.get_queries(), 100, params=params) + +# Calculating knn intersection measure for different index types on refinement +KIM_fp16 = knn_intersection_measure(I_fp16, ds.get_groundtruth()) +KIM_sq8 = knn_intersection_measure(I_sq8, ds.get_groundtruth()) + +# KNN intersection measure accuracy shows that choosing SQ8 impacts accuracy +assert (KIM_fp16 > KIM_sq8) + +print(I_sq8[:5]) +print(I_fp16[:5]) From db6ff2e0953e07aaba0780637f38467652695c3b Mon Sep 17 00:00:00 2001 From: Jim Borden Date: Mon, 27 May 2024 17:44:09 -0700 Subject: [PATCH 190/206] Workaround for missing intrinsic on gcc < 9 (#3481) Summary: Rebased branch for https://github.com/facebookresearch/faiss/issues/3420 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3481 Reviewed By: mdouze Differential Revision: D57830230 Pulled By: junjieqi fbshipit-source-id: a93fb3cc53f11245faec891a9590b5e849dbf3b9 --- faiss/impl/code_distance/code_distance-avx2.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/faiss/impl/code_distance/code_distance-avx2.h b/faiss/impl/code_distance/code_distance-avx2.h index 0aa1535b28..d37b022441 100644 --- a/faiss/impl/code_distance/code_distance-avx2.h +++ b/faiss/impl/code_distance/code_distance-avx2.h @@ -16,6 +16,11 @@ #include #include +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78782 +#if defined(__GNUC__) && __GNUC__ < 9 +#define _mm_loadu_si64(x) (_mm_loadl_epi64((__m128i_u*)x)) +#endif + namespace { inline float horizontal_sum(const __m128 v) { From 6e7d9e040f9be9734277c3f27b2cb364a67f442d Mon Sep 17 00:00:00 2001 From: simshi Date: Tue, 28 May 2024 11:47:04 -0700 Subject: [PATCH 191/206] fix algorithm of spreading vectors over shards (#3374) Summary: simple math: | **input n** | **input nshards** | shard_size | idx | i0 | ni | | -- |-- |-- |-- |-- |-- | | 19 | 6 | 4 | 5 | 20 | **-1** | | 1000 | 37 | 28 | 36 | 1008 | -8 | | 1000 | 64 | 16 | 63 | 1008 | -8 | root cause: integer cause precision loss, `idx * shard_size` overflows, because `(n + nshards - 1) / nshards` is roundup my solution: each shard takes at least `base_shard_size = n / nshards`, then `remain = n % nshards`, we know `0 <= remain < nshards`, next, assign those remain vectors to first `remain` shards, i.e. first `remain` shards take one more vector each. ```c++ auto i0 = idx * base_shard_size; if (i0 < remain) { // if current idx is one of the first `remain` shards i0 += idx; } else { i0 += remain; } ``` simplify above code: `i0 = idx * base_shard_size + std::min(size_t(idx), n % nshards);` Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3374 Reviewed By: fxdawnn Differential Revision: D57867910 Pulled By: junjieqi fbshipit-source-id: 7e72ea5cd197af4f3446fb7a3fd34ad08901dbb2 --- faiss/gpu/GpuIcmEncoder.cu | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/faiss/gpu/GpuIcmEncoder.cu b/faiss/gpu/GpuIcmEncoder.cu index 434fae9e36..8bd60f91b8 100644 --- a/faiss/gpu/GpuIcmEncoder.cu +++ b/faiss/gpu/GpuIcmEncoder.cu @@ -82,7 +82,7 @@ void GpuIcmEncoder::encode( size_t n, size_t ils_iters) const { size_t nshards = shards->size(); - size_t shard_size = (n + nshards - 1) / nshards; + size_t base_shard_size = n / nshards; auto codebooks = lsq->codebooks.data(); auto M = lsq->M; @@ -94,8 +94,14 @@ void GpuIcmEncoder::encode( // split input data auto fn = [=](int idx, IcmEncoderImpl* encoder) { - size_t i0 = idx * shard_size; - size_t ni = std::min(shard_size, n - i0); + size_t i0 = idx * base_shard_size + std::min(size_t(idx), n % nshards); + size_t ni = base_shard_size; + if (ni < n % nshards) { + ++ni; + } + if (ni <= 0) { // only if n < nshards + return; + } auto xi = x + i0 * d; auto ci = codes + i0 * M; std::mt19937 geni(idx + seed); // different seed for each shard From 0beecb4c85d0b0c49483f7f0a3100b28ba44b793 Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Thu, 30 May 2024 09:27:55 -0700 Subject: [PATCH 192/206] sys.big_endian to sys.byteorder (#3422) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3422 Found vec_io failing when running some benchmarking. There is no such field named big_endian in sys. So, reverting it to original field byteorder Reviewed By: algoriddle Differential Revision: D56718607 fbshipit-source-id: 553f1d2d6bc967581142a92282e534f3f164e8f9 --- contrib/vecs_io.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/vecs_io.py b/contrib/vecs_io.py index 5d18c0b162..9ef9e0ab64 100644 --- a/contrib/vecs_io.py +++ b/contrib/vecs_io.py @@ -14,7 +14,7 @@ def ivecs_read(fname): a = np.fromfile(fname, dtype='int32') - if sys.big_endian: + if sys.byteorder == 'big': a.byteswap(inplace=True) d = a[0] return a.reshape(-1, d + 1)[:, 1:].copy() @@ -25,7 +25,7 @@ def fvecs_read(fname): def ivecs_mmap(fname): - assert not sys.big_endian + assert sys.byteorder != 'big' a = np.memmap(fname, dtype='int32', mode='r') d = a[0] return a.reshape(-1, d + 1)[:, 1:] @@ -37,7 +37,7 @@ def fvecs_mmap(fname): def bvecs_mmap(fname): x = np.memmap(fname, dtype='uint8', mode='r') - if sys.big_endian: + if sys.byteorder == 'big': da = x[:4][::-1].copy() d = da.view('int32')[0] else: @@ -50,7 +50,7 @@ def ivecs_write(fname, m): m1 = np.empty((n, d + 1), dtype='int32') m1[:, 0] = d m1[:, 1:] = m - if sys.big_endian: + if sys.byteorder == 'big': m1.byteswap(inplace=True) m1.tofile(fname) From 22304340d22edae38ddb9e13874688ae18eb121d Mon Sep 17 00:00:00 2001 From: Kumar Saurabh Arora Date: Fri, 31 May 2024 14:30:39 -0700 Subject: [PATCH 193/206] Adding buck target for experiment bench_fw_ivf (#3423) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3423 Adding small fixes to run experiments from fbcode. 1. Added buck target 2. Full import path of faiss bench_fw modules 3. new dataset path to run tests locally as we can't use an existing directory ./data in fbcode. Reviewed By: algoriddle, junjieqi Differential Revision: D57235092 fbshipit-source-id: f78a23199e619b640a19ca37f8b52ff0abdd8298 --- benchs/bench_fw_ivf.py | 13 +++++++++---- contrib/datasets.py | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/benchs/bench_fw_ivf.py b/benchs/bench_fw_ivf.py index 8c84743e27..e9e144c569 100644 --- a/benchs/bench_fw_ivf.py +++ b/benchs/bench_fw_ivf.py @@ -3,16 +3,20 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -import logging import argparse +import logging import os -from bench_fw.benchmark import Benchmark -from bench_fw.benchmark_io import BenchmarkIO -from bench_fw.descriptors import DatasetDescriptor, IndexDescriptor +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, + IndexDescriptor, +) logging.basicConfig(level=logging.INFO) + def sift1M(bio): benchmark = Benchmark( num_threads=32, @@ -37,6 +41,7 @@ def sift1M(bio): benchmark.set_io(bio) benchmark.benchmark(result_file="result.json", local=False, train=True, reconstruct=False, knn=True, range=False) + def bigann(bio): for scale in [1, 2, 5, 10, 20, 50]: benchmark = Benchmark( diff --git a/contrib/datasets.py b/contrib/datasets.py index f37a2fb6e4..281f16e2fa 100644 --- a/contrib/datasets.py +++ b/contrib/datasets.py @@ -6,6 +6,8 @@ import os import numpy as np import faiss +import getpass + from .vecs_io import fvecs_read, ivecs_read, bvecs_mmap, fvecs_mmap from .exhaustive_search import knn @@ -115,10 +117,12 @@ def get_groundtruth(self, k=100): # that directory is ############################################################################ +username = getpass.getuser() for dataset_basedir in ( '/datasets01/simsearch/041218/', - '/mnt/vol/gfsai-flash3-east/ai-group/datasets/simsearch/'): + '/mnt/vol/gfsai-flash3-east/ai-group/datasets/simsearch/', + f'/home/{username}/simsearch/data/'): if os.path.exists(dataset_basedir): break else: From bf73e38d10ae6818d7e5d7250a55bb0c9944a9ef Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Fri, 31 May 2024 14:48:13 -0700 Subject: [PATCH 194/206] add skip_storage flag to HNSW (#3487) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3487 Sometimes it is not useful to serialize the storage index along with a HNSW index. This diff adds a flag that supports skipping the storage of the index. Searchign and adding to the index is not possible until a storage index is added back in. Reviewed By: junjieqi Differential Revision: D57911060 fbshipit-source-id: 5a4ceee4a8f53f6f746df59af3942b813a99c14f --- faiss/IndexHNSW.cpp | 5 ++--- faiss/impl/index_read.cpp | 10 ++++++---- faiss/impl/index_write.cpp | 25 ++++++++++++++++--------- faiss/index_io.h | 11 ++++++----- faiss/python/__init__.py | 4 ++-- tests/test_graph_based.py | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index 0686917211..94798c1b4a 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -251,7 +249,8 @@ void hnsw_search( const SearchParameters* params_in) { FAISS_THROW_IF_NOT_MSG( index->storage, - "Please use IndexHNSWFlat (or variants) instead of IndexHNSW directly"); + "No storage index, please use IndexHNSWFlat (or variants) " + "instead of IndexHNSW directly"); const SearchParametersHNSW* params = nullptr; const HNSW& hnsw = index->hnsw; diff --git a/faiss/impl/index_read.cpp b/faiss/impl/index_read.cpp index 8d80329bf9..ce4b1e76b1 100644 --- a/faiss/impl/index_read.cpp +++ b/faiss/impl/index_read.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -531,7 +529,11 @@ Index* read_index(IOReader* f, int io_flags) { Index* idx = nullptr; uint32_t h; READ1(h); - if (h == fourcc("IxFI") || h == fourcc("IxF2") || h == fourcc("IxFl")) { + if (h == fourcc("null")) { + // denotes a missing index, useful for some cases + return nullptr; + } else if ( + h == fourcc("IxFI") || h == fourcc("IxF2") || h == fourcc("IxFl")) { IndexFlat* idxf; if (h == fourcc("IxFI")) { idxf = new IndexFlatIP(); @@ -961,7 +963,7 @@ Index* read_index(IOReader* f, int io_flags) { read_index_header(idxhnsw, f); read_HNSW(&idxhnsw->hnsw, f); idxhnsw->storage = read_index(f, io_flags); - idxhnsw->own_fields = true; + idxhnsw->own_fields = idxhnsw->storage != nullptr; if (h == fourcc("IHNp") && !(io_flags & IO_FLAG_PQ_SKIP_SDC_TABLE)) { dynamic_cast(idxhnsw->storage)->pq.compute_sdc_table(); } diff --git a/faiss/impl/index_write.cpp b/faiss/impl/index_write.cpp index b2808d7170..01e5ae7257 100644 --- a/faiss/impl/index_write.cpp +++ b/faiss/impl/index_write.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - #include #include @@ -390,8 +388,12 @@ static void write_ivf_header(const IndexIVF* ivf, IOWriter* f) { write_direct_map(&ivf->direct_map, f); } -void write_index(const Index* idx, IOWriter* f) { - if (const IndexFlat* idxf = dynamic_cast(idx)) { +void write_index(const Index* idx, IOWriter* f, int io_flags) { + if (idx == nullptr) { + // eg. for a storage component of HNSW that is set to nullptr + uint32_t h = fourcc("null"); + WRITE1(h); + } else if (const IndexFlat* idxf = dynamic_cast(idx)) { uint32_t h = fourcc(idxf->metric_type == METRIC_INNER_PRODUCT ? "IxFI" : idxf->metric_type == METRIC_L2 ? "IxF2" @@ -765,7 +767,12 @@ void write_index(const Index* idx, IOWriter* f) { WRITE1(h); write_index_header(idxhnsw, f); write_HNSW(&idxhnsw->hnsw, f); - write_index(idxhnsw->storage, f); + if (io_flags & IO_FLAG_SKIP_STORAGE) { + uint32_t n4 = fourcc("null"); + WRITE1(n4); + } else { + write_index(idxhnsw->storage, f); + } } else if (const IndexNSG* idxnsg = dynamic_cast(idx)) { uint32_t h = dynamic_cast(idx) ? fourcc("INSf") : dynamic_cast(idx) ? fourcc("INSp") @@ -841,14 +848,14 @@ void write_index(const Index* idx, IOWriter* f) { } } -void write_index(const Index* idx, FILE* f) { +void write_index(const Index* idx, FILE* f, int io_flags) { FileIOWriter writer(f); - write_index(idx, &writer); + write_index(idx, &writer, io_flags); } -void write_index(const Index* idx, const char* fname) { +void write_index(const Index* idx, const char* fname, int io_flags) { FileIOWriter writer(fname); - write_index(idx, &writer); + write_index(idx, &writer, io_flags); } void write_VectorTransform(const VectorTransform* vt, const char* fname) { diff --git a/faiss/index_io.h b/faiss/index_io.h index f73cd073b7..3e77d0227c 100644 --- a/faiss/index_io.h +++ b/faiss/index_io.h @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// -*- c++ -*- - // I/O code for indexes #ifndef FAISS_INDEX_IO_H @@ -35,9 +33,12 @@ struct IOReader; struct IOWriter; struct InvertedLists; -void write_index(const Index* idx, const char* fname); -void write_index(const Index* idx, FILE* f); -void write_index(const Index* idx, IOWriter* writer); +/// skip the storage for graph-based indexes +const int IO_FLAG_SKIP_STORAGE = 1; + +void write_index(const Index* idx, const char* fname, int io_flags = 0); +void write_index(const Index* idx, FILE* f, int io_flags = 0); +void write_index(const Index* idx, IOWriter* writer, int io_flags = 0); void write_index_binary(const IndexBinary* idx, const char* fname); void write_index_binary(const IndexBinary* idx, FILE* f); diff --git a/faiss/python/__init__.py b/faiss/python/__init__.py index 0562d1dd89..ce4b42c618 100644 --- a/faiss/python/__init__.py +++ b/faiss/python/__init__.py @@ -292,10 +292,10 @@ def range_search_with_parameters(index, x, radius, params=None, output_stats=Fal ########################################### -def serialize_index(index): +def serialize_index(index, io_flags=0): """ convert an index to a numpy uint8 array """ writer = VectorIOWriter() - write_index(index, writer) + write_index(index, writer, io_flags) return vector_to_array(writer.data) diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py index d5ddbeec37..95925d7ae9 100644 --- a/tests/test_graph_based.py +++ b/tests/test_graph_based.py @@ -133,6 +133,42 @@ def test_ndis_stats(self): Dhnsw, Ihnsw = index.search(self.xq, 1) self.assertGreater(stats.ndis, len(self.xq) * index.hnsw.efSearch) + def test_io_no_storage(self): + d = self.xq.shape[1] + index = faiss.IndexHNSWFlat(d, 16) + index.add(self.xb) + + Dref, Iref = index.search(self.xq, 5) + + # test writing without storage + index2 = faiss.deserialize_index( + faiss.serialize_index(index, faiss.IO_FLAG_SKIP_STORAGE) + ) + self.assertEquals(index2.storage, None) + self.assertRaises( + RuntimeError, + index2.search, self.xb, 1) + + # make sure we can store an index with empty storage + index4 = faiss.deserialize_index( + faiss.serialize_index(index2)) + + # add storage afterwards + index.storage = faiss.clone_index(index.storage) + index.own_fields = True + + Dnew, Inew = index.search(self.xq, 5) + np.testing.assert_array_equal(Dnew, Dref) + np.testing.assert_array_equal(Inew, Iref) + + if False: + # test reading without storage + # not implemented because it is hard to skip over an index + index3 = faiss.deserialize_index( + faiss.serialize_index(index), faiss.IO_FLAG_SKIP_STORAGE + ) + self.assertEquals(index3.storage, None) + class TestNSG(unittest.TestCase): From a900cfa9f1d2842b4504b0eedc646414b377616b Mon Sep 17 00:00:00 2001 From: Xiao Fu Date: Tue, 4 Jun 2024 19:44:27 -0700 Subject: [PATCH 195/206] Add cpp tutorial for index factory refine index construction (#3494) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3494 This tasks focus on the refine index construction tutorial with different index refinement on fp16/sq8 quantization. The python version was added a while ago. Reviewed By: junjieqi Differential Revision: D58161983 fbshipit-source-id: 1c598fe612b5dee3952c5f7398e6802e117f141d --- tutorial/cpp/9-RefineComparison.cpp | 104 ++++++++++++++++++++++++++++ tutorial/cpp/CMakeLists.txt | 3 + 2 files changed, 107 insertions(+) create mode 100644 tutorial/cpp/9-RefineComparison.cpp diff --git a/tutorial/cpp/9-RefineComparison.cpp b/tutorial/cpp/9-RefineComparison.cpp new file mode 100644 index 0000000000..d7fbc90aec --- /dev/null +++ b/tutorial/cpp/9-RefineComparison.cpp @@ -0,0 +1,104 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include + +#include +#include +#include +using idx_t = faiss::idx_t; + +int main() { + int d = 64; // dimension + int nb = 100000; // database size + int nq = 10000; // nb of queries + + std::mt19937 rng; + std::uniform_real_distribution<> distrib; + + float* xb = new float[(int)(d * nb)]; + float* xq = new float[(int)(d * nq)]; + + for (int i = 0; i < nb; i++) { + for (int j = 0; j < d; j++) { + xb[d * i + j] = distrib(rng); + } + xb[d * i] += i / 1000.; + } + + for (int i = 0; i < nq; i++) { + for (int j = 0; j < d; j++) { + xq[d * i + j] = distrib(rng); + } + xq[d * i] += i / 1000.; + } + + // Constructing the refine PQ index with SQfp16 with index factory + faiss::Index* index_fp16; + index_fp16 = faiss::index_factory( + d, "PQ32x4fs,Refine(SQfp16)", faiss::METRIC_L2); + index_fp16->train(nb, xb); + index_fp16->add(nb, xb); + + // Constructing the refine PQ index with SQ8 + faiss::Index* index_sq8; + index_sq8 = + faiss::index_factory(d, "PQ32x4fs,Refine(SQ8)", faiss::METRIC_L2); + index_sq8->train(nb, xb); + index_sq8->add(nb, xb); + + int k = 10; + { // search xq + idx_t* I_fp16 = new idx_t[(int)(k * nq)]; + float* D_fp16 = new float[(int)(k * nq)]; + idx_t* I_sq8 = new idx_t[(int)(k * nq)]; + float* D_sq8 = new float[(int)(k * nq)]; + + // Parameterization on k factor while doing search for index refinement + float k_factor = 3; + faiss::IndexRefineSearchParameters* params = + new faiss::IndexRefineSearchParameters(); + params->k_factor = k_factor; + + // Perform index search using different index refinement + index_fp16->search(nq, xq, k, D_fp16, I_fp16, params); + index_sq8->search(nq, xq, k, D_sq8, I_sq8, params); + + printf("I_fp16=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) { + printf("%5zd ", I_fp16[i * k + j]); + } + printf("\n"); + } + + printf("I_sq8=\n"); + for (int i = nq - 5; i < nq; i++) { + for (int j = 0; j < k; j++) { + printf("%5zd ", I_sq8[i * k + j]); + } + printf("\n"); + } + + delete[] I_fp16; + delete[] D_fp16; + delete[] I_sq8; + delete[] D_sq8; + delete params; + + delete index_fp16; + delete index_sq8; + } + + delete[] xb; + delete[] xq; + + return 0; +} diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt index ad152c499d..f964b3dda9 100644 --- a/tutorial/cpp/CMakeLists.txt +++ b/tutorial/cpp/CMakeLists.txt @@ -27,3 +27,6 @@ target_link_libraries(7-PQFastScan PRIVATE faiss) add_executable(8-PQFastScanRefine EXCLUDE_FROM_ALL 8-PQFastScanRefine.cpp) target_link_libraries(8-PQFastScanRefine PRIVATE faiss) + +add_executable(9-RefineComparison EXCLUDE_FROM_ALL 9-RefineComparison.cpp) +target_link_libraries(9-RefineComparison PRIVATE faiss) From ec67ac159476d96c16912699584b0809074b5f0c Mon Sep 17 00:00:00 2001 From: Abhiram Vadlapatla Date: Tue, 4 Jun 2024 21:59:57 -0700 Subject: [PATCH 196/206] Update .gitignore (#3492) Summary: Adding build folder to gitignore, so that they don't show up in the commit tree while building from source Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3492 Reviewed By: junjieqi Differential Revision: D58171359 Pulled By: asadoughi fbshipit-source-id: b0efed348769328a3bdbcc13098dcb84cadb6c4f --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index caab1304c8..d6df432fa5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.dylib *.pyc *~ +/build/ /config.* /aclocal.m4 /autom4te.cache/ From df0dea6c6d8951056763dc03528b3973c6ba26e2 Mon Sep 17 00:00:00 2001 From: divyegala Date: Tue, 11 Jun 2024 08:14:48 -0700 Subject: [PATCH 197/206] Interop between CAGRA and HNSW (#3252) Summary: Depends on https://github.com/facebookresearch/faiss/pull/3084 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3252 Reviewed By: junjieqi Differential Revision: D57971948 Pulled By: mdouze fbshipit-source-id: 4371f4d136eeceb59568593f98a6ae9163a768ba --- CMakeLists.txt | 2 + faiss/IndexHNSW.cpp | 124 +++++++- faiss/IndexHNSW.h | 44 ++- faiss/gpu/CMakeLists.txt | 8 +- faiss/gpu/GpuCloner.cpp | 29 +- faiss/gpu/GpuIndexCagra.cu | 274 ++++++++++++++++ faiss/gpu/GpuIndexCagra.h | 282 +++++++++++++++++ faiss/gpu/impl/RaftCagra.cu | 371 ++++++++++++++++++++++ faiss/gpu/impl/RaftCagra.cuh | 132 ++++++++ faiss/gpu/test/CMakeLists.txt | 4 +- faiss/gpu/test/TestGpuIndexCagra.cu | 474 ++++++++++++++++++++++++++++ faiss/gpu/test/test_cagra.py | 71 +++++ faiss/impl/HNSW.cpp | 72 ++++- faiss/impl/HNSW.h | 12 +- faiss/impl/index_read.cpp | 10 +- faiss/impl/index_write.cpp | 7 + faiss/python/CMakeLists.txt | 5 + faiss/python/swigfaiss.swig | 7 + 18 files changed, 1895 insertions(+), 33 deletions(-) create mode 100644 faiss/gpu/GpuIndexCagra.cu create mode 100644 faiss/gpu/GpuIndexCagra.h create mode 100644 faiss/gpu/impl/RaftCagra.cu create mode 100644 faiss/gpu/impl/RaftCagra.cuh create mode 100644 faiss/gpu/test/TestGpuIndexCagra.cu create mode 100644 faiss/gpu/test/test_cagra.py diff --git a/CMakeLists.txt b/CMakeLists.txt index cedee9c456..1a468fb247 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,8 @@ project(faiss LANGUAGES ${FAISS_LANGUAGES}) include(GNUInstallDirs) +set(CMAKE_INSTALL_PREFIX "$ENV{CONDA_PREFIX}") + set(CMAKE_CXX_STANDARD 17) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index 94798c1b4a..c04642d218 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -15,12 +15,16 @@ #include #include +#include +#include #include +#include #include #include #include #include +#include "impl/HNSW.h" #include #include @@ -144,7 +148,9 @@ void hnsw_add_vertices( int i1 = n; - for (int pt_level = hist.size() - 1; pt_level >= 0; pt_level--) { + for (int pt_level = hist.size() - 1; + pt_level >= !index_hnsw.init_level0; + pt_level--) { int i0 = i1 - hist[pt_level]; if (verbose) { @@ -180,7 +186,13 @@ void hnsw_add_vertices( continue; } - hnsw.add_with_locks(*dis, pt_level, pt_id, locks, vt); + hnsw.add_with_locks( + *dis, + pt_level, + pt_id, + locks, + vt, + index_hnsw.keep_max_size_level0 && (pt_level == 0)); if (prev_display >= 0 && i - i0 > prev_display + 10000) { prev_display = i - i0; @@ -200,7 +212,11 @@ void hnsw_add_vertices( } i1 = i0; } - FAISS_ASSERT(i1 == 0); + if (index_hnsw.init_level0) { + FAISS_ASSERT(i1 == 0); + } else { + FAISS_ASSERT((i1 - hist[0]) == 0); + } } if (verbose) { printf("Done in %.3f ms\n", getmillisecs() - t0); @@ -404,10 +420,18 @@ void IndexHNSW::search_level_0( float* distances, idx_t* labels, int nprobe, - int search_type) const { + int search_type, + const SearchParameters* params_in) const { FAISS_THROW_IF_NOT(k > 0); FAISS_THROW_IF_NOT(nprobe > 0); + const SearchParametersHNSW* params = nullptr; + + if (params_in) { + params = dynamic_cast(params_in); + FAISS_THROW_IF_NOT_MSG(params, "params type invalid"); + } + storage_idx_t ntotal = hnsw.levels.size(); using RH = HeapBlockResultHandler; @@ -434,13 +458,21 @@ void IndexHNSW::search_level_0( nearest_d + i * nprobe, search_type, search_stats, - vt); + vt, + params); res.end(); vt.advance(); } #pragma omp critical { hnsw_stats.combine(search_stats); } } + if (is_similarity_metric(this->metric_type)) { +// we need to revert the negated distances +#pragma omp parallel for + for (size_t i = 0; i < k * n; i++) { + distances[i] = -distances[i]; + } + } } void IndexHNSW::init_level_0_from_knngraph( @@ -863,4 +895,86 @@ void IndexHNSW2Level::flip_to_ivf() { delete storage2l; } +/************************************************************** + * IndexHNSWCagra implementation + **************************************************************/ + +IndexHNSWCagra::IndexHNSWCagra() { + is_trained = true; +} + +IndexHNSWCagra::IndexHNSWCagra(int d, int M, MetricType metric) + : IndexHNSW( + (metric == METRIC_L2) + ? static_cast(new IndexFlatL2(d)) + : static_cast(new IndexFlatIP(d)), + M) { + FAISS_THROW_IF_NOT_MSG( + ((metric == METRIC_L2) || (metric == METRIC_INNER_PRODUCT)), + "unsupported metric type for IndexHNSWCagra"); + own_fields = true; + is_trained = true; + init_level0 = true; + keep_max_size_level0 = true; +} + +void IndexHNSWCagra::add(idx_t n, const float* x) { + FAISS_THROW_IF_NOT_MSG( + !base_level_only, + "Cannot add vectors when base_level_only is set to True"); + + IndexHNSW::add(n, x); +} + +void IndexHNSWCagra::search( + idx_t n, + const float* x, + idx_t k, + float* distances, + idx_t* labels, + const SearchParameters* params) const { + if (!base_level_only) { + IndexHNSW::search(n, x, k, distances, labels, params); + } else { + std::vector nearest(n); + std::vector nearest_d(n); + +#pragma omp for + for (idx_t i = 0; i < n; i++) { + std::unique_ptr dis( + storage_distance_computer(this->storage)); + dis->set_query(x + i * d); + nearest[i] = -1; + nearest_d[i] = std::numeric_limits::max(); + + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution distrib(0, this->ntotal); + + for (idx_t j = 0; j < num_base_level_search_entrypoints; j++) { + auto idx = distrib(gen); + auto distance = (*dis)(idx); + if (distance < nearest_d[i]) { + nearest[i] = idx; + nearest_d[i] = distance; + } + } + FAISS_THROW_IF_NOT_MSG( + nearest[i] >= 0, "Could not find a valid entrypoint."); + } + + search_level_0( + n, + x, + k, + nearest.data(), + nearest_d.data(), + distances, + labels, + 1, // n_probes + 1, // search_type + params); + } +} + } // namespace faiss diff --git a/faiss/IndexHNSW.h b/faiss/IndexHNSW.h index e0b65fca9d..71807c6537 100644 --- a/faiss/IndexHNSW.h +++ b/faiss/IndexHNSW.h @@ -34,6 +34,18 @@ struct IndexHNSW : Index { bool own_fields = false; Index* storage = nullptr; + // When set to false, level 0 in the knn graph is not initialized. + // This option is used by GpuIndexCagra::copyTo(IndexHNSWCagra*) + // as level 0 knn graph is copied over from the index built by + // GpuIndexCagra. + bool init_level0 = true; + + // When set to true, all neighbors in level 0 are filled up + // to the maximum size allowed (2 * M). This option is used by + // IndexHHNSWCagra to create a full base layer graph that is + // used when GpuIndexCagra::copyFrom(IndexHNSWCagra*) is invoked. + bool keep_max_size_level0 = false; + explicit IndexHNSW(int d = 0, int M = 32, MetricType metric = METRIC_L2); explicit IndexHNSW(Index* storage, int M = 32); @@ -81,7 +93,8 @@ struct IndexHNSW : Index { float* distances, idx_t* labels, int nprobe = 1, - int search_type = 1) const; + int search_type = 1, + const SearchParameters* params = nullptr) const; /// alternative graph building void init_level_0_from_knngraph(int k, const float* D, const idx_t* I); @@ -148,4 +161,33 @@ struct IndexHNSW2Level : IndexHNSW { const SearchParameters* params = nullptr) const override; }; +struct IndexHNSWCagra : IndexHNSW { + IndexHNSWCagra(); + IndexHNSWCagra(int d, int M, MetricType metric = METRIC_L2); + + /// When set to true, the index is immutable. + /// This option is used to copy the knn graph from GpuIndexCagra + /// to the base level of IndexHNSWCagra without adding upper levels. + /// Doing so enables to search the HNSW index, but removes the + /// ability to add vectors. + bool base_level_only = false; + + /// When `base_level_only` is set to `True`, the search function + /// searches only the base level knn graph of the HNSW index. + /// This parameter selects the entry point by randomly selecting + /// some points and using the best one. + int num_base_level_search_entrypoints = 32; + + void add(idx_t n, const float* x) override; + + /// entry point for search + void search( + idx_t n, + const float* x, + idx_t k, + float* distances, + idx_t* labels, + const SearchParameters* params = nullptr) const override; +}; + } // namespace faiss diff --git a/faiss/gpu/CMakeLists.txt b/faiss/gpu/CMakeLists.txt index 126cbe5044..d20f3b7f8e 100644 --- a/faiss/gpu/CMakeLists.txt +++ b/faiss/gpu/CMakeLists.txt @@ -238,11 +238,15 @@ generate_ivf_interleaved_code() if(FAISS_ENABLE_RAFT) list(APPEND FAISS_GPU_HEADERS + GpuIndexCagra.h + impl/RaftCagra.cuh impl/RaftFlatIndex.cuh impl/RaftIVFFlat.cuh impl/RaftIVFPQ.cuh utils/RaftUtils.h) list(APPEND FAISS_GPU_SRC + GpuIndexCagra.cu + impl/RaftCagra.cu impl/RaftFlatIndex.cu impl/RaftIVFFlat.cu impl/RaftIVFPQ.cu @@ -316,5 +320,5 @@ __nv_relfatbin : { *(__nv_relfatbin) } target_link_options(faiss_gpu PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") find_package(CUDAToolkit REQUIRED) -target_link_libraries(faiss_gpu PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass>) -target_compile_options(faiss_gpu PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr>) +target_link_libraries(faiss_gpu PRIVATE CUDA::cudart CUDA::cublas $<$:raft::raft> $<$:raft::compiled> $<$:nvidia::cutlass::cutlass> $<$:OpenMP::OpenMP_CXX>) +target_compile_options(faiss_gpu PRIVATE $<$:-Xfatbin=-compress-all --expt-extended-lambda --expt-relaxed-constexpr $<$:-Xcompiler=${OpenMP_CXX_FLAGS}>>) diff --git a/faiss/gpu/GpuCloner.cpp b/faiss/gpu/GpuCloner.cpp index 8f895ac9c7..b6d55a47aa 100644 --- a/faiss/gpu/GpuCloner.cpp +++ b/faiss/gpu/GpuCloner.cpp @@ -14,6 +14,9 @@ #include #include +#if defined USE_NVIDIA_RAFT +#include +#endif #include #include #include @@ -24,6 +27,9 @@ #include #include #include +#if defined USE_NVIDIA_RAFT +#include +#endif #include #include #include @@ -85,7 +91,15 @@ Index* ToCPUCloner::clone_Index(const Index* index) { // objective is to make a single component out of them // (inverse op of ToGpuClonerMultiple) - } else if (auto ish = dynamic_cast(index)) { + } +#if defined USE_NVIDIA_RAFT + else if (auto icg = dynamic_cast(index)) { + IndexHNSWCagra* res = new IndexHNSWCagra(); + icg->copyTo(res); + return res; + } +#endif + else if (auto ish = dynamic_cast(index)) { int nshard = ish->count(); FAISS_ASSERT(nshard > 0); Index* res = clone_Index(ish->at(0)); @@ -215,7 +229,18 @@ Index* ToGpuCloner::clone_Index(const Index* index) { } return res; - } else { + } +#if defined USE_NVIDIA_RAFT + else if (auto icg = dynamic_cast(index)) { + GpuIndexCagraConfig config; + config.device = device; + GpuIndexCagra* res = + new GpuIndexCagra(provider, icg->d, icg->metric_type, config); + res->copyFrom(icg); + return res; + } +#endif + else { // use CPU cloner for IDMap and PreTransform auto index_idmap = dynamic_cast(index); auto index_pt = dynamic_cast(index); diff --git a/faiss/gpu/GpuIndexCagra.cu b/faiss/gpu/GpuIndexCagra.cu new file mode 100644 index 0000000000..4ae56df10d --- /dev/null +++ b/faiss/gpu/GpuIndexCagra.cu @@ -0,0 +1,274 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace faiss { +namespace gpu { + +GpuIndexCagra::GpuIndexCagra( + GpuResourcesProvider* provider, + int dims, + faiss::MetricType metric, + GpuIndexCagraConfig config) + : GpuIndex(provider->getResources(), dims, metric, 0.0f, config), + cagraConfig_(config) { + this->is_trained = false; +} + +void GpuIndexCagra::train(idx_t n, const float* x) { + if (this->is_trained) { + FAISS_ASSERT(index_); + return; + } + + FAISS_ASSERT(!index_); + + std::optional ivf_pq_params = + std::nullopt; + std::optional ivf_pq_search_params = + std::nullopt; + if (cagraConfig_.ivf_pq_params != nullptr) { + ivf_pq_params = + std::make_optional(); + ivf_pq_params->n_lists = cagraConfig_.ivf_pq_params->n_lists; + ivf_pq_params->kmeans_n_iters = + cagraConfig_.ivf_pq_params->kmeans_n_iters; + ivf_pq_params->kmeans_trainset_fraction = + cagraConfig_.ivf_pq_params->kmeans_trainset_fraction; + ivf_pq_params->pq_bits = cagraConfig_.ivf_pq_params->pq_bits; + ivf_pq_params->pq_dim = cagraConfig_.ivf_pq_params->pq_dim; + ivf_pq_params->codebook_kind = + static_cast( + cagraConfig_.ivf_pq_params->codebook_kind); + ivf_pq_params->force_random_rotation = + cagraConfig_.ivf_pq_params->force_random_rotation; + ivf_pq_params->conservative_memory_allocation = + cagraConfig_.ivf_pq_params->conservative_memory_allocation; + } + if (cagraConfig_.ivf_pq_search_params != nullptr) { + ivf_pq_search_params = + std::make_optional(); + ivf_pq_search_params->n_probes = + cagraConfig_.ivf_pq_search_params->n_probes; + ivf_pq_search_params->lut_dtype = + cagraConfig_.ivf_pq_search_params->lut_dtype; + ivf_pq_search_params->preferred_shmem_carveout = + cagraConfig_.ivf_pq_search_params->preferred_shmem_carveout; + } + index_ = std::make_shared( + this->resources_.get(), + this->d, + cagraConfig_.intermediate_graph_degree, + cagraConfig_.graph_degree, + static_cast(cagraConfig_.build_algo), + cagraConfig_.nn_descent_niter, + this->metric_type, + this->metric_arg, + INDICES_64_BIT, + ivf_pq_params, + ivf_pq_search_params); + + index_->train(n, x); + + this->is_trained = true; + this->ntotal = n; +} + +bool GpuIndexCagra::addImplRequiresIDs_() const { + return false; +}; + +void GpuIndexCagra::addImpl_(idx_t n, const float* x, const idx_t* ids) { + FAISS_THROW_MSG("adding vectors is not supported by GpuIndexCagra."); +}; + +void GpuIndexCagra::searchImpl_( + idx_t n, + const float* x, + int k, + float* distances, + idx_t* labels, + const SearchParameters* search_params) const { + FAISS_ASSERT(this->is_trained && index_); + FAISS_ASSERT(n > 0); + + Tensor queries(const_cast(x), {n, this->d}); + Tensor outDistances(distances, {n, k}); + Tensor outLabels(const_cast(labels), {n, k}); + + SearchParametersCagra* params; + if (search_params) { + params = dynamic_cast( + const_cast(search_params)); + } else { + params = new SearchParametersCagra{}; + } + + index_->search( + queries, + k, + outDistances, + outLabels, + params->max_queries, + params->itopk_size, + params->max_iterations, + static_cast(params->algo), + params->team_size, + params->search_width, + params->min_iterations, + params->thread_block_size, + static_cast(params->hashmap_mode), + params->hashmap_min_bitlen, + params->hashmap_max_fill_rate, + params->num_random_samplings, + params->seed); + + if (not search_params) { + delete params; + } +} + +void GpuIndexCagra::copyFrom(const faiss::IndexHNSWCagra* index) { + FAISS_ASSERT(index); + + DeviceScope scope(config_.device); + + GpuIndex::copyFrom(index); + + auto base_index = dynamic_cast(index->storage); + FAISS_ASSERT(base_index); + auto distances = base_index->get_xb(); + + auto hnsw = index->hnsw; + // copy level 0 to a dense knn graph matrix + std::vector knn_graph; + knn_graph.reserve(index->ntotal * hnsw.nb_neighbors(0)); + +#pragma omp parallel for + for (size_t i = 0; i < index->ntotal; ++i) { + size_t begin, end; + hnsw.neighbor_range(i, 0, &begin, &end); + for (size_t j = begin; j < end; j++) { + // knn_graph.push_back(hnsw.neighbors[j]); + knn_graph[i * hnsw.nb_neighbors(0) + (j - begin)] = + hnsw.neighbors[j]; + } + } + + index_ = std::make_shared( + this->resources_.get(), + this->d, + index->ntotal, + hnsw.nb_neighbors(0), + distances, + knn_graph.data(), + this->metric_type, + this->metric_arg, + INDICES_64_BIT); + + this->is_trained = true; +} + +void GpuIndexCagra::copyTo(faiss::IndexHNSWCagra* index) const { + FAISS_ASSERT(index_ && this->is_trained && index); + + DeviceScope scope(config_.device); + + // + // Index information + // + GpuIndex::copyTo(index); + // This needs to be zeroed out as this implementation adds vectors to the + // cpuIndex instead of copying fields + index->ntotal = 0; + + auto graph_degree = index_->get_knngraph_degree(); + auto M = graph_degree / 2; + if (index->storage and index->own_fields) { + delete index->storage; + } + + if (this->metric_type == METRIC_L2) { + index->storage = new IndexFlatL2(index->d); + } else if (this->metric_type == METRIC_INNER_PRODUCT) { + index->storage = new IndexFlatIP(index->d); + } + index->own_fields = true; + index->keep_max_size_level0 = true; + index->hnsw.reset(); + index->hnsw.assign_probas.clear(); + index->hnsw.cum_nneighbor_per_level.clear(); + index->hnsw.set_default_probas(M, 1.0 / log(M)); + + auto n_train = this->ntotal; + auto train_dataset = index_->get_training_dataset(); + + // turn off as level 0 is copied from CAGRA graph + index->init_level0 = false; + if (!index->base_level_only) { + index->add(n_train, train_dataset.data()); + } else { + index->hnsw.prepare_level_tab(n_train, false); + index->storage->add(n_train, train_dataset.data()); + index->ntotal = n_train; + } + + auto graph = get_knngraph(); + +#pragma omp parallel for + for (idx_t i = 0; i < n_train; i++) { + size_t begin, end; + index->hnsw.neighbor_range(i, 0, &begin, &end); + for (size_t j = begin; j < end; j++) { + index->hnsw.neighbors[j] = graph[i * graph_degree + (j - begin)]; + } + } + + // turn back on to allow new vectors to be added to level 0 + index->init_level0 = true; +} + +void GpuIndexCagra::reset() { + DeviceScope scope(config_.device); + + if (index_) { + index_->reset(); + this->ntotal = 0; + this->is_trained = false; + } else { + FAISS_ASSERT(this->ntotal == 0); + } +} + +std::vector GpuIndexCagra::get_knngraph() const { + FAISS_ASSERT(index_ && this->is_trained); + + return index_->get_knngraph(); +} + +} // namespace gpu +} // namespace faiss diff --git a/faiss/gpu/GpuIndexCagra.h b/faiss/gpu/GpuIndexCagra.h new file mode 100644 index 0000000000..6ecee3ae03 --- /dev/null +++ b/faiss/gpu/GpuIndexCagra.h @@ -0,0 +1,282 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace faiss { +struct IndexHNSWCagra; +} + +namespace faiss { +namespace gpu { + +class RaftCagra; + +enum class graph_build_algo { + /// Use IVF-PQ to build all-neighbors knn graph + IVF_PQ, + /// Experimental, use NN-Descent to build all-neighbors knn graph + NN_DESCENT +}; + +/// A type for specifying how PQ codebooks are created. +enum class codebook_gen { // NOLINT + PER_SUBSPACE = 0, // NOLINT + PER_CLUSTER = 1, // NOLINT +}; + +struct IVFPQBuildCagraConfig { + /// + /// The number of inverted lists (clusters) + /// + /// Hint: the number of vectors per cluster (`n_rows/n_lists`) should be + /// approximately 1,000 to 10,000. + + uint32_t n_lists = 1024; + /// The number of iterations searching for kmeans centers (index building). + uint32_t kmeans_n_iters = 20; + /// The fraction of data to use during iterative kmeans building. + double kmeans_trainset_fraction = 0.5; + /// + /// The bit length of the vector element after compression by PQ. + /// + /// Possible values: [4, 5, 6, 7, 8]. + /// + /// Hint: the smaller the 'pq_bits', the smaller the index size and the + /// better the search performance, but the lower the recall. + + uint32_t pq_bits = 8; + /// + /// The dimensionality of the vector after compression by PQ. When zero, an + /// optimal value is selected using a heuristic. + /// + /// NB: `pq_dim /// pq_bits` must be a multiple of 8. + /// + /// Hint: a smaller 'pq_dim' results in a smaller index size and better + /// search performance, but lower recall. If 'pq_bits' is 8, 'pq_dim' can be + /// set to any number, but multiple of 8 are desirable for good performance. + /// If 'pq_bits' is not 8, 'pq_dim' should be a multiple of 8. For good + /// performance, it is desirable that 'pq_dim' is a multiple of 32. Ideally, + /// 'pq_dim' should be also a divisor of the dataset dim. + + uint32_t pq_dim = 0; + /// How PQ codebooks are created. + codebook_gen codebook_kind = codebook_gen::PER_SUBSPACE; + /// + /// Apply a random rotation matrix on the input data and queries even if + /// `dim % pq_dim == 0`. + /// + /// Note: if `dim` is not multiple of `pq_dim`, a random rotation is always + /// applied to the input data and queries to transform the working space + /// from `dim` to `rot_dim`, which may be slightly larger than the original + /// space and and is a multiple of `pq_dim` (`rot_dim % pq_dim == 0`). + /// However, this transform is not necessary when `dim` is multiple of + /// `pq_dim` + /// (`dim == rot_dim`, hence no need in adding "extra" data columns / + /// features). + /// + /// By default, if `dim == rot_dim`, the rotation transform is initialized + /// with the identity matrix. When `force_random_rotation == true`, a random + /// orthogonal transform matrix is generated regardless of the values of + /// `dim` and `pq_dim`. + + bool force_random_rotation = false; + /// + /// By default, the algorithm allocates more space than necessary for + /// individual clusters + /// (`list_data`). This allows to amortize the cost of memory allocation and + /// reduce the number of data copies during repeated calls to `extend` + /// (extending the database). + /// + /// The alternative is the conservative allocation behavior; when enabled, + /// the algorithm always allocates the minimum amount of memory required to + /// store the given number of records. Set this flag to `true` if you prefer + /// to use as little GPU memory for the database as possible. + + bool conservative_memory_allocation = false; +}; + +struct IVFPQSearchCagraConfig { + /// The number of clusters to search. + uint32_t n_probes = 20; + /// + /// Data type of look up table to be created dynamically at search time. + /// + /// Possible values: [CUDA_R_32F, CUDA_R_16F, CUDA_R_8U] + /// + /// The use of low-precision types reduces the amount of shared memory + /// required at search time, so fast shared memory kernels can be used even + /// for datasets with large dimansionality. Note that the recall is slightly + /// degraded when low-precision type is selected. + + cudaDataType_t lut_dtype = CUDA_R_32F; + /// + /// Storage data type for distance/similarity computed at search time. + /// + /// Possible values: [CUDA_R_16F, CUDA_R_32F] + /// + /// If the performance limiter at search time is device memory access, + /// selecting FP16 will improve performance slightly. + + cudaDataType_t internal_distance_dtype = CUDA_R_32F; + /// + /// Preferred fraction of SM's unified memory / L1 cache to be used as + /// shared memory. + /// + /// Possible values: [0.0 - 1.0] as a fraction of the + /// `sharedMemPerMultiprocessor`. + /// + /// One wants to increase the carveout to make sure a good GPU occupancy for + /// the main search kernel, but not to keep it too high to leave some memory + /// to be used as L1 cache. Note, this value is interpreted only as a hint. + /// Moreover, a GPU usually allows only a fixed set of cache configurations, + /// so the provided value is rounded up to the nearest configuration. Refer + /// to the NVIDIA tuning guide for the target GPU architecture. + /// + /// Note, this is a low-level tuning parameter that can have drastic + /// negative effects on the search performance if tweaked incorrectly. + + double preferred_shmem_carveout = 1.0; +}; + +struct GpuIndexCagraConfig : public GpuIndexConfig { + /// Degree of input graph for pruning. + size_t intermediate_graph_degree = 128; + /// Degree of output graph. + size_t graph_degree = 64; + /// ANN algorithm to build knn graph. + graph_build_algo build_algo = graph_build_algo::IVF_PQ; + /// Number of Iterations to run if building with NN_DESCENT + size_t nn_descent_niter = 20; + + IVFPQBuildCagraConfig* ivf_pq_params = nullptr; + IVFPQSearchCagraConfig* ivf_pq_search_params = nullptr; +}; + +enum class search_algo { + /// For large batch sizes. + SINGLE_CTA, + /// For small batch sizes. + MULTI_CTA, + MULTI_KERNEL, + AUTO +}; + +enum class hash_mode { HASH, SMALL, AUTO }; + +struct SearchParametersCagra : SearchParameters { + /// Maximum number of queries to search at the same time (batch size). Auto + /// select when 0. + size_t max_queries = 0; + + /// Number of intermediate search results retained during the search. + /// + /// This is the main knob to adjust trade off between accuracy and search + /// speed. Higher values improve the search accuracy. + + size_t itopk_size = 64; + + /// Upper limit of search iterations. Auto select when 0. + size_t max_iterations = 0; + + // In the following we list additional search parameters for fine tuning. + // Reasonable default values are automatically chosen. + + /// Which search implementation to use. + search_algo algo = search_algo::AUTO; + + /// Number of threads used to calculate a single distance. 4, 8, 16, or 32. + + size_t team_size = 0; + + /// Number of graph nodes to select as the starting point for the search in + /// each iteration. aka search width? + size_t search_width = 1; + /// Lower limit of search iterations. + size_t min_iterations = 0; + + /// Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. + size_t thread_block_size = 0; + /// Hashmap type. Auto selection when AUTO. + hash_mode hashmap_mode = hash_mode::AUTO; + /// Lower limit of hashmap bit length. More than 8. + size_t hashmap_min_bitlen = 0; + /// Upper limit of hashmap fill rate. More than 0.1, less than 0.9. + float hashmap_max_fill_rate = 0.5; + + /// Number of iterations of initial random seed node selection. 1 or more. + + uint32_t num_random_samplings = 1; + /// Bit mask used for initial random seed node selection. + uint64_t seed = 0x128394; +}; + +struct GpuIndexCagra : public GpuIndex { + public: + GpuIndexCagra( + GpuResourcesProvider* provider, + int dims, + faiss::MetricType metric = faiss::METRIC_L2, + GpuIndexCagraConfig config = GpuIndexCagraConfig()); + + /// Trains CAGRA based on the given vector data + void train(idx_t n, const float* x) override; + + /// Initialize ourselves from the given CPU index; will overwrite + /// all data in ourselves + void copyFrom(const faiss::IndexHNSWCagra* index); + + /// Copy ourselves to the given CPU index; will overwrite all data + /// in the index instance + void copyTo(faiss::IndexHNSWCagra* index) const; + + void reset() override; + + std::vector get_knngraph() const; + + protected: + bool addImplRequiresIDs_() const override; + + void addImpl_(idx_t n, const float* x, const idx_t* ids) override; + + /// Called from GpuIndex for search + void searchImpl_( + idx_t n, + const float* x, + int k, + float* distances, + idx_t* labels, + const SearchParameters* search_params) const override; + + /// Our configuration options + const GpuIndexCagraConfig cagraConfig_; + + /// Instance that we own; contains the inverted lists + std::shared_ptr index_; +}; + +} // namespace gpu +} // namespace faiss diff --git a/faiss/gpu/impl/RaftCagra.cu b/faiss/gpu/impl/RaftCagra.cu new file mode 100644 index 0000000000..292079321d --- /dev/null +++ b/faiss/gpu/impl/RaftCagra.cu @@ -0,0 +1,371 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace faiss { +namespace gpu { + +RaftCagra::RaftCagra( + GpuResources* resources, + int dim, + idx_t intermediate_graph_degree, + idx_t graph_degree, + faiss::cagra_build_algo graph_build_algo, + size_t nn_descent_niter, + faiss::MetricType metric, + float metricArg, + IndicesOptions indicesOptions, + std::optional ivf_pq_params, + std::optional + ivf_pq_search_params) + : resources_(resources), + dim_(dim), + metric_(metric), + metricArg_(metricArg), + index_params_(), + ivf_pq_params_(ivf_pq_params), + ivf_pq_search_params_(ivf_pq_search_params) { + FAISS_THROW_IF_NOT_MSG( + metric == faiss::METRIC_L2 || metric == faiss::METRIC_INNER_PRODUCT, + "CAGRA currently only supports L2 or Inner Product metric."); + FAISS_THROW_IF_NOT_MSG( + indicesOptions == faiss::gpu::INDICES_64_BIT, + "only INDICES_64_BIT is supported for RAFT CAGRA index"); + + index_params_.intermediate_graph_degree = intermediate_graph_degree; + index_params_.graph_degree = graph_degree; + index_params_.build_algo = + static_cast( + graph_build_algo); + index_params_.nn_descent_niter = nn_descent_niter; + + if (!ivf_pq_params_) { + ivf_pq_params_ = + std::make_optional(); + } + if (!ivf_pq_search_params_) { + ivf_pq_search_params_ = + std::make_optional(); + } + index_params_.metric = metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct; + ivf_pq_params_->metric = metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct; + + reset(); +} + +RaftCagra::RaftCagra( + GpuResources* resources, + int dim, + idx_t n, + int graph_degree, + const float* distances, + const idx_t* knn_graph, + faiss::MetricType metric, + float metricArg, + IndicesOptions indicesOptions) + : resources_(resources), + dim_(dim), + metric_(metric), + metricArg_(metricArg) { + FAISS_THROW_IF_NOT_MSG( + metric == faiss::METRIC_L2 || metric == faiss::METRIC_INNER_PRODUCT, + "CAGRA currently only supports L2 or Inner Product metric."); + FAISS_THROW_IF_NOT_MSG( + indicesOptions == faiss::gpu::INDICES_64_BIT, + "only INDICES_64_BIT is supported for RAFT CAGRA index"); + + auto distances_on_gpu = getDeviceForAddress(distances) >= 0; + auto knn_graph_on_gpu = getDeviceForAddress(knn_graph) >= 0; + + FAISS_ASSERT(distances_on_gpu == knn_graph_on_gpu); + + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + + if (distances_on_gpu && knn_graph_on_gpu) { + raft_handle.sync_stream(); + // Copying to host so that raft::neighbors::cagra::index + // creates an owning copy of the knn graph on device + auto knn_graph_copy = + raft::make_host_matrix(n, graph_degree); + thrust::copy( + thrust::device_ptr(knn_graph), + thrust::device_ptr(knn_graph + (n * graph_degree)), + knn_graph_copy.data_handle()); + + auto distances_mds = + raft::make_device_matrix_view( + distances, n, dim); + + raft_knn_index = raft::neighbors::cagra::index( + raft_handle, + metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct, + distances_mds, + raft::make_const_mdspan(knn_graph_copy.view())); + } else if (!distances_on_gpu && !knn_graph_on_gpu) { + // copy idx_t (int64_t) host knn_graph to uint32_t host knn_graph + auto knn_graph_copy = + raft::make_host_matrix(n, graph_degree); + std::copy( + knn_graph, + knn_graph + (n * graph_degree), + knn_graph_copy.data_handle()); + + auto distances_mds = raft::make_host_matrix_view( + distances, n, dim); + + raft_knn_index = raft::neighbors::cagra::index( + raft_handle, + metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct, + distances_mds, + raft::make_const_mdspan(knn_graph_copy.view())); + } else { + FAISS_THROW_MSG( + "distances and knn_graph must both be in device or host memory"); + } +} + +void RaftCagra::train(idx_t n, const float* x) { + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + if (index_params_.build_algo == + raft::neighbors::cagra::graph_build_algo::IVF_PQ) { + std::optional> knn_graph( + raft::make_host_matrix( + n, index_params_.intermediate_graph_degree)); + if (getDeviceForAddress(x) >= 0) { + auto dataset_d = + raft::make_device_matrix_view( + x, n, dim_); + raft::neighbors::cagra::build_knn_graph( + raft_handle, + dataset_d, + knn_graph->view(), + 1.0f, + ivf_pq_params_, + ivf_pq_search_params_); + } else { + auto dataset_h = raft::make_host_matrix_view( + x, n, dim_); + raft::neighbors::cagra::build_knn_graph( + raft_handle, + dataset_h, + knn_graph->view(), + 1.0f, + ivf_pq_params_, + ivf_pq_search_params_); + } + auto cagra_graph = raft::make_host_matrix( + n, index_params_.graph_degree); + + raft::neighbors::cagra::optimize( + raft_handle, knn_graph->view(), cagra_graph.view()); + + // free intermediate graph before trying to create the index + knn_graph.reset(); + + if (getDeviceForAddress(x) >= 0) { + auto dataset_d = + raft::make_device_matrix_view( + x, n, dim_); + raft_knn_index = raft::neighbors::cagra::index( + raft_handle, + metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct, + dataset_d, + raft::make_const_mdspan(cagra_graph.view())); + } else { + auto dataset_h = raft::make_host_matrix_view( + x, n, dim_); + raft_knn_index = raft::neighbors::cagra::index( + raft_handle, + metric_ == faiss::METRIC_L2 + ? raft::distance::DistanceType::L2Expanded + : raft::distance::DistanceType::InnerProduct, + dataset_h, + raft::make_const_mdspan(cagra_graph.view())); + } + + } else { + if (getDeviceForAddress(x) >= 0) { + raft_knn_index = raft::runtime::neighbors::cagra::build( + raft_handle, + index_params_, + raft::make_device_matrix_view( + x, n, dim_)); + } else { + raft_knn_index = raft::runtime::neighbors::cagra::build( + raft_handle, + index_params_, + raft::make_host_matrix_view( + x, n, dim_)); + } + } +} + +void RaftCagra::search( + Tensor& queries, + int k, + Tensor& outDistances, + Tensor& outIndices, + idx_t max_queries, + idx_t itopk_size, + idx_t max_iterations, + faiss::cagra_search_algo graph_search_algo, + idx_t team_size, + idx_t search_width, + idx_t min_iterations, + idx_t thread_block_size, + faiss::cagra_hash_mode hash_mode, + idx_t hashmap_min_bitlen, + float hashmap_max_fill_rate, + idx_t num_random_samplings, + idx_t rand_xor_mask) { + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + idx_t numQueries = queries.getSize(0); + idx_t cols = queries.getSize(1); + idx_t k_ = k; + + FAISS_ASSERT(raft_knn_index.has_value()); + FAISS_ASSERT(numQueries > 0); + FAISS_ASSERT(cols == dim_); + + auto queries_view = raft::make_device_matrix_view( + queries.data(), numQueries, cols); + auto distances_view = raft::make_device_matrix_view( + outDistances.data(), numQueries, k_); + auto indices_view = raft::make_device_matrix_view( + outIndices.data(), numQueries, k_); + + raft::neighbors::cagra::search_params search_pams; + search_pams.max_queries = max_queries; + search_pams.itopk_size = itopk_size; + search_pams.max_iterations = max_iterations; + search_pams.algo = + static_cast(graph_search_algo); + search_pams.team_size = team_size; + search_pams.search_width = search_width; + search_pams.min_iterations = min_iterations; + search_pams.thread_block_size = thread_block_size; + search_pams.hashmap_mode = + static_cast(hash_mode); + search_pams.hashmap_min_bitlen = hashmap_min_bitlen; + search_pams.hashmap_max_fill_rate = hashmap_max_fill_rate; + search_pams.num_random_samplings = num_random_samplings; + search_pams.rand_xor_mask = rand_xor_mask; + + auto indices_copy = raft::make_device_matrix( + raft_handle, numQueries, k_); + + raft::runtime::neighbors::cagra::search( + raft_handle, + search_pams, + raft_knn_index.value(), + queries_view, + indices_copy.view(), + distances_view); + thrust::copy( + raft::resource::get_thrust_policy(raft_handle), + indices_copy.data_handle(), + indices_copy.data_handle() + indices_copy.size(), + indices_view.data_handle()); +} + +void RaftCagra::reset() { + raft_knn_index.reset(); +} + +idx_t RaftCagra::get_knngraph_degree() const { + FAISS_ASSERT(raft_knn_index.has_value()); + return static_cast(raft_knn_index.value().graph_degree()); +} + +std::vector RaftCagra::get_knngraph() const { + FAISS_ASSERT(raft_knn_index.has_value()); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + auto stream = raft_handle.get_stream(); + + auto device_graph = raft_knn_index.value().graph(); + + std::vector host_graph( + device_graph.extent(0) * device_graph.extent(1)); + + raft_handle.sync_stream(); + + thrust::copy( + thrust::device_ptr(device_graph.data_handle()), + thrust::device_ptr( + device_graph.data_handle() + device_graph.size()), + host_graph.data()); + + return host_graph; +} + +std::vector RaftCagra::get_training_dataset() const { + FAISS_ASSERT(raft_knn_index.has_value()); + const raft::device_resources& raft_handle = + resources_->getRaftHandleCurrentDevice(); + auto stream = raft_handle.get_stream(); + + auto device_dataset = raft_knn_index.value().dataset(); + + std::vector host_dataset( + device_dataset.extent(0) * device_dataset.extent(1)); + + RAFT_CUDA_TRY(cudaMemcpy2DAsync( + host_dataset.data(), + sizeof(float) * dim_, + device_dataset.data_handle(), + sizeof(float) * device_dataset.stride(0), + sizeof(float) * dim_, + device_dataset.extent(0), + cudaMemcpyDefault, + raft_handle.get_stream())); + raft_handle.sync_stream(); + + return host_dataset; +} + +} // namespace gpu +} // namespace faiss diff --git a/faiss/gpu/impl/RaftCagra.cuh b/faiss/gpu/impl/RaftCagra.cuh new file mode 100644 index 0000000000..95f6c03fca --- /dev/null +++ b/faiss/gpu/impl/RaftCagra.cuh @@ -0,0 +1,132 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace faiss { + +/// Algorithm used to build underlying CAGRA graph +enum class cagra_build_algo { IVF_PQ, NN_DESCENT }; + +enum class cagra_search_algo { SINGLE_CTA, MULTI_CTA }; + +enum class cagra_hash_mode { HASH, SMALL, AUTO }; + +namespace gpu { + +class RaftCagra { + public: + RaftCagra( + GpuResources* resources, + int dim, + idx_t intermediate_graph_degree, + idx_t graph_degree, + faiss::cagra_build_algo graph_build_algo, + size_t nn_descent_niter, + faiss::MetricType metric, + float metricArg, + IndicesOptions indicesOptions, + std::optional ivf_pq_params = + std::nullopt, + std::optional + ivf_pq_search_params = std::nullopt); + + RaftCagra( + GpuResources* resources, + int dim, + idx_t n, + int graph_degree, + const float* distances, + const idx_t* knn_graph, + faiss::MetricType metric, + float metricArg, + IndicesOptions indicesOptions); + + ~RaftCagra() = default; + + void train(idx_t n, const float* x); + + void search( + Tensor& queries, + int k, + Tensor& outDistances, + Tensor& outIndices, + idx_t max_queries, + idx_t itopk_size, + idx_t max_iterations, + faiss::cagra_search_algo graph_search_algo, + idx_t team_size, + idx_t search_width, + idx_t min_iterations, + idx_t thread_block_size, + faiss::cagra_hash_mode hash_mode, + idx_t hashmap_min_bitlen, + float hashmap_max_fill_rate, + idx_t num_random_samplings, + idx_t rand_xor_mask); + + void reset(); + + idx_t get_knngraph_degree() const; + + std::vector get_knngraph() const; + + std::vector get_training_dataset() const; + + private: + /// Collection of GPU resources that we use + GpuResources* resources_; + + /// Expected dimensionality of the vectors + const int dim_; + + /// Metric type of the index + faiss::MetricType metric_; + + /// Metric arg + float metricArg_; + + /// Parameters to build RAFT CAGRA index + raft::neighbors::cagra::index_params index_params_; + + /// Parameters to build CAGRA graph using IVF PQ + std::optional ivf_pq_params_; + std::optional ivf_pq_search_params_; + + /// Instance of trained RAFT CAGRA index + std::optional> + raft_knn_index{std::nullopt}; +}; + +} // namespace gpu +} // namespace faiss diff --git a/faiss/gpu/test/CMakeLists.txt b/faiss/gpu/test/CMakeLists.txt index 9300deead9..60f78ef74f 100644 --- a/faiss/gpu/test/CMakeLists.txt +++ b/faiss/gpu/test/CMakeLists.txt @@ -21,7 +21,6 @@ find_package(CUDAToolkit REQUIRED) # Defines `gtest_discover_tests()`. include(GoogleTest) - add_library(faiss_gpu_test_helper TestUtils.cpp) target_link_libraries(faiss_gpu_test_helper PUBLIC faiss gtest CUDA::cudart $<$:raft::raft> $<$:raft::compiled>) @@ -42,6 +41,9 @@ faiss_gpu_test(TestGpuIndexIVFPQ.cpp) faiss_gpu_test(TestGpuIndexIVFScalarQuantizer.cpp) faiss_gpu_test(TestGpuDistance.cu) faiss_gpu_test(TestGpuSelect.cu) +if(FAISS_ENABLE_RAFT) + faiss_gpu_test(TestGpuIndexCagra.cu) +endif() add_executable(demo_ivfpq_indexing_gpu EXCLUDE_FROM_ALL demo_ivfpq_indexing_gpu.cpp) diff --git a/faiss/gpu/test/TestGpuIndexCagra.cu b/faiss/gpu/test/TestGpuIndexCagra.cu new file mode 100644 index 0000000000..8d330a81cb --- /dev/null +++ b/faiss/gpu/test/TestGpuIndexCagra.cu @@ -0,0 +1,474 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct Options { + Options() { + numTrain = 2 * faiss::gpu::randVal(2000, 5000); + dim = faiss::gpu::randVal(4, 10); + numAdd = faiss::gpu::randVal(1000, 3000); + + graphDegree = faiss::gpu::randSelect({32, 64}); + intermediateGraphDegree = faiss::gpu::randSelect({64, 98}); + buildAlgo = faiss::gpu::randSelect( + {faiss::gpu::graph_build_algo::IVF_PQ, + faiss::gpu::graph_build_algo::NN_DESCENT}); + + numQuery = faiss::gpu::randVal(32, 100); + k = faiss::gpu::randVal(10, 30); + + device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1); + } + + std::string toString() const { + std::stringstream str; + str << "CAGRA device " << device << " numVecs " << numTrain << " dim " + << dim << " graphDegree " << graphDegree + << " intermediateGraphDegree " << intermediateGraphDegree + << "buildAlgo " << static_cast(buildAlgo) << " numQuery " + << numQuery << " k " << k; + + return str.str(); + } + + int numTrain; + int numAdd; + int dim; + size_t graphDegree; + size_t intermediateGraphDegree; + faiss::gpu::graph_build_algo buildAlgo; + int numQuery; + int k; + int device; +}; + +void queryTest(faiss::MetricType metric, double expected_recall) { + for (int tries = 0; tries < 5; ++tries) { + Options opt; + if (opt.buildAlgo == faiss::gpu::graph_build_algo::NN_DESCENT && + metric == faiss::METRIC_INNER_PRODUCT) { + continue; + } + + std::vector trainVecs = + faiss::gpu::randVecs(opt.numTrain, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numTrain, opt.dim, trainVecs.data()); + } + + // train cpu index + faiss::IndexHNSWFlat cpuIndex(opt.dim, opt.graphDegree / 2, metric); + cpuIndex.hnsw.efConstruction = opt.k * 2; + cpuIndex.add(opt.numTrain, trainVecs.data()); + + // train gpu index + faiss::gpu::StandardGpuResources res; + res.noTempMemory(); + + faiss::gpu::GpuIndexCagraConfig config; + config.device = opt.device; + config.graph_degree = opt.graphDegree; + config.intermediate_graph_degree = opt.intermediateGraphDegree; + config.build_algo = opt.buildAlgo; + + faiss::gpu::GpuIndexCagra gpuIndex(&res, cpuIndex.d, metric, config); + gpuIndex.train(opt.numTrain, trainVecs.data()); + + // query + auto queryVecs = faiss::gpu::randVecs(opt.numQuery, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numQuery, opt.dim, queryVecs.data()); + } + + std::vector refDistance(opt.numQuery * opt.k, 0); + std::vector refIndices(opt.numQuery * opt.k, -1); + faiss::SearchParametersHNSW cpuSearchParams; + cpuSearchParams.efSearch = opt.k * 2; + cpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + refDistance.data(), + refIndices.data(), + &cpuSearchParams); + + // test quality of searches + auto gpuRes = res.getResources(); + auto devAlloc = faiss::gpu::makeDevAlloc( + faiss::gpu::AllocType::FlatData, + gpuRes->getDefaultStreamCurrentDevice()); + faiss::gpu::DeviceTensor testDistance( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + faiss::gpu::DeviceTensor testIndices( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + gpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + testDistance.data(), + testIndices.data()); + + auto refDistanceDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + refDistance, + gpuRes->getDefaultStreamCurrentDevice()); + auto refIndicesDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + refIndices, + gpuRes->getDefaultStreamCurrentDevice()); + + auto raft_handle = gpuRes->getRaftHandleCurrentDevice(); + + auto ref_dis_mds = raft::make_device_matrix_view( + refDistanceDev.data(), opt.numQuery, opt.k); + auto ref_dis_mds_opt = + std::optional>( + ref_dis_mds); + auto ref_ind_mds = + raft::make_device_matrix_view( + refIndicesDev.data(), opt.numQuery, opt.k); + + auto test_dis_mds = raft::make_device_matrix_view( + testDistance.data(), opt.numQuery, opt.k); + auto test_dis_mds_opt = + std::optional>( + test_dis_mds); + + auto test_ind_mds = + raft::make_device_matrix_view( + testIndices.data(), opt.numQuery, opt.k); + + double scalar_init = 0; + auto recall_score = raft::make_host_scalar(scalar_init); + + raft::stats::neighborhood_recall( + raft_handle, + test_ind_mds, + ref_ind_mds, + recall_score.view(), + test_dis_mds_opt, + ref_dis_mds_opt); + ASSERT_TRUE(*recall_score.data_handle() > expected_recall); + } +} + +TEST(TestGpuIndexCagra, Float32_Query_L2) { + queryTest(faiss::METRIC_L2, 0.98); +} + +TEST(TestGpuIndexCagra, Float32_Query_IP) { + queryTest(faiss::METRIC_INNER_PRODUCT, 0.98); +} + +void copyToTest( + faiss::MetricType metric, + double expected_recall, + bool base_level_only) { + for (int tries = 0; tries < 5; ++tries) { + Options opt; + if (opt.buildAlgo == faiss::gpu::graph_build_algo::NN_DESCENT && + metric == faiss::METRIC_INNER_PRODUCT) { + continue; + } + + std::vector trainVecs = + faiss::gpu::randVecs(opt.numTrain, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numTrain, opt.dim, trainVecs.data()); + } + std::vector addVecs = faiss::gpu::randVecs(opt.numAdd, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numAdd, opt.dim, addVecs.data()); + } + + faiss::gpu::StandardGpuResources res; + res.noTempMemory(); + + // train gpu index and copy to cpu index + faiss::gpu::GpuIndexCagraConfig config; + config.device = opt.device; + config.graph_degree = opt.graphDegree; + config.intermediate_graph_degree = opt.intermediateGraphDegree; + config.build_algo = opt.buildAlgo; + + faiss::gpu::GpuIndexCagra gpuIndex(&res, opt.dim, metric, config); + gpuIndex.train(opt.numTrain, trainVecs.data()); + + faiss::IndexHNSWCagra copiedCpuIndex( + opt.dim, opt.graphDegree / 2, metric); + copiedCpuIndex.base_level_only = base_level_only; + gpuIndex.copyTo(&copiedCpuIndex); + copiedCpuIndex.hnsw.efConstruction = opt.k * 2; + + // add more vecs to copied cpu index + if (!base_level_only) { + copiedCpuIndex.add(opt.numAdd, addVecs.data()); + } + + // train cpu index + faiss::IndexHNSWFlat cpuIndex(opt.dim, opt.graphDegree / 2, metric); + cpuIndex.hnsw.efConstruction = opt.k * 2; + cpuIndex.add(opt.numTrain, trainVecs.data()); + + // add more vecs to cpu index + if (!base_level_only) { + cpuIndex.add(opt.numAdd, addVecs.data()); + } + + // query indexes + auto queryVecs = faiss::gpu::randVecs(opt.numQuery, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numQuery, opt.dim, queryVecs.data()); + } + + std::vector refDistance(opt.numQuery * opt.k, 0); + std::vector refIndices(opt.numQuery * opt.k, -1); + faiss::SearchParametersHNSW cpuSearchParams; + cpuSearchParams.efSearch = opt.k * 2; + cpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + refDistance.data(), + refIndices.data(), + &cpuSearchParams); + + std::vector copyRefDistance(opt.numQuery * opt.k, 0); + std::vector copyRefIndices(opt.numQuery * opt.k, -1); + faiss::SearchParametersHNSW cpuSearchParamstwo; + cpuSearchParamstwo.efSearch = opt.k * 2; + copiedCpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + copyRefDistance.data(), + copyRefIndices.data(), + &cpuSearchParamstwo); + + // test quality of search + auto gpuRes = res.getResources(); + + auto refDistanceDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + refDistance, + gpuRes->getDefaultStreamCurrentDevice()); + auto refIndicesDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + refIndices, + gpuRes->getDefaultStreamCurrentDevice()); + + auto copyRefDistanceDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + copyRefDistance, + gpuRes->getDefaultStreamCurrentDevice()); + auto copyRefIndicesDev = faiss::gpu::toDeviceTemporary( + gpuRes.get(), + copyRefIndices, + gpuRes->getDefaultStreamCurrentDevice()); + + auto raft_handle = gpuRes->getRaftHandleCurrentDevice(); + + auto ref_dis_mds = raft::make_device_matrix_view( + refDistanceDev.data(), opt.numQuery, opt.k); + auto ref_dis_mds_opt = + std::optional>( + ref_dis_mds); + auto ref_ind_mds = + raft::make_device_matrix_view( + refIndicesDev.data(), opt.numQuery, opt.k); + + auto copy_ref_dis_mds = raft::make_device_matrix_view( + copyRefDistanceDev.data(), opt.numQuery, opt.k); + auto copy_ref_dis_mds_opt = + std::optional>( + copy_ref_dis_mds); + auto copy_ref_ind_mds = + raft::make_device_matrix_view( + copyRefIndicesDev.data(), opt.numQuery, opt.k); + + double scalar_init = 0; + auto recall_score = raft::make_host_scalar(scalar_init); + + raft::stats::neighborhood_recall( + raft_handle, + copy_ref_ind_mds, + ref_ind_mds, + recall_score.view(), + copy_ref_dis_mds_opt, + ref_dis_mds_opt); + ASSERT_TRUE(*recall_score.data_handle() > expected_recall); + } +} + +TEST(TestGpuIndexCagra, Float32_CopyTo_L2) { + copyToTest(faiss::METRIC_L2, 0.98, false); +} + +TEST(TestGpuIndexCagra, Float32_CopyTo_L2_BaseLevelOnly) { + copyToTest(faiss::METRIC_L2, 0.98, true); +} + +TEST(TestGpuIndexCagra, Float32_CopyTo_IP) { + copyToTest(faiss::METRIC_INNER_PRODUCT, 0.98, false); +} + +TEST(TestGpuIndexCagra, Float32_CopyTo_IP_BaseLevelOnly) { + copyToTest(faiss::METRIC_INNER_PRODUCT, 0.98, true); +} + +void copyFromTest(faiss::MetricType metric, double expected_recall) { + for (int tries = 0; tries < 5; ++tries) { + Options opt; + if (opt.buildAlgo == faiss::gpu::graph_build_algo::NN_DESCENT && + metric == faiss::METRIC_INNER_PRODUCT) { + continue; + } + + std::vector trainVecs = + faiss::gpu::randVecs(opt.numTrain, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numTrain, opt.dim, trainVecs.data()); + } + + // train cpu index + faiss::IndexHNSWCagra cpuIndex(opt.dim, opt.graphDegree / 2, metric); + cpuIndex.hnsw.efConstruction = opt.k * 2; + cpuIndex.add(opt.numTrain, trainVecs.data()); + + faiss::gpu::StandardGpuResources res; + res.noTempMemory(); + + // convert to gpu index + faiss::gpu::GpuIndexCagra copiedGpuIndex(&res, cpuIndex.d, metric); + copiedGpuIndex.copyFrom(&cpuIndex); + + // train gpu index + faiss::gpu::GpuIndexCagraConfig config; + config.device = opt.device; + config.graph_degree = opt.graphDegree; + config.intermediate_graph_degree = opt.intermediateGraphDegree; + config.build_algo = opt.buildAlgo; + + faiss::gpu::GpuIndexCagra gpuIndex(&res, opt.dim, metric, config); + gpuIndex.train(opt.numTrain, trainVecs.data()); + + // query + auto queryVecs = faiss::gpu::randVecs(opt.numQuery, opt.dim); + if (metric == faiss::METRIC_INNER_PRODUCT) { + faiss::fvec_renorm_L2(opt.numQuery, opt.dim, queryVecs.data()); + } + + auto gpuRes = res.getResources(); + auto devAlloc = faiss::gpu::makeDevAlloc( + faiss::gpu::AllocType::FlatData, + gpuRes->getDefaultStreamCurrentDevice()); + faiss::gpu::DeviceTensor copyTestDistance( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + faiss::gpu::DeviceTensor copyTestIndices( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + copiedGpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + copyTestDistance.data(), + copyTestIndices.data()); + + faiss::gpu::DeviceTensor testDistance( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + faiss::gpu::DeviceTensor testIndices( + gpuRes.get(), devAlloc, {opt.numQuery, opt.k}); + gpuIndex.search( + opt.numQuery, + queryVecs.data(), + opt.k, + testDistance.data(), + testIndices.data()); + + // test quality of searches + auto raft_handle = gpuRes->getRaftHandleCurrentDevice(); + + auto test_dis_mds = raft::make_device_matrix_view( + testDistance.data(), opt.numQuery, opt.k); + auto test_dis_mds_opt = + std::optional>( + test_dis_mds); + + auto test_ind_mds = + raft::make_device_matrix_view( + testIndices.data(), opt.numQuery, opt.k); + + auto copy_test_dis_mds = + raft::make_device_matrix_view( + copyTestDistance.data(), opt.numQuery, opt.k); + auto copy_test_dis_mds_opt = + std::optional>( + copy_test_dis_mds); + + auto copy_test_ind_mds = + raft::make_device_matrix_view( + copyTestIndices.data(), opt.numQuery, opt.k); + + double scalar_init = 0; + auto recall_score = raft::make_host_scalar(scalar_init); + + raft::stats::neighborhood_recall( + raft_handle, + copy_test_ind_mds, + test_ind_mds, + recall_score.view(), + copy_test_dis_mds_opt, + test_dis_mds_opt); + ASSERT_TRUE(*recall_score.data_handle() > expected_recall); + } +} + +TEST(TestGpuIndexCagra, Float32_CopyFrom_L2) { + copyFromTest(faiss::METRIC_L2, 0.98); +} + +TEST(TestGpuIndexCagra, Float32_CopyFrom_IP) { + copyFromTest(faiss::METRIC_INNER_PRODUCT, 0.98); +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + + // just run with a fixed test seed + faiss::gpu::setTestSeed(100); + + return RUN_ALL_TESTS(); +} diff --git a/faiss/gpu/test/test_cagra.py b/faiss/gpu/test/test_cagra.py new file mode 100644 index 0000000000..dd7d09f2de --- /dev/null +++ b/faiss/gpu/test/test_cagra.py @@ -0,0 +1,71 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import unittest + +import faiss +import numpy as np + +from faiss.contrib import datasets, evaluation + + +@unittest.skipIf( + "RAFT" not in faiss.get_compile_options(), + "only if RAFT is compiled in") +class TestComputeGT(unittest.TestCase): + + def do_compute_GT(self, metric): + d = 64 + k = 12 + ds = datasets.SyntheticDataset(d, 0, 10000, 100) + Dref, Iref = faiss.knn(ds.get_queries(), ds.get_database(), k, metric) + + res = faiss.StandardGpuResources() + + index = faiss.GpuIndexCagra(res, d, metric) + index.train(ds.get_database()) + Dnew, Inew = index.search(ds.get_queries(), k) + + evaluation.check_ref_knn_with_draws(Dref, Iref, Dnew, Inew, k) + + def test_compute_GT_L2(self): + self.do_compute_GT(faiss.METRIC_L2) + + def test_compute_GT_IP(self): + self.do_compute_GT(faiss.METRIC_INNER_PRODUCT) + +@unittest.skipIf( + "RAFT" not in faiss.get_compile_options(), + "only if RAFT is compiled in") +class TestInterop(unittest.TestCase): + + def do_interop(self, metric): + d = 64 + k = 12 + ds = datasets.SyntheticDataset(d, 0, 10000, 100) + + res = faiss.StandardGpuResources() + + index = faiss.GpuIndexCagra(res, d, metric) + index.train(ds.get_database()) + Dnew, Inew = index.search(ds.get_queries(), k) + + cpu_index = faiss.index_gpu_to_cpu(index) + Dref, Iref = cpu_index.search(ds.get_queries(), k) + + evaluation.check_ref_knn_with_draws(Dref, Iref, Dnew, Inew, k) + + faiss.write_index(cpu_index, "index_hnsw_cagra.index") + deserialized_index = faiss.read_index("index_hnsw_cagra.index") + gpu_index = faiss.index_cpu_to_gpu(res, 0, deserialized_index) + Dnew2, Inew2 = gpu_index.search(ds.get_queries(), k) + + evaluation.check_ref_knn_with_draws(Dnew2, Inew2, Dnew, Inew, k) + + def test_interop_L2(self): + self.do_interop(faiss.METRIC_L2) + + def test_interop_IP(self): + self.do_interop(faiss.METRIC_INNER_PRODUCT) diff --git a/faiss/impl/HNSW.cpp b/faiss/impl/HNSW.cpp index d8c8225968..3ba5f72f68 100644 --- a/faiss/impl/HNSW.cpp +++ b/faiss/impl/HNSW.cpp @@ -7,6 +7,7 @@ #include +#include #include #include @@ -215,8 +216,8 @@ int HNSW::prepare_level_tab(size_t n, bool preset_levels) { if (pt_level > max_level) max_level = pt_level; offsets.push_back(offsets.back() + cum_nb_neighbors(pt_level + 1)); - neighbors.resize(offsets.back(), -1); } + neighbors.resize(offsets.back(), -1); return max_level; } @@ -229,7 +230,14 @@ void HNSW::shrink_neighbor_list( DistanceComputer& qdis, std::priority_queue& input, std::vector& output, - int max_size) { + int max_size, + bool keep_max_size_level0) { + // This prevents number of neighbors at + // level 0 from being shrunk to less than 2 * M. + // This is essential in making sure + // `faiss::gpu::GpuIndexCagra::copyFrom(IndexHNSWCagra*)` is functional + std::vector outsiders; + while (input.size() > 0) { NodeDistFarther v1 = input.top(); input.pop(); @@ -250,8 +258,15 @@ void HNSW::shrink_neighbor_list( if (output.size() >= max_size) { return; } + } else if (keep_max_size_level0) { + outsiders.push_back(v1); } } + size_t idx = 0; + while (keep_max_size_level0 && (output.size() < max_size) && + (idx < outsiders.size())) { + output.push_back(outsiders[idx++]); + } } namespace { @@ -268,7 +283,8 @@ using NodeDistFarther = HNSW::NodeDistFarther; void shrink_neighbor_list( DistanceComputer& qdis, std::priority_queue& resultSet1, - int max_size) { + int max_size, + bool keep_max_size_level0 = false) { if (resultSet1.size() < max_size) { return; } @@ -280,7 +296,8 @@ void shrink_neighbor_list( resultSet1.pop(); } - HNSW::shrink_neighbor_list(qdis, resultSet, returnlist, max_size); + HNSW::shrink_neighbor_list( + qdis, resultSet, returnlist, max_size, keep_max_size_level0); for (NodeDistFarther curen2 : returnlist) { resultSet1.emplace(curen2.d, curen2.id); @@ -294,7 +311,8 @@ void add_link( DistanceComputer& qdis, storage_idx_t src, storage_idx_t dest, - int level) { + int level, + bool keep_max_size_level0 = false) { size_t begin, end; hnsw.neighbor_range(src, level, &begin, &end); if (hnsw.neighbors[end - 1] == -1) { @@ -319,7 +337,7 @@ void add_link( resultSet.emplace(qdis.symmetric_dis(src, neigh), neigh); } - shrink_neighbor_list(qdis, resultSet, end - begin); + shrink_neighbor_list(qdis, resultSet, end - begin, keep_max_size_level0); // ...and back size_t i = begin; @@ -429,7 +447,8 @@ void HNSW::add_links_starting_from( float d_nearest, int level, omp_lock_t* locks, - VisitedTable& vt) { + VisitedTable& vt, + bool keep_max_size_level0) { std::priority_queue link_targets; search_neighbors_to_add( @@ -438,13 +457,13 @@ void HNSW::add_links_starting_from( // but we can afford only this many neighbors int M = nb_neighbors(level); - ::faiss::shrink_neighbor_list(ptdis, link_targets, M); + ::faiss::shrink_neighbor_list(ptdis, link_targets, M, keep_max_size_level0); std::vector neighbors; neighbors.reserve(link_targets.size()); while (!link_targets.empty()) { storage_idx_t other_id = link_targets.top().id; - add_link(*this, ptdis, pt_id, other_id, level); + add_link(*this, ptdis, pt_id, other_id, level, keep_max_size_level0); neighbors.push_back(other_id); link_targets.pop(); } @@ -452,7 +471,7 @@ void HNSW::add_links_starting_from( omp_unset_lock(&locks[pt_id]); for (storage_idx_t other_id : neighbors) { omp_set_lock(&locks[other_id]); - add_link(*this, ptdis, other_id, pt_id, level); + add_link(*this, ptdis, other_id, pt_id, level, keep_max_size_level0); omp_unset_lock(&locks[other_id]); } omp_set_lock(&locks[pt_id]); @@ -467,7 +486,8 @@ void HNSW::add_with_locks( int pt_level, int pt_id, std::vector& locks, - VisitedTable& vt) { + VisitedTable& vt, + bool keep_max_size_level0) { // greedy search on upper levels storage_idx_t nearest; @@ -496,7 +516,14 @@ void HNSW::add_with_locks( for (; level >= 0; level--) { add_links_starting_from( - ptdis, pt_id, nearest, d_nearest, level, locks.data(), vt); + ptdis, + pt_id, + nearest, + d_nearest, + level, + locks.data(), + vt, + keep_max_size_level0); } omp_unset_lock(&locks[pt_id]); @@ -910,9 +937,12 @@ void HNSW::search_level_0( const float* nearest_d, int search_type, HNSWStats& search_stats, - VisitedTable& vt) const { + VisitedTable& vt, + const SearchParametersHNSW* params) const { const HNSW& hnsw = *this; + auto efSearch = params ? params->efSearch : hnsw.efSearch; int k = extract_k_from_ResultHandler(res); + if (search_type == 1) { int nres = 0; @@ -925,16 +955,24 @@ void HNSW::search_level_0( if (vt.get(cj)) continue; - int candidates_size = std::max(hnsw.efSearch, k); + int candidates_size = std::max(efSearch, k); MinimaxHeap candidates(candidates_size); candidates.push(cj, nearest_d[j]); nres = search_from_candidates( - hnsw, qdis, res, candidates, vt, search_stats, 0, nres); + hnsw, + qdis, + res, + candidates, + vt, + search_stats, + 0, + nres, + params); } } else if (search_type == 2) { - int candidates_size = std::max(hnsw.efSearch, int(k)); + int candidates_size = std::max(efSearch, int(k)); candidates_size = std::max(candidates_size, int(nprobe)); MinimaxHeap candidates(candidates_size); @@ -947,7 +985,7 @@ void HNSW::search_level_0( } search_from_candidates( - hnsw, qdis, res, candidates, vt, search_stats, 0); + hnsw, qdis, res, candidates, vt, search_stats, 0, 0, params); } } diff --git a/faiss/impl/HNSW.h b/faiss/impl/HNSW.h index 8261423cdd..f3aacf8a5b 100644 --- a/faiss/impl/HNSW.h +++ b/faiss/impl/HNSW.h @@ -184,7 +184,8 @@ struct HNSW { float d_nearest, int level, omp_lock_t* locks, - VisitedTable& vt); + VisitedTable& vt, + bool keep_max_size_level0 = false); /** add point pt_id on all levels <= pt_level and build the link * structure for them. */ @@ -193,7 +194,8 @@ struct HNSW { int pt_level, int pt_id, std::vector& locks, - VisitedTable& vt); + VisitedTable& vt, + bool keep_max_size_level0 = false); /// search interface for 1 point, single thread HNSWStats search( @@ -211,7 +213,8 @@ struct HNSW { const float* nearest_d, int search_type, HNSWStats& search_stats, - VisitedTable& vt) const; + VisitedTable& vt, + const SearchParametersHNSW* params = nullptr) const; void reset(); @@ -224,7 +227,8 @@ struct HNSW { DistanceComputer& qdis, std::priority_queue& input, std::vector& output, - int max_size); + int max_size, + bool keep_max_size_level0 = false); void permute_entries(const idx_t* map); }; diff --git a/faiss/impl/index_read.cpp b/faiss/impl/index_read.cpp index ce4b1e76b1..aa041c0fac 100644 --- a/faiss/impl/index_read.cpp +++ b/faiss/impl/index_read.cpp @@ -950,7 +950,7 @@ Index* read_index(IOReader* f, int io_flags) { idx = idxp; } else if ( h == fourcc("IHNf") || h == fourcc("IHNp") || h == fourcc("IHNs") || - h == fourcc("IHN2")) { + h == fourcc("IHN2") || h == fourcc("IHNc")) { IndexHNSW* idxhnsw = nullptr; if (h == fourcc("IHNf")) idxhnsw = new IndexHNSWFlat(); @@ -960,7 +960,15 @@ Index* read_index(IOReader* f, int io_flags) { idxhnsw = new IndexHNSWSQ(); if (h == fourcc("IHN2")) idxhnsw = new IndexHNSW2Level(); + if (h == fourcc("IHNc")) + idxhnsw = new IndexHNSWCagra(); read_index_header(idxhnsw, f); + if (h == fourcc("IHNc")) { + READ1(idxhnsw->keep_max_size_level0); + auto idx_hnsw_cagra = dynamic_cast(idxhnsw); + READ1(idx_hnsw_cagra->base_level_only); + READ1(idx_hnsw_cagra->num_base_level_search_entrypoints); + } read_HNSW(&idxhnsw->hnsw, f); idxhnsw->storage = read_index(f, io_flags); idxhnsw->own_fields = idxhnsw->storage != nullptr; diff --git a/faiss/impl/index_write.cpp b/faiss/impl/index_write.cpp index 01e5ae7257..0a924d0225 100644 --- a/faiss/impl/index_write.cpp +++ b/faiss/impl/index_write.cpp @@ -762,10 +762,17 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) { : dynamic_cast(idx) ? fourcc("IHNp") : dynamic_cast(idx) ? fourcc("IHNs") : dynamic_cast(idx) ? fourcc("IHN2") + : dynamic_cast(idx) ? fourcc("IHNc") : 0; FAISS_THROW_IF_NOT(h != 0); WRITE1(h); write_index_header(idxhnsw, f); + if (h == fourcc("IHNc")) { + WRITE1(idxhnsw->keep_max_size_level0); + auto idx_hnsw_cagra = dynamic_cast(idxhnsw); + WRITE1(idx_hnsw_cagra->base_level_only); + WRITE1(idx_hnsw_cagra->num_base_level_search_entrypoints); + } write_HNSW(&idxhnsw->hnsw, f); if (io_flags & IO_FLAG_SKIP_STORAGE) { uint32_t n4 = fourcc("null"); diff --git a/faiss/python/CMakeLists.txt b/faiss/python/CMakeLists.txt index dee8c7762e..0073c20e04 100644 --- a/faiss/python/CMakeLists.txt +++ b/faiss/python/CMakeLists.txt @@ -38,6 +38,11 @@ macro(configure_swigfaiss source) set_source_files_properties(${source} PROPERTIES COMPILE_DEFINITIONS GPU_WRAPPER ) + if (FAISS_ENABLE_RAFT) + set_property(SOURCE ${source} APPEND PROPERTY + COMPILE_DEFINITIONS FAISS_ENABLE_RAFT + ) + endif() endif() endmacro() diff --git a/faiss/python/swigfaiss.swig b/faiss/python/swigfaiss.swig index 85e04d322c..74a371f6cd 100644 --- a/faiss/python/swigfaiss.swig +++ b/faiss/python/swigfaiss.swig @@ -304,6 +304,7 @@ void gpu_sync_all_devices(); #include #include #include +#include #include #include #include @@ -557,6 +558,9 @@ struct faiss::simd16uint16 {}; %include %include %include +#ifdef FAISS_ENABLE_RAFT +%include +#endif %include %include %include @@ -673,6 +677,9 @@ struct faiss::simd16uint16 {}; DOWNCAST ( IndexRowwiseMinMax ) DOWNCAST ( IndexRowwiseMinMaxFP16 ) #ifdef GPU_WRAPPER +#ifdef FAISS_ENABLE_RAFT + DOWNCAST_GPU ( GpuIndexCagra ) +#endif DOWNCAST_GPU ( GpuIndexIVFPQ ) DOWNCAST_GPU ( GpuIndexIVFFlat ) DOWNCAST_GPU ( GpuIndexIVFScalarQuantizer ) From f71d5b9aa2c37d24c63a5ef4035294f2eeed1e25 Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Tue, 11 Jun 2024 08:14:48 -0700 Subject: [PATCH 198/206] fix spurious include to land the cagra diff (#3502) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3502 include probably added by vscode Reviewed By: mengdilin Differential Revision: D58411537 fbshipit-source-id: 3035f690d26decc937fb492c54ffa2f974ee2db8 --- CMakeLists.txt | 2 -- faiss/IndexHNSW.cpp | 1 - faiss/gpu/test/test_cagra.py | 6 +++--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a468fb247..cedee9c456 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,8 +46,6 @@ project(faiss LANGUAGES ${FAISS_LANGUAGES}) include(GNUInstallDirs) -set(CMAKE_INSTALL_PREFIX "$ENV{CONDA_PREFIX}") - set(CMAKE_CXX_STANDARD 17) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index c04642d218..fd80b87df7 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -24,7 +24,6 @@ #include #include #include -#include "impl/HNSW.h" #include #include diff --git a/faiss/gpu/test/test_cagra.py b/faiss/gpu/test/test_cagra.py index dd7d09f2de..4c7e532c2b 100644 --- a/faiss/gpu/test/test_cagra.py +++ b/faiss/gpu/test/test_cagra.py @@ -6,7 +6,6 @@ import unittest import faiss -import numpy as np from faiss.contrib import datasets, evaluation @@ -57,8 +56,9 @@ def do_interop(self, metric): evaluation.check_ref_knn_with_draws(Dref, Iref, Dnew, Inew, k) - faiss.write_index(cpu_index, "index_hnsw_cagra.index") - deserialized_index = faiss.read_index("index_hnsw_cagra.index") + deserialized_index = faiss.deserialize_index( + faiss.serialize_index(cpu_index)) + gpu_index = faiss.index_cpu_to_gpu(res, 0, deserialized_index) Dnew2, Inew2 = gpu_index.search(ds.get_queries(), k) From 3d32330e3d00f6f89d3680f44c86cc4ec602a105 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Wed, 12 Jun 2024 19:19:23 -0700 Subject: [PATCH 199/206] add use_raft to knn_gpu (torch) (#3509) Summary: Add support for `use_raft` in the torch version of `knn_gpu`. The numpy version already has this support, see https://github.com/facebookresearch/faiss/blob/main/faiss/python/gpu_wrappers.py#L59 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3509 Reviewed By: mlomeli1, junjieqi Differential Revision: D58489851 Pulled By: algoriddle fbshipit-source-id: cfad722fefd4809b135b765d0d43587cfd782d0e --- contrib/torch_utils.py | 4 +++- faiss/gpu/test/torch_test_contrib_gpu.py | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/contrib/torch_utils.py b/contrib/torch_utils.py index e371932c9f..18f136e914 100644 --- a/contrib/torch_utils.py +++ b/contrib/torch_utils.py @@ -492,8 +492,9 @@ def torch_replacement_sa_decode(self, codes, x=None): if issubclass(the_class, faiss.Index): handle_torch_Index(the_class) + # allows torch tensor usage with bfKnn -def torch_replacement_knn_gpu(res, xq, xb, k, D=None, I=None, metric=faiss.METRIC_L2, device=-1): +def torch_replacement_knn_gpu(res, xq, xb, k, D=None, I=None, metric=faiss.METRIC_L2, device=-1, use_raft=False): if type(xb) is np.ndarray: # Forward to faiss __init__.py base method return faiss.knn_gpu_numpy(res, xq, xb, k, D, I, metric, device) @@ -574,6 +575,7 @@ def torch_replacement_knn_gpu(res, xq, xb, k, D=None, I=None, metric=faiss.METRI args.outIndices = I_ptr args.outIndicesType = I_type args.device = device + args.use_raft = use_raft with using_stream(res): faiss.bfKnn(res, args) diff --git a/faiss/gpu/test/torch_test_contrib_gpu.py b/faiss/gpu/test/torch_test_contrib_gpu.py index 0c949c29f2..f7444337f1 100644 --- a/faiss/gpu/test/torch_test_contrib_gpu.py +++ b/faiss/gpu/test/torch_test_contrib_gpu.py @@ -249,7 +249,7 @@ def test_sa_encode_decode(self): return class TestTorchUtilsKnnGpu(unittest.TestCase): - def test_knn_gpu(self): + def test_knn_gpu(self, use_raft=False): torch.manual_seed(10) d = 32 nb = 1024 @@ -286,7 +286,7 @@ def test_knn_gpu(self): else: xb_c = xb_np - D, I = faiss.knn_gpu(res, xq_c, xb_c, k) + D, I = faiss.knn_gpu(res, xq_c, xb_c, k, use_raft=use_raft) self.assertTrue(torch.equal(torch.from_numpy(I), gt_I)) self.assertLess((torch.from_numpy(D) - gt_D).abs().max(), 1e-4) @@ -312,7 +312,7 @@ def test_knn_gpu(self): xb_c = to_column_major_torch(xb) assert not xb_c.is_contiguous() - D, I = faiss.knn_gpu(res, xq_c, xb_c, k) + D, I = faiss.knn_gpu(res, xq_c, xb_c, k, use_raft=use_raft) self.assertTrue(torch.equal(I.cpu(), gt_I)) self.assertLess((D.cpu() - gt_D).abs().max(), 1e-4) @@ -320,7 +320,7 @@ def test_knn_gpu(self): # test on subset try: # This internally uses the current pytorch stream - D, I = faiss.knn_gpu(res, xq_c[6:8], xb_c, k) + D, I = faiss.knn_gpu(res, xq_c[6:8], xb_c, k, use_raft=use_raft) except TypeError: if not xq_row_major: # then it is expected @@ -331,7 +331,13 @@ def test_knn_gpu(self): self.assertTrue(torch.equal(I.cpu(), gt_I[6:8])) self.assertLess((D.cpu() - gt_D[6:8]).abs().max(), 1e-4) - def test_knn_gpu_datatypes(self): + @unittest.skipUnless( + "RAFT" in faiss.get_compile_options(), + "only if RAFT is compiled in") + def test_knn_gpu_raft(self): + self.test_knn_gpu(use_raft=True) + + def test_knn_gpu_datatypes(self, use_raft=False): torch.manual_seed(10) d = 10 nb = 1024 @@ -354,7 +360,7 @@ def test_knn_gpu_datatypes(self): D = torch.zeros(nq, k, device=xb_c.device, dtype=torch.float32) I = torch.zeros(nq, k, device=xb_c.device, dtype=torch.int32) - faiss.knn_gpu(res, xq_c, xb_c, k, D, I) + faiss.knn_gpu(res, xq_c, xb_c, k, D, I, use_raft=use_raft) self.assertTrue(torch.equal(I.long().cpu(), gt_I)) self.assertLess((D.float().cpu() - gt_D).abs().max(), 1.5e-3) @@ -366,7 +372,7 @@ def test_knn_gpu_datatypes(self): xb_c = xb.half().numpy() xq_c = xq.half().numpy() - faiss.knn_gpu(res, xq_c, xb_c, k, D, I) + faiss.knn_gpu(res, xq_c, xb_c, k, D, I, use_raft=use_raft) self.assertTrue(torch.equal(torch.from_numpy(I).long(), gt_I)) self.assertLess((torch.from_numpy(D) - gt_D).abs().max(), 1.5e-3) From d45f78b1e14867086faebeb1d3b7bedbc79c644b Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 13 Jun 2024 08:14:38 -0700 Subject: [PATCH 200/206] Add conda bin to path early in the cmake GitHub action (#3512) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3512 Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3510 GitHub hosted runners some with the build-essentials package pre-installed, self-hosted runners on AWS do not have this package. This made it all steps other than the `all targets` one fall back to the system executables which unintentially worked on GitHub hosted runners but not on the self-hosted ones. This diff fixes it by pulling the line that adds conda bin to path early in the cmake build action. Reviewed By: asadoughi Differential Revision: D58513853 fbshipit-source-id: 23e95459e0031c96bd142515db07d1b700d713cf --- .github/actions/build_cmake/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index cd023aaca7..6e21f785ea 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -30,6 +30,7 @@ runs: run: | conda install -y -q -c conda-forge gxx_linux-64=11.2 sysroot_linux-64=2.28 conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest + echo "$CONDA/bin" >> $GITHUB_PATH - name: Install CUDA if: inputs.gpu == 'ON' && inputs.raft == 'OFF' shell: bash @@ -72,7 +73,6 @@ runs: shell: bash run: | conda install -y pytest - echo "$CONDA/bin" >> $GITHUB_PATH - name: Python tests (CPU only) if: inputs.gpu == 'OFF' shell: bash From 34feae48d47ca0e8d097d3672168675d903584c3 Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Thu, 13 Jun 2024 13:31:34 -0700 Subject: [PATCH 201/206] typo in test_io_no_storage (#3515) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3515 Fix typo `test_io_no_storage` Reviewed By: kuarora, asadoughi Differential Revision: D58540190 fbshipit-source-id: b8b9cacd7ea6005c0edb94014de74188450318c1 --- tests/test_graph_based.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py index 95925d7ae9..c769e03ade 100644 --- a/tests/test_graph_based.py +++ b/tests/test_graph_based.py @@ -144,7 +144,7 @@ def test_io_no_storage(self): index2 = faiss.deserialize_index( faiss.serialize_index(index, faiss.IO_FLAG_SKIP_STORAGE) ) - self.assertEquals(index2.storage, None) + self.assertEqual(index2.storage, None) self.assertRaises( RuntimeError, index2.search, self.xb, 1) From 44d21eedb623fa0ef244e86b6fa38fb27b771aa5 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Thu, 13 Jun 2024 22:30:28 -0700 Subject: [PATCH 202/206] Consolidate build environment configuration steps in cmake builds (#3516) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3516 This diff seeks to simplify the steps that install conda packages and environment configuration into a single step at the start of the cmake build action. Reviewed By: mnorris11 Differential Revision: D58560454 fbshipit-source-id: ee2c6b36865809f31eb335cfb3c2fffdccaa318d --- .github/actions/build_cmake/action.yml | 44 ++++++++++++++------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index 6e21f785ea..2bc476add5 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -20,27 +20,35 @@ runs: with: python-version: '3.11' miniconda-version: latest - - name: Initialize Conda environment + - name: Configure build environment shell: bash run: | + # initialize Conda conda config --set solver libmamba conda update -y -q conda - - name: Configure Conda environment - shell: bash - run: | + echo "$CONDA/bin" >> $GITHUB_PATH + + # install base packages conda install -y -q -c conda-forge gxx_linux-64=11.2 sysroot_linux-64=2.28 conda install -y -q python=3.11 cmake make swig mkl=2023 mkl-devel=2023 numpy scipy pytest - echo "$CONDA/bin" >> $GITHUB_PATH - - name: Install CUDA - if: inputs.gpu == 'ON' && inputs.raft == 'OFF' - shell: bash - run: | - conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" - - name: Install RAFT - if: inputs.raft == 'ON' - shell: bash - run: | - conda install -y -q libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + + # install CUDA packages + if [ "${{ inputs.gpu }}" = "ON" ] && [ "${{ inputs.raft }}" = "OFF" ]; then + conda install -y -q cuda-toolkit -c "nvidia/label/cuda-11.8.0" + fi + + # install RAFT packages + if [ "${{ inputs.raft }}" = "ON" ]; then + conda install -y -q libraft cuda-version=11.8 cuda-toolkit -c rapidsai-nightly -c "nvidia/label/cuda-11.8.0" -c conda-forge + fi + + # install test packages + conda install -y pytest + if [ "${{ inputs.gpu }}" = "ON" ]; then + conda install -y -q pytorch pytorch-cuda=11.8 -c pytorch -c nvidia/label/cuda-11.8.0 + else + conda install -y -q pytorch -c pytorch + fi - name: Build all targets shell: bash run: | @@ -69,22 +77,16 @@ runs: working-directory: build/faiss/python run: | $CONDA/bin/python setup.py install - - name: Install pytest - shell: bash - run: | - conda install -y pytest - name: Python tests (CPU only) if: inputs.gpu == 'OFF' shell: bash run: | - conda install -y -q pytorch -c pytorch pytest --junitxml=test-results/pytest/results.xml tests/test_*.py pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py - name: Python tests (CPU + GPU) if: inputs.gpu == 'ON' shell: bash run: | - conda install -y -q pytorch pytorch-cuda=11.8 -c pytorch -c nvidia/label/cuda-11.8.0 pytest --junitxml=test-results/pytest/results.xml tests/test_*.py pytest --junitxml=test-results/pytest/results-torch.xml tests/torch_*.py cp tests/common_faiss_tests.py faiss/gpu/test From e65a910eb47e93e796a4fb8f1dd70a6a0a11136c Mon Sep 17 00:00:00 2001 From: Gergely Szilvasy Date: Fri, 14 Jun 2024 13:00:05 -0700 Subject: [PATCH 203/206] fix Windows build - signed int OMP for MSVC (#3517) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3517 MSVC doesn't support unsigned int for OMP Reviewed By: kuarora, junjieqi, ramilbakhshyiev Differential Revision: D58591594 fbshipit-source-id: ac7d6b37a82f9543be3e0fe418f0f6b439751475 --- faiss/IndexHNSW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/faiss/IndexHNSW.cpp b/faiss/IndexHNSW.cpp index fd80b87df7..8e5c654f04 100644 --- a/faiss/IndexHNSW.cpp +++ b/faiss/IndexHNSW.cpp @@ -468,7 +468,7 @@ void IndexHNSW::search_level_0( if (is_similarity_metric(this->metric_type)) { // we need to revert the negated distances #pragma omp parallel for - for (size_t i = 0; i < k * n; i++) { + for (int64_t i = 0; i < k * n; i++) { distances[i] = -distances[i]; } } From 849557a38a4acd87f18e62fa9e538b151964d582 Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 17 Jun 2024 01:40:32 -0700 Subject: [PATCH 204/206] Unbreak RAFT conda builds (#3519) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3519 Fixing the conda conflicts because of `_openmp_mutex` build versions. This change pins that version for RAFT conda package builds. Reviewed By: algoriddle Differential Revision: D58646659 fbshipit-source-id: 4c1eaa9f08bd354da016b9399a36698007a497d8 --- conda/faiss-gpu-raft/meta.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 23e4835032..9a5fd542f1 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -50,14 +50,18 @@ outputs: - llvm-openmp # [osx] - cmake >=3.24.0 - make # [not win] + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] + - mkl =2023 # [x86_64] - mkl-devel =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} host: + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] - mkl =2023 # [x86_64] - openblas # [not x86_64] - libraft =24.04 - cuda-version {{ cuda_constraints }} run: + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] - mkl =2023 # [x86_64] - openblas # [not x86_64] - cuda-cudart {{ cuda_constraints }} @@ -87,12 +91,16 @@ outputs: - swig - cmake >=3.24.0 - make # [not win] + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] + - mkl =2023 # [x86_64] - cuda-toolkit {{ cudatoolkit }} host: + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] - python {{ python }} - numpy >=1.19,<2 - {{ pin_subpackage('libfaiss', exact=True) }} run: + - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] - python {{ python }} - numpy >=1.19,<2 - packaging From e188eb381026a25b8817e3846c9ce53710f8947a Mon Sep 17 00:00:00 2001 From: Ramil Bakhshyiev Date: Mon, 17 Jun 2024 17:59:13 -0700 Subject: [PATCH 205/206] Bump libraft to 24.06 to unblock nightly RAFT builds (#3522) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3522 Quick fix to unblock nightly Reviewed By: mlomeli1 Differential Revision: D58694193 fbshipit-source-id: ea323991cc2e2b958fc11ab614dcd6e09d4c072c --- conda/faiss-gpu-raft/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/faiss-gpu-raft/meta.yaml b/conda/faiss-gpu-raft/meta.yaml index 9a5fd542f1..1dde8e9868 100644 --- a/conda/faiss-gpu-raft/meta.yaml +++ b/conda/faiss-gpu-raft/meta.yaml @@ -58,7 +58,7 @@ outputs: - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] - mkl =2023 # [x86_64] - openblas # [not x86_64] - - libraft =24.04 + - libraft =24.06 - cuda-version {{ cuda_constraints }} run: - _openmp_mutex =4.5=2_kmp_llvm # [x86_64] @@ -66,7 +66,7 @@ outputs: - openblas # [not x86_64] - cuda-cudart {{ cuda_constraints }} - libcublas {{ libcublas_constraints }} - - libraft =24.04 + - libraft =24.06 - cuda-version {{ cuda_constraints }} test: requires: From e758973fa08164728eb9e136631fe6c57d7edf6c Mon Sep 17 00:00:00 2001 From: Matthijs Douze Date: Tue, 18 Jun 2024 03:13:51 -0700 Subject: [PATCH 206/206] Add ABS_INNER_PRODUCT metric (#3524) Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3524 Searches with the metric abs(dot(query, database)) This makes it possible to search vectors that are closest to a hyperplane * adds support for alternative metrics in faiss.knn in python * checks that it works with HNSW * simplifies the extra distances interface by removing the template on Reviewed By: asadoughi Differential Revision: D58695971 fbshipit-source-id: 2a0ff49c7f7ac2c005d85f141cc5de148081c9c4 --- faiss/IndexFlat.cpp | 18 ++++++---- faiss/MetricType.h | 8 +++-- faiss/python/extra_wrappers.py | 12 +++++-- faiss/utils/extra_distances-inl.h | 12 +++++++ faiss/utils/extra_distances.cpp | 55 +++++++++++-------------------- faiss/utils/extra_distances.h | 5 +-- tests/test_extra_distances.py | 7 ++++ tests/test_graph_based.py | 15 +++++++++ 8 files changed, 82 insertions(+), 50 deletions(-) diff --git a/faiss/IndexFlat.cpp b/faiss/IndexFlat.cpp index f606f8e621..7d29ca5387 100644 --- a/faiss/IndexFlat.cpp +++ b/faiss/IndexFlat.cpp @@ -41,15 +41,19 @@ void IndexFlat::search( } else if (metric_type == METRIC_L2) { float_maxheap_array_t res = {size_t(n), size_t(k), labels, distances}; knn_L2sqr(x, get_xb(), d, n, ntotal, &res, nullptr, sel); - } else if (is_similarity_metric(metric_type)) { - float_minheap_array_t res = {size_t(n), size_t(k), labels, distances}; - knn_extra_metrics( - x, get_xb(), d, n, ntotal, metric_type, metric_arg, &res); } else { - FAISS_THROW_IF_NOT(!sel); - float_maxheap_array_t res = {size_t(n), size_t(k), labels, distances}; + FAISS_THROW_IF_NOT(!sel); // TODO implement with selector knn_extra_metrics( - x, get_xb(), d, n, ntotal, metric_type, metric_arg, &res); + x, + get_xb(), + d, + n, + ntotal, + metric_type, + metric_arg, + k, + distances, + labels); } } diff --git a/faiss/MetricType.h b/faiss/MetricType.h index 4689d4d018..8e889b1a03 100644 --- a/faiss/MetricType.h +++ b/faiss/MetricType.h @@ -31,9 +31,13 @@ enum MetricType { METRIC_Canberra = 20, METRIC_BrayCurtis, METRIC_JensenShannon, - METRIC_Jaccard, ///< defined as: sum_i(min(a_i, b_i)) / sum_i(max(a_i, b_i)) - ///< where a_i, b_i > 0 + + /// sum_i(min(a_i, b_i)) / sum_i(max(a_i, b_i)) where a_i, b_i > 0 + METRIC_Jaccard, + /// Squared Eucliden distance, ignoring NaNs METRIC_NaNEuclidean, + /// abs(x | y): the distance to a hyperplane + METRIC_ABS_INNER_PRODUCT, }; /// all vector indices are this type diff --git a/faiss/python/extra_wrappers.py b/faiss/python/extra_wrappers.py index d7fd05bc9f..a037b0280f 100644 --- a/faiss/python/extra_wrappers.py +++ b/faiss/python/extra_wrappers.py @@ -330,7 +330,7 @@ def lookup(self, keys): # KNN function ###################################################### -def knn(xq, xb, k, metric=METRIC_L2): +def knn(xq, xb, k, metric=METRIC_L2, metric_arg=0.0): """ Compute the k nearest neighbors of a vector without constructing an index @@ -374,10 +374,16 @@ def knn(xq, xb, k, metric=METRIC_L2): swig_ptr(xq), swig_ptr(xb), d, nq, nb, k, swig_ptr(D), swig_ptr(I) ) - else: - raise NotImplementedError("only L2 and INNER_PRODUCT are supported") + else: + knn_extra_metrics( + swig_ptr(xq), swig_ptr(xb), + d, nq, nb, metric, metric_arg, k, + swig_ptr(D), swig_ptr(I) + ) + return D, I + def knn_hamming(xq, xb, k, variant="hc"): """ Compute the k nearest neighbors of a set of vectors without constructing an index. diff --git a/faiss/utils/extra_distances-inl.h b/faiss/utils/extra_distances-inl.h index 5b21482d18..3171580f8c 100644 --- a/faiss/utils/extra_distances-inl.h +++ b/faiss/utils/extra_distances-inl.h @@ -150,4 +150,16 @@ inline float VectorDistance::operator()( } return float(d) / float(present) * accu; } + +template <> +inline float VectorDistance::operator()( + const float* x, + const float* y) const { + float accu = 0; + for (size_t i = 0; i < d; i++) { + accu += fabs(x[i] * y[i]); + } + return accu; +} + } // namespace faiss diff --git a/faiss/utils/extra_distances.cpp b/faiss/utils/extra_distances.cpp index fb225e7c9e..407057e58e 100644 --- a/faiss/utils/extra_distances.cpp +++ b/faiss/utils/extra_distances.cpp @@ -50,16 +50,18 @@ void pairwise_extra_distances_template( } } -template +template void knn_extra_metrics_template( VD vd, const float* x, const float* y, size_t nx, size_t ny, - HeapArray* res) { - size_t k = res->k; + size_t k, + float* distances, + int64_t* labels) { size_t d = vd.d; + using C = typename VD::C; size_t check_period = InterruptCallback::get_period_hint(ny * d); check_period *= omp_get_max_threads(); @@ -71,18 +73,15 @@ void knn_extra_metrics_template( const float* x_i = x + i * d; const float* y_j = y; size_t j; - float* simi = res->get_val(i); - int64_t* idxi = res->get_ids(i); + float* simi = distances + k * i; + int64_t* idxi = labels + k * i; // maxheap_heapify(k, simi, idxi); heap_heapify(k, simi, idxi); for (j = 0; j < ny; j++) { float disij = vd(x_i, y_j); - // if (disij < simi[0]) { - if ((!vd.is_similarity && (disij < simi[0])) || - (vd.is_similarity && (disij > simi[0]))) { - // maxheap_replace_top(k, simi, idxi, disij, j); + if (C::cmp(simi[0], disij)) { heap_replace_top(k, simi, idxi, disij, j); } y_j += d; @@ -165,13 +164,13 @@ void pairwise_extra_distances( HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); HANDLE_VAR(NaNEuclidean); + HANDLE_VAR(ABS_INNER_PRODUCT); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); } } -template void knn_extra_metrics( const float* x, const float* y, @@ -180,13 +179,15 @@ void knn_extra_metrics( size_t ny, MetricType mt, float metric_arg, - HeapArray* res) { + size_t k, + float* distances, + int64_t* indexes) { switch (mt) { -#define HANDLE_VAR(kw) \ - case METRIC_##kw: { \ - VectorDistance vd = {(size_t)d, metric_arg}; \ - knn_extra_metrics_template(vd, x, y, nx, ny, res); \ - break; \ +#define HANDLE_VAR(kw) \ + case METRIC_##kw: { \ + VectorDistance vd = {(size_t)d, metric_arg}; \ + knn_extra_metrics_template(vd, x, y, nx, ny, k, distances, indexes); \ + break; \ } HANDLE_VAR(L2); HANDLE_VAR(L1); @@ -197,32 +198,13 @@ void knn_extra_metrics( HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); HANDLE_VAR(NaNEuclidean); + HANDLE_VAR(ABS_INNER_PRODUCT); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); } } -template void knn_extra_metrics>( - const float* x, - const float* y, - size_t d, - size_t nx, - size_t ny, - MetricType mt, - float metric_arg, - HeapArray>* res); - -template void knn_extra_metrics>( - const float* x, - const float* y, - size_t d, - size_t nx, - size_t ny, - MetricType mt, - float metric_arg, - HeapArray>* res); - FlatCodesDistanceComputer* get_extra_distance_computer( size_t d, MetricType mt, @@ -245,6 +227,7 @@ FlatCodesDistanceComputer* get_extra_distance_computer( HANDLE_VAR(Lp); HANDLE_VAR(Jaccard); HANDLE_VAR(NaNEuclidean); + HANDLE_VAR(ABS_INNER_PRODUCT); #undef HANDLE_VAR default: FAISS_THROW_MSG("metric type not implemented"); diff --git a/faiss/utils/extra_distances.h b/faiss/utils/extra_distances.h index 79b65bc1e9..f8b47cfba5 100644 --- a/faiss/utils/extra_distances.h +++ b/faiss/utils/extra_distances.h @@ -33,7 +33,6 @@ void pairwise_extra_distances( int64_t ldb = -1, int64_t ldd = -1); -template void knn_extra_metrics( const float* x, const float* y, @@ -42,7 +41,9 @@ void knn_extra_metrics( size_t ny, MetricType mt, float metric_arg, - HeapArray* res); + size_t k, + float* distances, + int64_t* indexes); /** get a DistanceComputer that refers to this type of distance and * indexes a flat array of size nb */ diff --git a/tests/test_extra_distances.py b/tests/test_extra_distances.py index 66318f76c5..fcaf4d383d 100644 --- a/tests/test_extra_distances.py +++ b/tests/test_extra_distances.py @@ -114,6 +114,13 @@ def test_nan_euclidean(self): new_dis = faiss.pairwise_distances(x, q, faiss.METRIC_NaNEuclidean) self.assertTrue(np.isnan(new_dis[0])) + def test_abs_inner_product(self): + xq, yb = self.make_example() + dis = faiss.pairwise_distances(xq, yb, faiss.METRIC_ABS_INNER_PRODUCT) + + gt_dis = np.abs(xq @ yb.T) + np.testing.assert_allclose(dis, gt_dis, atol=1e-5) + class TestKNN(unittest.TestCase): """ test that the knn search gives the same as distance matrix + argmin """ diff --git a/tests/test_graph_based.py b/tests/test_graph_based.py index c769e03ade..d5797186da 100644 --- a/tests/test_graph_based.py +++ b/tests/test_graph_based.py @@ -169,6 +169,21 @@ def test_io_no_storage(self): ) self.assertEquals(index3.storage, None) + def test_abs_inner_product(self): + """Test HNSW with abs inner product (not a real distance, so dubious that triangular inequality works)""" + d = self.xq.shape[1] + xb = self.xb - self.xb.mean(axis=0) # need to be centered to give interesting directions + xq = self.xq - self.xq.mean(axis=0) + Dref, Iref = faiss.knn(xq, xb, 10, faiss.METRIC_ABS_INNER_PRODUCT) + + index = faiss.IndexHNSWFlat(d, 32, faiss.METRIC_ABS_INNER_PRODUCT) + index.add(xb) + Dnew, Inew = index.search(xq, 10) + + inter = faiss.eval_intersection(Iref, Inew) + # 4769 vs. 500*10 + self.assertGreater(inter, Iref.size * 0.9) + class TestNSG(unittest.TestCase):

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�ZN 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 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 deleted file mode 100644 index bcd8804df55f5811d9f1a1d856440151addad8e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138612 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�ZN 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 b/demos/offline_ivf/tests/test_data/goku_lang/IVF256_PQ4.shard_0 new file mode 100644 index 0000000000000000000000000000000000000000..bcd8804df55f5811d9f1a1d856440151addad8e3 GIT binary patch literal 138612 zcmZU*Wms0-)&>eFC?O%GNC_B#(jf7y`=+~7Qm_>S43tt)6cxJ#6}$VjL2SVWyIX8g zU+g?+Hi126N3CF=NyuXiQ{OTRAy7&2Hka|NGJW|3G>9{}li4*Z<g7W&k$Vz5nykbX!w6~SyS=WODtOuPI<&oQKbaB^TMgR!2wfdR=_#R7aH4BG5==?Hq|-J-G~H1zVO@PD8J|fq2@lH3l20a^hJZs{EOYV0%UGbl2pA zv9TC>pA1>P61V&NvCmr*IH>H#9j&Q2eAwYwwvt6VG|Yjyt+Lvr-rc24SRfxm<`1}lkjgxCnhDgW5IzCc9(yQ+C#H2>gyet zy=%?zy_x7gN}iV6{1|jRf)|VInZCOSQyXG2%Pxl728K{)wjX{kn1cXAPwH%Tz_3$x ztbRKO`!p6o@b`z$+jO`L)S*Lm5&CvdV7u5Hl;01hLhlW*n|l*61#whv_U0CwIaqYg z4gPCqU~51C4SFs?B#s#7P6%S@Wad#8}IjKOX?BaGWB5n!DP-qc^9w7STiEV906y#;YP9rM)~+s z;jJgXjmyMo&9Zhi6mIBPK2*rDLh}haiXjTGZD@{9}Ic0JQEYD z!gwJ*g7Hz)@G>BVbAMJ~!<0ZiKjwjxBU%vs-U?fMvQc87%mXQAxVJWm#|#tkN~s59 z-uK3UMQ%)g)E%dKuEuCTM?PNhFY3<)bF8g4o2K;Os(vzF93M%yu1dThn~aZ->QE+2 zCGJFXkcPmq9!H_rBbY`WepF2kWzqgq7(cfk{!BW8im?Gq_q+?UmL$Y3_vPB9y`X>F zj3G-`VooS&`zwiKwES2)DFluoIf%^|fe}W5Y(D1C>`(L2y26@!hI!M^$N{Tcb*10f ze2gfUF>rVzI^PK7Hz5_z@?`WpH<&xRhEPL0fm&{MH2E3J@YxeEQq_}>i-+J^1&7k3e+1Wr^@Q034c;GTi4&#)++gB`*HwXd(@~#? z;=DOHN*SX}!kD#n8*0)zaIX0l)G1`bdX7Jveh$a0IsagLj{EG$$ye#& zygEXKYn`LH-R(4HX4RnoybK=fcpMdT)2ZCm6bAYcoO?J91BO}B)F2ysHpSrAcx!HC zf7lg8u(YWhH~+*SbYmS1s$b#dLoY7g_8z;Uv?yrxfOoJJhWw7AK~n&&6$jwf#dMUH z`>^Y-!|2xHz{8#~jJy^>mHi$FFAC!6ONB5|_QLHdH5N2PvvKhZ?9no$rLz-`@9<{g zc_*svS^`Jk2{?P+izb@$5EK%~kGuV8Cq`9g$E}ZO0+57~`_Xwj=_7RwT zd5g^tU6{T%gie=0uh|<>J~9*Ue}?mI-}&eQJ2r%e@|{Hxza~d=wQDl=UyJ0;W=-B+ zF2_qQVRTVW;LO2MblmE}*oU6X+?T|c>YH(+WD5Q{>p(T> zvhh+3?j4JSQIQsP3LoKgt5|NY>_X>b^)N4Y!Jvm>v`h-8n<%pjze@)?>u$ zDEw#@!GHBVnPRMhW#V~b+&+jYlOj3zd^BeLih=g8E^OD3jV@z

M$6=T^F!78pyQ`?iY-^jf1ktH3#mP1Ga-#ao2QE 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_1 new file mode 100644 index 0000000000000000000000000000000000000000..f229716ab9d41f2f67fc5bc95d2f0ea1f8b45253 GIT binary patch literal 138612 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 A`(e5eujTw%~pVWkYJFa2F@DK0} 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 literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 b/demos/offline_ivf/tests/test_data/coco_lang/IVF256_PQ4.shard_2 new file mode 100644 index 0000000000000000000000000000000000000000..28aabd44c7fc0cb2a1a506305acde7a19b257b48 GIT binary patch literal 138612 zcmZU*bzE0X^9BqkC?O%CA|;^$N;ltgU37O!3bulPfl?}pVt0ay-F@34wxAebcZ)6R zjh*j#evjwC#Ts>{Pll7n*SdvFaMw7|NZ)Z ziCl0&fWv<}N%dm)|CGd^|I+_<`o9)(a&`)2yyZaH>I5=$n=$VHR%B2>4=S%t=gVj{ zYJK--!>$nK-f-mi+-w-DZGqxvFB*Czvy<^kTrr4b_F^mU$@FGpvoXfLEkoB|jtJT7 z!tJlYYv(+eIz5i-QeUg)6q4>=(j}HpeioF@ck> zMl$n^E`^gZIBsCeS(_~py)zxZeg$Gy4=egyievq%;b2lfg!U;#%iIKNotuXb2kkL_ z=q)Ua8iGmTR@_}R7N?HPf%0Krw(OaSEw@uy7#Pn=+evVajpX^*N<6TR!jrR8k>0;Q zUZfp{-l_5U)ykTRw_ak|f(XhZmWnE+(47}S)eR1qJhKAM(SFd_o`(59OR=fOnRAL{ z*ep-p`WnXNt≫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 z zs2-NZ?(*gwulK?gJ#EH2OcSDwi`Zq|V-$Yt$()x9WRDx>;%-B&%*ksl4nAKev_xnK zUbB`8Hv4pt-S(t#J);fJtXLu|>|TSwLKh)@NCC?WNATtoXPo`5E_jy=q;q`_#@B|? z_jwYNnn%&m%$gY6pXD+AsWo?ih|mO3ub(U1%B3^ev@hj<#InmuABL{ZqUFUbDwvF9 z@j6AGOdLgnv+4Y&x{&YAThY;_nC=s0e5O)JpXYj1ame9^cVQfzP)L{E9k_97F^9M~ zi5CA#3^h~X!e@gZ?C!(qEsyYOY-g&Z48)zh9(?$6GBS)?b8)2;w%?869;ZimQmM#+ z%M{_&>K$(Mj={cHJK;4v2m61@qh*pgmX8x7gD&BSjd_KdppHQ7MJ%KbJ|^U$(0Zp} z7(5G$=j)=tB!r{S$n(b;bC!IRW06l9*Ss{K+agaIPWEQmjzIdvIdWU2BiF34;kh-j zywu*32Wl<3c9V=hlkUK_*LMs&`Vc?m)cI%mC@vO}1f4B%y!$SO-KT1BWM%-D%=&;n zYg}o1Oq*t|3H(=0ovr)zTKe#Hz;@xHc0a0_ zbb?YFD;^y%OL!Gr$lt?*G0rlX^PQi|1{rRWwGJ(y{`!w_9vC3xJgAhF&s0QhbERO? z_(50?L*A}=Bioq#02(8=$X565E(E`uE;F6FM!05P#NeHUJfon=wtCLYsmQ z?kQ#)#PRCn!Bo@DV$cLJE8vJR6YKj>-E|Z%^%Aof%DU3#Y7VbCjTY?ua#<>79}N0k zz?OX)xH)Ykdj)PqQ+i0E{brovwhO%_<5#(Pk;`!<(Jl#=9J@Ljhj+}=L zy-Zm3-5qMj2hrx>QFOiJ&d%9pI2Y#0#>!F*dZNjSURH4YlgUqA8qiBymAkD^2);=> z@VTuK0<-3$!=q%pnkFwS7ZLBqNu3bVKMe)XA0cGrZeiG{b1w*EA7KCWK`eRHp6gqik<)@XW)L~0Or32vbmC4Cb(h=e&%_y` zCHc84)f?k^V6`t=lt(b_*?Hvpc(ZlzRG91?%nj!bV}a<7U6vg}URD}It#0GV<%q2=+CK{8(I%dGe;rt2u(Rhc$U%?_PA;Eu-(;Moc*0fvej-MDoz3u(Mx?Up{*< z(z*&gAO943yR1RXExx}%<^&!T^-G3Gg{+!aS>;|s6bw0K6CRL1`tV&BEi785MrD;;c543w72R$Ki+&Ae->f1I*ZhMYpBD<dh_Xb;5==Q6d^)1>ejt zI?E~H#@7^v~Aka>+M2xo*vKDUPrMa_y_WCzJP}A5NITx5VNMH4S54O1NvIozFuEqSldY!t}&n|B~LOO9(t zwc(y&{aG^V2O2-fagA{gUP^bPf#n?6U}&4zccPe9G}?(}c&ht1y|S?jn5S^LFIuUAtLXb9d;-;9FSr2CB& z(S&V<(t;7pw(boln*i#Lcr0tuOyJQC8bXVU7mMURU}kC{x2<<$l7lO?C$|xL+Vu zjEgLLQr0Jt%Yv;rG22%}AxuT|Bc6}HdU2C$Aiu4;iT7g0*?!SR=(0GIUvi7lePcG? zZM=+a9rQWyg&td9wP2ALAz8A~hL?&|xh%z+uZ_g_*LECICXeQZp$icZoX=I~J`2GY zM{$$6j*!#4ka7P(nQc=T9@~bKL!!A>5F^)z22tp(%V)Nk43zc40&fo%^esgHgis!6 zv_$td(Y)8=u)z5tln=Opm6P4rnDHF7?fvNJaTI$u*wFssZzyMYGQcg1h3^jt-Zw{6 zZ;}sB-^pON!hGTUp#oMs=*Q}0Z+`!gLxoqO7k56DrI*sU@zw}BPl~2*^I&dGAHk!? z)llzQ#3Q-YLUnKs_aE{QZjC762ZgUPi!?C`7ucPxqs{3ldMQ?o%JlwfL(cBTmZPGl z>vKWqqngRE;zE{gF5rZn9fdyU64?Jwu<+*0EZMvdk1%n59xsIHQ|nGXEni%N-Q!|L zt9o*SS1}__>tkf2jH$Qw$qsFHqE(r>a8^s73X8VM#yo7#FS@I+%FLGf!}lRX&6kmN zGI($5%Byo1Kx-VheOC!R1u?SPJd`T}?8K;85lge2;5)8>mVdfXcY+%uzQi#2UJyr^ zhO&dU3k!$!<$cXqX3COj7+Jsr_6O0)ZUFndG2->gVqOR?N7qxs$zpZRa5ZPMx-F}- z9a$6NO6P!%931G*Pm|ney2+nsGPlDktC)R7iSWw>9MMO_cSKt&;ix== zKMvs21~dAr^{2_EuNbtVkdHc8@lIYouZvlV_jV>T1f=B;*ymF30kinhC$3(ZjBn<{XrkiiN&9?9-`6 zxMrrnycT=m=A#aDj6V!@YdaP_5m8w4&lqYHDQ0`!M&TQ6c-QIEZ}=Q!>@=f->Slzc zwV{60By_ZRg>n9qap1H(pY^?nCA-?P?Z+m35kBC=?Df#usY0Xr9Wdy82&K8|@aerA z?b9C!H|mb#%*0Ber~d@J=vggfzuJhb*WHisXH*G;mJJ*kqqwOFUeyP0% zM^&NUu4~vd;yrxB zf8oI`Q$A~+kCl1uh_SSS!`BKSbMz@p6YY`j<5gjFp&fg_n}Nf9Yq2sw8;OY`sx04x z3H{sfY1B1TU)ABKs+D-qL5)_?rxB^5#9O1RsT{gZ(7oeKrzj14jWuO(@q5|wFiq<1 zdM^tY`5Sfn6j1SNIJ2rmByQ(xB-N}Do`hs`0kh~Hu0!94ndth#lM#1HF>IbHIjb8w zT)2qe-tmYX{0UD6yu<22%3M+{&xd7=C`;IicM~6>SI%X$K4OEa&PLeT(?M8pd@jx$ zi-+RcHmEzR3`})}o=GCs6_;UXkTT8}&c~j&)-dQNW-T4869T5?;PHf~!nJwNa3FY< za5v%tw%_nX`Ls>gS5_y2&)XoEFc+&9{DFz+2RK53&Q?iiTK*V`>&)@O{~?;yhw^-@ zb(rUp&-+F{VE-rtrHrjoer+yACPrJ}-Z#ypC;l#XpBmNq%$FR)ST=dzK zIajp!`r%307ta)UY}FRp1Wy+{Y?_4cC5=MR@MhWYtx7PPtioTGqZ#j}C)#BZ9Nd1B zaOHhZ9PAdxf13)K>2_LZzgCW$+EmG$wB%Xjc3oCK`XOANzmpBzzaNUW`;pL~!(9)b z!hdgfe!MjSzSp!l-ozQ3&i#Us!Fr4nQOHk*+YmeZFmm**v1V2q8jl))2lFoDSo#6{ zl2_oGX*-~7b_14G**JSni94^&#F1a8up+V;U-k6q{q`2}#f-H{XFaju_8Z(zSca>C zxiFekk8iF|#RyOXJ{B**lG@oAyQLXjckaPn)fp&zEKk`$JNCM(#8Y4HVE7hgPJQdf zah4i%_pd=HLKFpXD z!|~?dG04&orw$b&^O7&UWRIcXD+lwNcTp8>!2Ji`;bd7l(r2__)EZq5{$7j0n|*LC zxi#;F2eLlKi5F6);-9DO+3#5-Q$`2S>bnb6Of`5`oQr$4G0%(9hpSBp z-TRECrN6MCKAwJ8%~_LUh8gOH%$FZPyPO^r{Pze}v0ZsuL>r$*c42Len6Y%xo!7^O z@XI~WykSe*K%!H}4ZBH7K#& zfdZ&pdW7qTlxZJUjY`vjc%k|)^z}V>aG@`APmO_=RtNrZ^`=&GFYcF{50AULw0hrx zvRy_TVcm#so=&{pWKMaraCXgk35T;y7`nlq$unKp@ID0Jm5e!Qe-mNM5@VeQ5H!s+~4L>*7ziUZ%# z`Q371+V=}M)7yowyDRWc{$A|a@eIqi+Hh^?N0jfJh05p4VY{$5ucaF@`edDOb8{(j zl?piIs1~!vl?kWToy3j?e-7)ZN!444SU%?l6oy67^tYCniDH1XUC&^1E|X`9!x(@6 zlhC?Ooe6uADQ}&@k-d|lm}kU+3C>*g*qN5SuVHPaIs1!Q{Oc`37!uW*=lBy3mkek1 z7grYEYljQDn*3-vfM&hjseJf=pm-g;@1{#9??CnsSPHqH0tfwcVW+G(p7P%fr}$3T zXQIc>b=DZ5U58IYI|y$1k1->$L6~;-1lA9(5zbs_#r%un7cCmw5Gi{lJn8iUQ>yBO z=6(w>q;r)pBS=IopN+%g&R*!0dQG--nH-PKyD4nB9D(f{_6etZwrBF~>G(Qy8aCE9 z$sXOT#)=|C%oC&L5tmx=Y(!rgy)59Fq;9zRBc1Yt2hqCAHQChR*M)s^V%R*|ujBgkA}-(L%^}?i==@HPTOtPI7g)Hj7*&i-y|e| z`&alnGXi_AyHIIyGL*v0@TcUEVEDp_A9|_^ts3p1cA8?eqAwfv{R>Z@Loyn?70NUF z^L{`X9BK@NL;GA&rx4F(%_}(ac)9R;@c@~7iFiJ2ih@nTA>l{7E}NByafJOy?z)>S zvpH@<=Uv(SP+GwAQ%2LttS3ixh^7j9@z286oYys$1H_EQJ%cjnBz~pi9Hhz%iwfB7 zgutQ`i)3M2f@$0)pB1-b#Jg5oxVa^i9)-QBsoS4J9BP1lnS8%KN&JE-OU!^YrN;a( zLfXG>^iK@J$+kUlwxUWF_s51tk#A%}cND_Cu{}z+S+hdT7~8bg!fMqYS&u*MxPD5w zu;uG2BrHuAt{e(t)wDAZ9^H`n?C}t+W+rgo6(8gm=m_11`3YwGc+E>=rY6MP$>Y z^(#br<#E7cSB~vo#2Xr|Sgl@#2aiTE@?0vf4pzX}jFIf>JAl`1vZy!51dG3CGF8l~ z)P6RCmaG3k^^*en-m+ru;zC|;^B7?lN^oS@5Nc&=2n{2P=yFaTnpYCIIk#E1{MZB8 z1KTlBVlw^f_9A@DF(Ix_NBA+X52N(w37cI<3-4@$u{}n#*IOC0b5L7BJx2?xC+G8* z?J9KYt0fe_SR<%?9?tf$s#G&OBJ0%oo^1W99A*vsAauB(AT(Dz#E-nute7~M4Uubv z_9iC0_M(7$+m7biKSKpaF#~UKgCFm9%HiddOZd^L7pG|laGPNkTiGe{-uxpNW?Do` zQ$Kz@ohOWX>dxgBMbvli&Bh!Jp?0gl8oj>!ePIv>#4dzaSRQTV68P&@F@sg>@#S%Q zUI{rNTk!8_HXV5cqgEnjFwq^ly%PCPYe)OkBZBgbJ{;5f4g9_vvqRZx4B0PZ z`qAsiwrCMX?9Sq`ZS!H%xr8}$wedbIk*@N45b$dVpLkZlxImy&)l*~*>nCPXZo+bh z9-R8^EvCVZm=gsz6HTG8cMeCzw8G9~7EC>&lDT!w0^!)KZ)iVg zuW-U4mD`;~pGJ2VrWI`z9yNNidSjDtzq}1QMA^ghw=3Pub1`<@ZK2nbRJ6-3;Gg$J zG*s>=6v*Vr+XeK_sTTHSPDb;&tvFz2#JJO=cID%q-SgV-scMEJH{kvDbP2$rKoY~xI`P<(tgVif-o`p*lY*Aye6=7cU= zj4kl)O(5^jB(%$~%XX-T@KMcRfp5ffgc`z=HC^eV>xy?B2eRk=W}(wlLv|4DE^FID zcI)Vb^aN9Wo?efWZ)0f?KOPocPRfiT3i;4+F#7(|r^>JOf>&`rzC1l2U(D~oO2rHw zb-n32y%wD({=)J6a&%I6V$a*IY$kAAx&1XTmdYw@{pv&d%E#WaZ7L5R#yTU8PYR zqIzFwy1xlYW$mzC%bi92RfM@0U*Vf|5>CXq@pBhz3}1Ctc6{t<_+L~Ma()&u;$06x z-$#dMRu;;}p3i1=httAhlk-^Las*XZ3pu3J2p?CevvSWqbjbAM%>5^1cT9H5Zt4u6 zqrE*x9qV_lx3+M>2dr%8XN4Hxks1!lh&c- zaTM#q#V=Mj#B%46tJo3NgWo&Y@r;QZi$=YN@faIE-Px6&My02R5$P0$rEdpu+$bITtM-A?g3b^$`cw6!7nha)K&QOj zm>loP(Zf|a)a<_Oz*7qZ+eY%IcqV>|c7rVWE0&6x&5PUkQO>axJ8#y*a*QRT-X&1~ z)iu2S&->BYfc17>?5zJmc-Cu&%>8*j-`3mnxlEIDN~)n*7R|xFpYcg}374`u6pDUe z$}$T+o2SOR^Y7yQnI3#~yA`Wk4FnFIjZQ1XOkaZ-svJIqA@xf1FZ1I3^-f%K=oz9d zOsH+*#4HiJzh3?dyK~zxd_ZTO+}M?imv(`&qavIK7xBgG7^Zw%jFtXL_!XGN2K>T2 zo!OWjYm5yVnKa*EPV;vUFl5wX#EaQh$MZj9>O50n{!!7dSdc8*w*?$s9tNMsJ1{yn zj(*}@;eX5==T1~1q|TQg3^I6Y=>??QJ;s9uD>_(o<7zRr=Ww4H!asZSxc6)bJCFf|G?M_p`6(Wo^w}c$9X?sHKYq)PSxZ0>M*qFCSqZ!S}YG2 z&wKeYq?wvhq5LPN?hIkyg9q`)*@+*HsL^3`A`MR*hP$OPe~EVAMlFHuHm(w`-QOjw z@GatA%Rc-#%mv+(3K4&J6pho2*{;+AqrV5jxGA2pJwZIz?;Pf*p2TeNYlizu9T@XW zS@6L&ygeu|YwAdjefnIOv+N^!it(}uGt+n~=dfVZY72a9&A4LU0G=FFiNom%49eG} z!XQV=YuKXS`wF3(cwR=Nlb3amBg1(jw*OAzrVGkk_H70BxzB~NNi37)oT%7Vp7##i zLf#=gD&1CP@huBMKKU`4jBMD-B%gZ4X&CpYBkR=L@z=p1PJNRtelheGFB&>?%(_T^ z5@P~}Lv*NA6GNsYFOTzPc9WZX)DBjv2p0U2gxV(2ZZi)7A>Z7)tKTG_gtULoH zhca35A(}H+9K+r*>(Ifg2}+~Oo_-uM zRtJ;XR>MP#bIs_{ml{JCqhrKVgili7Nf8eioSivb`qu(d&cJ~D>};vd=x-i@#b0Xo zm)icN)_)&=Je<}Y`X`a%! zQu|JSpG)#d`j_}f<4b&``AGXgT4zaKsh`A0l0(wJ^jxBnzNGm{^^%+tmH12JN$VoX zFY%G|E4BCfJ3pztq%Ub7{qH(S&!zcE?IeDZ-XyuC_7auGk@lCQ2Z>7ZN$cVCS3YUp z(mrzdTQ7|x^_Qr$uch^n`2H^+Np6X+G#_bPNq-&wj;HgNn*62Gx=H2#9be)rjW6j( zl1u6*jVskld?a}#D(wSlouzh?KK{4Aq;F~cB|cI+X?>-7iAwTH>n!O>l3${d{v~;& z_d%MswC>V#={=J8NpeW@@cpY-NiWj)dVlMsb(PKqiAv*2a!dTAb(H2MQAs}OJe0b zOMInul;o4vUy@TQOMH)Se*dJdKB&b@X`@9yAM>()8?>JIo%!du`SFBnO{F~^ojN{h z&7;;~io;Yi1ATY4Un;jIZ~oJh1}&#ebw6}h$iDGJ)nRwv()j8V5IQqv-$A&T;>x zZ{z<<_b2|B%Jup$_54c@CjGbk|Il>b(O5U`AHZ!QA|bM+LPbU-4Kf>KOGcTAL{?<) zQTEEpNJK*@lD)Ttva_@-y(x5L&De5G9vgE9zhoQuo~9hBzztTGU-7kp2%bYMkAAH z3&Q7fTN323BDfdXG$WG}$mA}2>Ou%E8!A6j^22~&X#rztUVmFKB#H~dnf15{UI$bVP zEK(?=h@;dXPT=pQkft@V{M{5QtD|n>(sy&6SCX>GQhYp7HfF|M&iR}18snWl?HIK* zQ%Q+KyxNjR=KD>P%QL)ncQ}1HjbBT9)cyiG(*`}!jdD%GY-Z4nALzyt zbfWgsw0E+M*-7(2*E)qzmrHO;Lxja1xf^Abg(_xH%rUImEa* zYUoT0)J0dU;2kJ{o1+SSVKH2R=keTNM#nl}JUT{|@aj)H?E1pn_wv3=M|RS| zs;(50lJ8~vhKb57Wr#TsS6Nq?{<}14xj`naSQTC-|A3}wDq*gOWns+dr2g$ur8iUY zIw|v?nPsS=8_O4e-*bKR^Vu7sSc*mNBA07NDoIbIdp^59UZh*$8+~}2OyPR7D3 zxa!^qqCtLRA;)(<=mrn&i2@WyN46jXx?&1b(V0#-2>-yp|8)pmAVUWvpb0wg5Eer= zJdgO0{c&VpjqFF@XLLXo_oM^&!~$JVLH1hE9X>$De_$Lk&cbu3AFjg;WG{!ivH;U? zM{=Mfx{!bl$gl1jp3;2hUejr|dSUCVo5>pIEPvuXyJzn_m&rb@S~Mhd ziDK_WvZW}l{2Y}n)Sn9McI#hWxtF-Ryzp~wQJEIc%Bq|B%0@X~x&CTUyU53IRl*+m zAltLJ1LVlo2bspe4(xjujKIEMN0xV?D)w6ex4sRT2_v&_@E5YGLspi^>NB!Bgj*jB z>)|XiGr@lLBeQGB#i{JQDAcCi_uR4z8HW z_XgGwUyI|BU`?}j(Xao`WLze6(%{1}`+r3ex>bAmZ@PBxk!aVnw)c!)+N)eIAh#VU z%%c{|SML$ez~T}9@?B>Mhjw42!iAL0n{oq;E&Pd$ODFF8UE#jp`uyqFFQ?ayKC(`D zG=>Bkmk8JYjhnO>`Qo}h5N|%|S~6#<|51hK9HV8lXAvJ+Y8dVBis(BB`a8q+{)=~w zcSeRG@FA?g{&peLOB#gND1~h6;1Ogii~U@~ekvj38?Y39g>R7k3GC-n*aq9Nue#^} zG4|8{zdeO~=zt0=LKlRQ^%Ka0%$bmRJ`6+l>eyFe?58mNWJ`G6^yt7L*lS1l`G?rk z7IZ_0ex?Y?aPxijNE9$Ts^*b}; z@Hju=dfezqcnDcVLw97Ai%fpPBHUt1?By|7054+JkFj@iFbFqT2D4AYjIUzG6xh4N zm@OM-YmM3FVy1PF8Z+GouVJ=FFk1!8mN+Evo_*-y^sM~sQga&N8!B>i%Z>FsxkR^x z3;lf-QUWJJ=8MBK$|;D$Vkb#=eXg7R{z=}~ypoic&iz8>Zc*?0h_P&+hT$lRjDCu` z=fg_*msYEl+0%(8BW`2{hsYEt|L?y5tWgp*pRZfap=a!Gz|PcTSB78#=KKpj#17Ts zZpvfs_Am|3VRu-N2QhZ$9Q=n|%CRfYFn@jAKY7eK9WrCiZm<>e^+0!D!vf4z0CQ!; zTzBh|H65{d7UFMFpF?`skM!~tsv&vvridnT{;1teM6W5WEytClu&3|f z<)#eMg8^MR4FUC($Nd%p?*`-q-JzYlu|6|ye#Lu)d^@l^z^pzl=ZfzmABoVBr)CYQ z4N9SRt7Ylb$R!oyGWhpbka@^)Db0k=C^b;N4f^Iwey|}d;_|op4sLRP@(cg_dkY82 z0vGtLy(=^@%T)LRuE49fPv0@qamJI^PSvh4{JzN68C3L|a75?-JEDK}d$N^JIqzms|wXtEXB zysp#$>96~syOF{d`<4wEuy2;?gxB^QR-gmT zFb7>Q`|te+tb`-b5FLp}_Bn7I9hmv=4x$Sepgp{W%)dbn?B`cVfez5415t1j)}j+n z(1{nY8W!N5a$>(-U<GHHWYY2kpv}?2`e&*gLiOKsWEdq7>JqEW9FAJb4?fkPa%Whv=xsJoyo^GJ3oBi z>^gm>tg~n5&!ab|x`Ly=pKjf1nX65v*)G=PFpB)}YNN$rp`&2uVQcZ1f%0Ur)PY!o zGefIeEhY8VUsuA^-)}d*c{Nlv(6OG!+R{9bH1w><;bGB=GR%sU(U-Nmuis#D-f+&Y{K-qtL4(qtKidvTef)aSD&3Nw4Ko?|WioJG#$L|rcN`SwS z*|06`{Gg-uV6rpg{YB>s&vu+FX`6S;#+T`my-+?Tpw@N#?u_vZtE?rQH!I%zxM46_crrg!tLdk^Byo+#;@7X2D|{XDiHik)7Dp~yEJa$%SCVF0W^ z?&R3XC-5Nd@*^mKK753F*ik9;<1Um$FBq|#qS#G$=#3tn!`;?|+wc>1(;qz{MNbUj zBxFNRB;j}TLlV7^hbvGM{m6!1=*JHjg6BZ4J)sw6=*0#cKtB?(%b|*Aemv41q4{vf zN-xpjdfTLugLNCzAAyc<@Apg!uL!=7eSdV@!6S6>j`5Wd{<&RCKMx3GS;XntT3xp) z_4;GIcyrF9QgJ}JobqOHn~Py++qYlTjL3=uj$+m-c<*}>Ge3wKe}G$<87F3u2K}%@ z-EaqrVpbfO4L5AVY|OAT7Vtb~6M)y=B-MHE)4qrDHx1*kl*DmuaX zkh@+#J=fom`=HPMJRL=;XPi^+^&3Rx$_5m68@Wv)-Z`f48`I3UJ3kQ{FN)m!AU8E` z&{^!~oLff0QeQq*IV&$ODqnbG=lmzqll8;0XKib_jXqkC7W*eQFfZO9z1G-iGD6`z z!E~`u?&`;P^|n8XeT<0Qo?%aVF>4vz!7tDrd(o&#=z{|Gq5+m-FBI_%o59`WLS}D} z*->Q1g#9>+JK70puqTh;C+x`)+|d-MgS|?gwl|C#bL|%rFPiqa&B#OLV0L&&0FXCuZ!=F?47Y3cfU6TTEF~nol(_w=FwB z{JMFI|3#@iv1+NI`Nih}V+Gr1$vv+Fw-ibX9PD$`DoFAK zyESw32K7 zvrwLqT@8V~6VElj<^*PWP}P|X9naBp%AzK%;%Nv><*QK`<})Ww^j(rj6%1@F%M3ff z65yxEnqDjGmVJTQaPk7vnb`;lj^|xOtR^w>Rr89L5-Qo2tnF<)YS!8OWg#^;U0;0D zt$bZaX<(h;-jacBg+us7cPxwT-2iLkp2P!wK=M%ZOz+~Xv?7s`UX$XykBVaJ=`VeIq?sEpk{j9#3D=I{u1 z`X-ErHt5H3^n)1po(8^#`_PZKPzn8b1X<9J5bX3AltW(@p$Gc%3(BH5a_Ef{hN0#~Y+|SB%x%8Ptc5KfNr?KaFYcX0kEOO?U zZ|<*os`WX~LW{+E_dhK%@lD;1eRlMMOq(u87<0K^@8?d)$zF~Z46fE9meXQ-MO3QA z=X9SgOXf!0L&l#>q>Rz*yToUm1=Lm@g=980#}0pDq^9N;eM<33r*(gEP+?r5VsozM|C;4?a7jBZ3gYTS7v zm<&rG2eQwCzma(?GS@)1CvX$oAu;YaBfNslgOGJ3ynxJq!p*ycn@57IzrZahiEQ6N zA}7MNW=R6kznQ(o^J0OEn+&URoNuBh z^iMw?+oX%Tjlro6%{1KcS>Dk{z8c)U#7vo`(Nvr)N&8lQ*~Fz)V<&oPR=Zybs_-?&Qc>6WYLR zLK?*xEs4phUfZ4$c#Sl!mF2VRf*SBXItcN_^wdDP*{1{8vmBG zIjESz|BG|ZV$7Ov^*2YM%ly2PQ_OF9XIXwuU!)Y7n)dS^znv2mTwSypZ1ZY5z1l}Y zkT>SDN_v*vi}oiu`O|GzA9hk?SwABcS6(c-`f|dbUin9Z?_^_}}UALmQ6z2ZeP=b%i}x3B2TbxF~`xVCB1&O>D$&N^;u5kNavYP1&FytAexoeu@ zV<1lvcFTwKn^i#fq}Soq*S1XwG=h^)8f<0)^Vw^>JE#tpsR@mLm~r!th%umC<+t(< z&JoIJ%y}S*tTd6;56G!O=prBNhVt0O5qJj~dO{K04}}>#!i|-Mr8j2oAf8yj@(3w2X?)tspkiIwU__gFup(h+?BpX$TZQ3>_ho4(`4>bi!F(%%E`lqf({42 z@49mSkF^ASyY)bBGLK5`A6|t*&q?Fqq%7V3ETU7nAFNHC-yrWbD1f}Zq1jbJ?mO63 zY2r z*xerFV2gRLf1#w@+g(Rg{E=ZYK8B8eZ(R%#b6YlrR%6D*YWJnn(xEk$?9nZL`+7np zPOdaKl|)7;N_HzcF?Bz6U|$R4IoozY;#?dl*~y`rEa@Z$7y9VKj4}znVh#xxqwUzwuvcbN!Je^~N6{&vg_utBlmmN@sYX!(`RRL~ zd@bWYhBC(YF*w^T`{^=$cR>+`2n@;9SM0zPJWAKt9+ z_M7#}6pl=545-{8TG|}ui7EF8r5@a>qfG3K_H#clo7MY)q-nU#`Xn+aXwfobpty5j}k zp(_J$3TmJ`e(26NJc3)1h7MWZBfOrk4g{y5*nQG5S*{rGPw%q|bC_oabFNW4%No}W z6Q9c3h&<6X9p_PJcaoWMF_YyRyWE3@>SwO6SD#9g|6Dc>zv0NVBs%ryWx>q#{923t zjOu09wy|YqA4d^=O09I(y3f9P4Hj?SXB3oNZK}?6%uy^jlXWA|^+NHOSD4n+zoitO z>tR~c3=99VALJL_L;l>z{S!1n&KWQo`Enp%ZQKSPDx4kUi--qOncZI@6?N7}~UA8W&I`*I=SwWzs z;-_WEz&gvHZHYZ^)lB>1hFNa<#HsVl{j%X0X{S}FXtuYS9Q0h+@?1Aq8FDFEG5q=X z%fAM%Gakrz3YH<`IPCZ!c6<-A=0(;%P!ySOAahz|JC1C5vBUf@0+J&0O6>3|WIzY5 zz%lq5U3dev(248t0Jg^u{Z2-peP(VctnAv!Y$qw(Be#PcEqe#P!D zKsM}r8g^a`JO2QdL2-003l^e#-S8T2g24$h@h4|4l$J?TSG%}3%=T^sCw91zEW4RC ze(Z5mF4XgEo$|O=C!V-XeBM)vWZ6}!_UARvh5lxiiPA6nfhi-7?cSTtBn5^$q{TZs zzW;h8={Ai|`)yno&y(8Ze3*XUt7&ojZOs0pGp&w#2jo&x-Kc7Ju98HSwUgMnosgd> zb8C$@(hHdwW{LP`aHf8>UA(!#P4$_3SqF7&3R{d_ZzUcADM7{j`?SGX^ zAEHZ-(4|zEhb{@DL+MZ-T`Gi^&?!sk1nJQ+B6N%ua>7mc7job|;(OQw|3F7{u?F3e zM5p$nQ@!ZYIIKpO0&rI%;AM2=D$IhExHr@Pbp+1`TXbU$+4Cdw6nGce6FCy@9}ldA z6HwOsF_G*=OQsunTiQ7$jEbiDL$WqCJ0=2u<=4bOp+8`Rgt%xfJe6ix0h?jr4x zoTTSClyUJ|yzDIw=5OQnI>%l=rg(vyv4xzSaVxU42;c8X-2JO?9`nA98_tXi~ zVb?2>gEHo91ADNeH?f=R@IL163QaI~3GAjFOvL=t;R)=hDRSV#+*dL8Xv{Yrrg`2^ z9+6-R8Wp#A{?GON$`e)T*DH1d48Jc zyKh_)^vV6F${%$ewSB(LJo={HnC)A#*YU8^L|k6W?+;3o=G*P@|0*zk8|wnGNuI9W&?u|Z_Jz&yTlEzV5cT9`@PteZkT`!zCvX@ zi$h>DWX8@Mf$DG(P9QrEWYz_lklj5P47rh|23)~=G)wGKE;8jsMtiUui;xW2Xh0D= zLbtA5ares6`kQx5Dq(kn$guHIU74>rZl7PP7$lAEmai1NVeDvVPdjY*jkfpV)QR|f zGOu-kZ#rK>vg|53Y$P~ef0s$=Iwtz%3XkKy*0*Oq?asJY9KOr*WZM#qZ>Zy%XY5{2eSH8Y@h!#+GJwa_^P5T5ihMVG=t^HVG3&CrZvDHFdB0Y#O_?d{6nxi{+R1+%+&?1Lo?j42F&{@c8MRm zas{`E2fH8&W#9;G$NZOI0CE_HM{vWg!)MqfOYD+#qF!%8+ELN7#a9)%9`+wP8Pl)J z5k*zYmd9PJ>oc9g^^Qm+D%sYVVda*~YL~4JBcs%+R;Y4sNnxfIN8tFBbT~b?Ol|4D z^>9VAcf*3tTAc@-xS}84kf?JM)%2Sc`P^+Y#unLnL$}k;x35#GfFrViTc^?D23L|u z9z(2zGeh@{4V|#aNG5*@3+cV>H|}+{Q~Zw0E%?+dVxkpI^^tDmqI~hYkM!C>;#avk z&r_%m${mzQoEc3qu>eL>BqPQ z)o>hcK{|BwD!h$Oa-oY8a34DP8J*lsTy9?7S!U1uut=Nu>EJulQnnJl7n}YRbJ1iX zng9640@EZebPdWYrEi`*(!NO~pZ)i=iocPI*A~gvm$OnNj#MWxRzKS0r;NDoTTNo39)(^gA^$w&z6Dp2w-|0l9P(a)QOKJcdAGwv z+yZmtPK(^%BlimA{vJ6CBfmV{0B7X)5&C1EKQO;S%#9Xv%W)+1r^V%{`S%7orSQv* z%v8VR8D5x%JJ4Qeri@ThCTW>gT>mjMCPt$sV*32f#_2G}gC_)Ljt92f+$}+MMo)+4 zSgV}1?xOmO!<|mY%=#HFE#>M`drX`bx=cr6qy4|X)9i8kw7L4M(kqACdl#lCPUo## zkhUKpwV$-4<9qeZ#^lcQtY(N~JxQLnnR%a@+G-hHQQ#8!=?^6I$T; zdI}lchI^1v3S5OHxa+sDvycAUU3dqXW+2m>$dCcMs|@eJS!8<|JGvJcpNG~^6`6-% zcNLI1F?KW?j^NKXN3fei@GN%A|1O~e{B{KW&=ECsgaaKp1CwFlboZI}LZ{y^eouW* zHg|%nK3{B$)Y>&5+v*MNWQcv-`E2XQvU7Jv4j$5-n|*%g&xG~&_p+wfTDX@u&RCjW zF%0Zro%308pf#5hIwP>K_2gFu^9!R{b#m|vwy;~o*)pqe`XO|^A z&!n~dne%(D+evrsvz`|6pIsbG${EKO-xWFvmWl77(n^pd*~fP0NNk)o)!7)Qi}GUX zitY^OYWLrx)$?XOcd_udYQGfQIYCc)h4HZ`y7KN|6TyN?PaHKlN$eMolH#em3{! z0*xkb5mqOv4ITTtNi z&6!;JJVDCra4m^ntD#2T@26m#G?C53)41*t_BDzU=kMQ~;APu@Yg|3?N zFAXT!WCOhc4$&HymwmW^#?t!EqSYLo{q`t1(Y> zwn+b~V~>-uzm1RuS+zj}Wc3_2!7JF)eE1AmUcg?mV=uR1B=%DlH{2RZVLzLp5;AQ? zmb%C?7FjmIhsg9LGOdA|$n+-m@+bE43HII{W82Y7m|LwN$t}Q6Y_N79M;^swz4-=mrPS067Sity0kEM@j}qYTpG*s#}{dw z7nCndy&@x1q%rA?w!N^Yj7B)5@a{K;Wq~`FK3$^9$Q8C;Dz$n>UVhyF@LwuZ?f9kf zgD>c z@yJOZ`D{U5v)Fj=dg$w;o|ALPW&`pfn`tP3Y`l;S zEwV|5Hpu80cB}yoz&*I99&inA!2`If=CBRV%qV0mgk8K0UqTh^?|$1(2On&LqptUJLm!(aHq?#yL-`{8au*{ES^}YK=&IRuw2;HK37RWukFe zH8ME0$}+Dz%znAA=mBkC+@U)aG1@{UD@FpkNxH|PJ{jm6lpJT%PTbxz(#U$*b@RY& zr%1A+GJ6jy_jOluaIUtz_1iRJ}@Q zxpqobuALcTxUIhSR{wO2%g%#vj?S|muhXyw*&D1E7=}70GFtum#AWQU>2dj7&>WXx z(HB*tz`JV4a0i;;EL1_)g5XhfZBCsqtKI0D2o!~7kQ3e8gYGrp-XBKi;^01XN)H*IyR0@?Zy2N_^(^&P!(K;#^}_3bV?hY%7!xN(nFX6%h4@0+<$#|8eO{!pP^H4 zU=JLD3g}uRx+adUNkKz&jR#$;hsV%08YjY>kHKt`F8^`TZ}pCHbz&Fj>%P=w`DKy? zXYl!5YI`&(_gdkQZ_Q~wp}GS~L^PT{yx%BEC;iALZd3co)-(xI%7yBX%GDLs`30Ch zz0|>Ld5O%0yX7TuwQm=(|NM;D_@&E~fq6knN`f?1Q$%4(H|o3i?VpoU?lK9_nnxc- zkiRhU&qls%$W<5iz;#H8oEPzDw`@EoypXFFavedg4#>?Ld1xSycs!q7kw+V(M;_8J z3pd~b=FEsW%R*gfiFx}t5a#^Nksw9J2p{jo-wFvt@e;liM&{1Xznr!sVmkCWpF?&k ztAh02{9B&ifxmci<}3C^2dB!KR9|Ma8`Cit^?7?b`-ZlH%y}0clkpOgHDxD8^RZrr znoE5=Or%D#zVu!P-j2JQ*J7Rn@G|Dh!m zzhK@p*e7@N|2yXO5Pdz4p1NQ@e_#Rn_#5+S;*5Gb-DUO0^n<3)?j5gRhZDMI0+;8C z8vEwHkw5uPE^n}tQRnCN{%LY|_G+m|Ty^-lIPN!ILqusVf8;j3&T)q__4yYWu+|Q; z#x(R^iK^-5$}s<+l6`q|V23-6;jRD5O4UTH{Ue2LkE-b>e@>Zkd4)B`CHqrEXub)m z@9s8<=ki+d*Y7>o7miRq}VBo60heLtEn75pUi!D(srWiaI;9R5;C>LjGN&A zl*FtxVLz0??2}+TX5No3S7G)wFcY&@#;i*)Yd74e45*IVwsW2Gxik$-}%(TYcd>crk?YM!TDRB>|RJ`8+L)GRuTekwd%)pKHRGoLG+ zBs!z;rTLU))C89P6zzxFd{|DufQyCONUYW26 z65}>ez;NVL23O!;vP*Y3W{13Va*ge`~}kg`!7ze%4s7Tsfig?Sx@td)5l+ z2i^*$e|{^9<+X-s-_ILm4pDr~Q6pMY`hMOrdNau3P+7In`rIxr#qD%mk`zHM-%V=! zst=iOMN6rTrvB7%T6CC{oUXziDdHAIKt}9?2F!uq;0^3Y9C9gy%TNe8ML>1z&pG77 zk6emi7UrLdXGAad#|b&aWA1L4`$5e80bIqiVITH^7i!|x*&v4wxEnd}!%ny};P~O% zAG?;pcB0gsA)@ZBqV)Hb8$Z4p#(m7#S?%}#vo`&vLi1uka>@Ozj_#?P_WIc-k5Q8^ zBdO`*&HD4FQhf8qpA0H~^Q_FRDKGo6@}zC~Ompc+j<%$SK0PD0A?1DE1MNfH;~N#Z z`DtlHkKOw2%_UV*wRi>2%ZHO}kL`3NbtkEwjPcinIYav?W6$y?doe__z-a!KDA5<;YPGIl04|$g2VS#g5!O;ToRpJMcB~k-j4GZq@6O317F-rWg&xyFV>W`gQ!im5Ohq2gF@FWjUmx?Yf;QMIT|DbQ zVeV4cmsq$CFX6p%Eo4C+mvFxVF+XMW|0eoRj`^uzZjR`?D(;Ux>^AN&tL$HT*DdAe z)cd|GvwvHKap>9}CJ#dz-83#z-S(4#Cd&F zac+0pW!7~-P5n>R^Fy0V*$(Yq5xhnld^u{yGbe_-LMR@m)&zR#ksj>UVBG6g-sU^% zmLISG-iIamst{u@m$_m$*QHF4{eFA{<&SjL+^I!f{~RM3HDcne(vRS2$84uCTVc%h zEmXyf1<~bI*oPTYq1%p_@o9A023>sxS8#g{VWx7>66V5K+@v@-iEdv;m(Ac5oP&3f zQ3`y6ta@M#o*CiDP7B$wA-e=P4rP#~Ix-Bz4lF>@{(e8DNIR~NW&3xZXJc7EpVl8f zwJFl#ZFDG2p_qF#d(ptI#xNv~IlcaK4 zt*(@}m3RNavm*cY2GkAlhARCz`-Cja?l|{;`g)#T=@)f_#h+`-H=gBe?#&DuT#h;T z(PAO;uU7rR_sdPbU1yv8x~XjCJIqE4o>=T=Lxwi+3^JU7o5+$@gK(!_KuKh32j`&( z_Gca$Z$brR?Fr+sH_x#*T)1OuFaf@Y3h0C%I#CA`ao4(#eFC!gMy6ZvFETuY=YJit zY=Voh9$Ef?UC8v|bQ9kzo7eG=mTF9o?^)uzb*IBuRpNP(t$m%=Lv8Aw+YLUVR30() zi!+mcLJ~oI*6LRd@467s)7C&2BPiR#d*|kN^ZW){egTU*G6BmRiCqGImV5S05+Ac) zx+(NC=!6w*4C8UrI*U7Gb(y=g+lb>-iT?kG5$69Ip2hs+afiy_Vch+5n3FcDudThL?7%<9X+d*yoJ@O8b2g)Sx%7{7u&F=1H{8X-MUj zVmv=EEAxE2^IV97{()&|58d3OA}3UPOP}FlTr4mJPiXhmx=r zieT>X@F|o+4$|-ge1aawqsMJ<5Bhure!z43H*(8IK6A+DK6*QcJVY>mBFudkWPy$F zE^bsooxw(I@X5v6;FHtdA)K2HL^AQyvz(4M{oH@@)W;|B5f7Tx)NpcsJfE~&*Q_6T zFy!C9L$&OsCe#|@fut<^ZU*)yQN*Q{UiClgcqr5}Gc&#`+AiH7{%ULC zu#)fkQ=%?s@oYin!od2I8%h*cMW?G-mY>dZ{)v)y;kpCs* zPmA~6ig=dwqYt~VzsKMO_!~V5wj;cbDSLwM=tm@c2Z_-KrGr0-dDV2~_>TUSG}o4P zDYmFIeQF=?&u6Zq;lp1b%h!}fcF#Im_v5dB7t*Z@Eclu}Ny`3`a-y)&KfpIrV4k77 zkA=*cGXc*T#}22RA^JQI{G(x!<_-yLpHT9p^EES?Th9L)J3(7|Z*<1P9z0L{^p z2K1x{J@LW)Z-NTwhZP)ya(G^bVzfp<}nvDP?p?8@|Ntm`0~AqeFp^3O7U+YNJ~oa1r{UYe{eb z4#6Mj9woXa1tZ`obnO9T$FqtP`oTvq9qvH~8Q>P&gYJz&9^5VtbZ-mYqCL(WF+0BZ z8|`iJuouB)+e<1^0e1xKMyAFLP91NN_!Xjj|4GC|V&6Cg=O3XC=l8isIKwh7#RpJL z?%QM4EdI?h*JZpkAevSvLVWygi_!R96}HrjspDsCf4IM)AzB`|W&JnesLAgE+Iihm z$8U=UP(5RNOLJ3nAcK2z$;w(ME*l*QLH6m$o)OuX!$f31f{bI4Z7#B0fi=ji6<+%9 zP9URoWFU|G@BrpPBHRhN|3o&0kQ;Zy7ygBTxFdte?meH}U*&!Trd9bjW(M^Ychq;^&d|yrjp&5{W?-`GcwL{#C-wN&0Ks6-iB7mF3+% zWAE~n+y7N`3&d7Ds49Q0+)=tPdRKp?>t@+0gL<~)(SIlV9(cT4`WpDDqKA_$>`O)3 zxUqlq8TXfG%`0}F{nnmd^k$30xks-<=FH!X%BVrw${a)A$`!Zp!jMXze@(-!oPBM! zm8q?ve~Z+fuX1b-pIrHStTcP{c@lXGZiF;$!wz!i#!XOy?6?g!Fb%!9j$Xu}4@Bt0 z06c-4K#N|~pbzeN|G(wYjGqmS9sc*M$|pAbH63D z+4|2(YKE4}a`qZnO0;P)NIWWXNC^L_!xT2Eus^z(;!|w=UWX`pOP#{rHLk%}GKZaV zhkc#LCETBs+v_eTl}PqoHDyjsv#0Czl#5L(bJ$<0uMl6qY08u|dOAKa`T)!7UmmTF z$_rd67GkUk_cghqO8M1amD#%_u%DLrSbXBZ^>T+ZrH+q6&TZf<9284@=1X zFPuT%>9`l6$o&}ZhAIp|{w~;iIpl8zS78@=&PG2{{7E7S-iVBt;*5m*IEjH|Jx|p_1F81(kNLI$8uv+)5fto#9Bdy`R5NBUdbgpM%U|o zTygovlG?v?;fwFdCX0A%PdWHwHht?SE4jS&e=(O!sd$5En@NkT$vV|q?p&iVD!N^(( z8S`ooI$4B_pW^OKLoPh`I+3vlvb~KRyNVsN!j35+>lMg>ta+e39Ki1VhNb8N2fDzI z9b`bZoX9j5UPh)7&>q>oh11CR5Hi+=ZZHm}Bl|&kz>YAF1>8eH?64zDgM8@9Be)Fd zvD<~POugPfSS|Y~)lDjoQ%XJ$N*%%k1qB+}+Ruevlj5g7($OGy`z0l*7mYxUUIvf< z^@nEu!H=72t%Xizt62Ta@LU?F6F6q!uiB!v+hG1^-L-GihiPckEL}H#`LbpFI((hR z%lCS&YDDk{Nnfj1)^v0)Eftg>YRg$uU8WPFKKlB|xI_?JXt{rLo9co}7kM^Y+qY-> zEdu$}yR0dcL)Y__t(;nRUr{BzW=)s^U&ArDiOw9uU64n2)X|*)+y{SjCKH{ZMmOl8 z8ytn)=t>B>p@dGfpbOc!3-@pj>~WX5aF?xdkN-dtbVdY5!;`oVXV9T2sErQYhy3V} zJ{*Uy(5cVp$V+rV9NA}N#YZ3O(%pEGo>KTQKUyR=`t1ZwmCQcsV0wzV#gb2t+O@b< zkA9VVG;3@&*X4dPBsZb(NAvK+#p5UK!pL+Ksoq9M3!Rm@C%iCxke2@>H}$*EDdELG ziSEpbi_+AT6tv`4PS^&N^@f{1Aqx+bh!%S3T>SbdbD`iwiP^5K!3n{vvgpMQwuxh5 zPbAy+tVi!@9sGIa=&(lX;@ja}5$=a<(-Ue{kHnE(%oT~g-Tp~&Pgj*j+v`!82zDKv z@mHHaAJVZX@*(RCxPW`1i|mgg`|B_alA;5)xEucHLKGB5C#oS8?nn!~g*(y#ebJ3s zIE{|jp(E8$5_jVa`~nZ5JNwX`2>1+lKmI}kd&0-8=uR>2L<8K0teI|C=+5tLVOKdmy0?qSm8sK=O4rZr zx{e&9V0`sHJ+_)L8x5a}`Uxg_tr8@3%@XH1RhiG*4MzKNdwmvk`rkjFNA0DXBd*4F z!&#caH~pg6tE)mx)k#$Qs41-zd}IVTn~knB*VYT_m~e10x60gQ@iA!L>u+(CgOrHI zg{serE>A>|nTX;F-RxN#I%-lc^?YgD6IA?{t&npl`~ugZEb=cx?)A6<3&?pdo*TZ% z*&q3a!ne>Bc`w5uA z`z4%6LQL(lb+@sK)fT&~#8ArRJ0FC}tsbX*JLJLMB*~yp`t91QX&3bka_sLF>~B2w z^(}69Gi*nG+{iBkzJV8z=YH&O4m3lq0q_%Y{f4~qkk1$7(~dkgU=VWYhpNa$8vFMG zxy->d?BOg-L0%Hrw_?}@XScJmevJ5Lx3-6wM{EmcZ&d`=jsM*fQ^`)tKcttxRZ+U| zt9g%~QgCcXWApB|*E5^}`R)2ObM3|%uiNxqW-My?#*|&&wU*R%Wu|R|?q$Wlx*4l& z;g!Woibtn7Uq`hL?iOA;t@h#6Xntl$VpB}HYFJN;0Xcd5UqJ!-ATVe*exz}$P;p)OWTkFU7~~0FcId%5?Fw)8DjUxpb$Fd z1ijF)XqW*HpmR^*I26InP=nd%VB=lF>)3!ycot|uBHWZwI0m2JBm6#p+?XeDza!!2 z4?$V@5@skb>%XTmQE9z2dpVSJmiB$iys9<##E<;Q8~V3eJH2S?G_KqtYHgmQ7~2e= zCt?o?ZNGfmr*wBmz?9c*iWi^X2j6b4sLNv)oZn|4&~od4|HP}a3Qevubue}2?pJlU zxP)qF-I|FSk9;Saz5c3Nk3Em?Nbmyb$LqFrkwT%7f^JI`^mlHjEwkA)E_xmJQ`J+= zS5~8yn>B6^$vk?OM6fM4?}gwlzFQYt^GNcnR0*$z2_1ESlaLr)ErOD`Uy{=%I_!)2ZI7tQdce9&xB7LZ5_;GPwJz0YybVRYpcCk z)u8hr?ca~D+&nh_kEZhu=R)t_xKxr=MnWj56h+ya?94=z9Vwf#%L*YHMrKxa$lj}D zkE|jq*(=H@8PV^#e(uvhujgE+=bXOp*L~lgZ`Zk=^AKKn7~Y}$pe<16=9a=pYiS}$ zOK=ibOeC*xdt3WRZ#0qaVBe&9lux!tTxW)1XAiNCP{f$7e$4IW&qG!^WqIw^e|vph zH&=aCM4o3_brcZmwh!Iz?9Xp)+XyAG@`P_acn$^MgFEmn3%^!i12_osY3_c0LTpkU z_yYd5;rk=lfDP(`Z#8UC6}SxFq40eko~u9sYzh;6+kt1{c|SbMgLl9*upB&&9O!`M z$iXbAi9AFh52o0N9ONO-e)n@1fFj7lXOM1?GV5CRtuOaOLh2&xx4zj2S$_Ew9sY(o zR482Zi~81DWqEf`#qrc5-R`L#q3%t8M$9+Ty0*(1mJ_xp-|-YPgb&SKY>Vz@dTCCd zN8LL{5q3S?DVQ%`o9f{hBeljK?yk7h(tPztC0m{ijDFF%rIlO%`>TE_rpb#O|M%=yM1e*+wQpum$hIS!6^BS@?=9Y=Vi%06DrI0KNcUqxN+J`sU>mpv@*C~ChzD!HVPxhNzMFmpnUSIUU@$gh5@bWBctH_t$qX`9 zj|@#BI|RtgI=EuH`|BY_cBGJeja8n7~unxE5#*O}hVq>8X_9huH z-fvxFl(rZ&FeMbvrHf3dh%yZKPkd(h^dWt1nudv3+XH-Bv|)|D`( z62{x8p&PBBI_~6*`}AV>p5i{VxKBMe3Nm8v7Qmn2EHdnZY$o7NB*>m2Xb=7YrIE!t z?AQwK$cQ@zgUR3pWc57mTZ}9k^3lkOk*`zh2+N4X#%IX8QY1S5eLBBqK;noE@J59crOVGr+HaSVw0HQ3_YJK7VCk%}yZ11s>&VURcIROi z8luj(iL`3U3ev-(qDNm9IZ#E%o#m+#KdG(bA?oNMaO(QdZ@ZKK_|8!42C*M)b{yT~ z8aKN4rm&6nH=5=>dZG$41LfD`tE;a{sZB~9__GQLkkZf$nOQs-7b2A zrg)zo!H*dHNFm2A;9ca`3Hd#NE&76OnSq}b_~Ava8OBKo9u+49cKK=J5RqJ@TsVC1}_Y*}LDZ`%`VP zE9(c!tv#~zaap6x+J7#Ie7o%9;mKphu`+faEBNt z9o>-f*1t}adexv%-cF*_hw|w41AGR_sV>xeSPZx1_lOw!@8Q|rCne^2V2_{>WfHTt z{F`I1sJxi8FZu9k@Ar58O#RDXi?a6WmgCF=!@J6SN9F5(58eF*&xGo`UR6N)YrB8U z2U>&e@U9B)uHaix7yg6cy$s&#;9VcSXF&;gzX;Ey@W>Aqg4FP53GTz&;S8F<=TmS3 zbc5Fva066<=S6rVM_)NWKKRoGyWlbGA(LMuv)glOkIE!k9llR|<#V}CJD&R7N53`E zQMxbE(rjmIUfUkB6YL)1-3ggsVA6fXOLMF))Wup%nASY9kXfRs@Zr74h#MO})Hlo{ zg$+YguW!sPQW!eUQ60Apd8vQXpU&ZxUcQ9eG3b9UQX3V0exdO3o6(y5y6#%S zjNw7>yaK;{@YRZa-H-m-f#L8d2ajstTW|;admei$0qVi`7I+Tc8}MHB!+QX{*Mg(q z50DEx5QH5_2CKkx*ntc9PH_~u-~^?Si#FuI3_WLoZ*}k%xB=?Hza?0UUjGF9(C-~k z0l6>$4?FJmruvXk>L+`z%D4j-%e}IS?}m@`Pc_SwNpv^;P~JF@L4VU>G;7$?n$_<3e{yUl6THLz zJg%w#g`l}v=f=5tuI39;bstl#^arO$)AVl}Sv`;E%SZoRLT>Bi3Q(g``co#w4a7;-jg~0r(x-b zp0;F2ubR|jGqv3t)Pl=bcmLQB*^|bWq=FH6TT($~Y)lkrj;t0Ut9@W0GWrYTMK(Wy ze8}hpWV0F+Mm9!2aF?FP0?37ORbsgTh* zkONu$f~`7-t>Oa-Xu7|B1Cxj)`;IU+qx3*fdmDaiRvdya-TYN_Qpz`KfUg?A}x*Ga|GGc zcC&c%+AhsOCS-~T`?nX_c>^*cJ7dUB9(K(g*_i@0k%dN(8X0H>S3xIaVgoxijomtg z3|s;GkcDkf3(nVVc7OehaLEUjgG_K#4jzP~O^^yZbqWk052Fw@N@gtD8#HflQd&)5 zyslGwJXcX7iF}iiV`k8xwRWUrHg_a~G)PsQJ-5W!mz>N#;CY9**<jc?XetvhQW=^*TMm=d~|~{zRI@Z&J1#28*U9`+&CRs|0N% zN4>)Wjp3#S41uGM*o`%iU48d6r-Nl0yMOG2zCVPUIdC8PS_fV-+Wq<0;O06Q1g_)F z5rCs%^z%O4=;BQ|4>ynDpd5@w&r-oKydmsxk^t_<&5z3v$h$jVz2vd~He2DJS(A}T z#Xakn>kE6$&x;7DJl*rrvg?R|OycQxlee$$uq~X{n32=avu$1tIgsi2&pt!0O}*7v zh$~4}>|X1E{Dw?IUE36=-|2QHs&Tvim|+v4K*e;I zteAkJfYa10ORP-2w4-*b9KUS6dOmJWirf037r$`hzu4eR^h5`nYlPd&qbEk75c)EO zo@}BY25>-&TYG{T;3f3p5BLWCI1CrnU0c&kRXZL;_Ad70x#oYiOoLmwHuGQ39j_c9 zA?Ximic#3~)xQL9$>3vjIiL_cGr_YV7zW0Ir}1`nf&<`pP!+kTK}WCP?ev4^DRk5jUXP-K z6;D#xD#u$ME3{6~#}N2^`}<+azq~#xD2Ax*`FEqmvG$Ch3$c5jq%|9doxGWO?#q_c z!Mkl)tam%!aM11$TYq^nuOtyGx!5#vSo(3>Pm0EQcD5`boH&%JL(m$}@`=SsQB{U_e~#bg~U9JY9N z#~E8V1S-RCBYggV$5-g(K6q(^mw5Ej1bq~Pk0;<~&stp3X5VO6dAZ-(+1dK@WldCozpF<6Pr*%-&#@AgZZD5F{1tZj)q9_@ zsl1y{zc(` z6?Fef>0s}svE;Nq(#6}a`#v--eC=qN7TxNO^HRx(dS3W&LJ@CuanBK*BY#)FUB6G= zAAXUtLrhabxVXpghCr-_q5gO&^Vby-I_*2^ReGYr55E;q$7w|fY<)e!@VUAu%)@FlS*h$t)A3hmz{P|J)O)yn>wyF zHg!g#mF=b2Wa(i(0*QK&`O;;#jMN?q!9OXyXB#J&JCes}#=H+ZOh+dFRo&0)5U@Yg ziN@!{rP17mi_O37oG$JyR`c2uE|9otbWvgA{q@owjkLjy33225xba7@728LEPS}E7=)&dy zx&X4k#eKM_oEx}aOm>;N>S?7TAD{iv-?wbpwE6C`q}vK1Auk z?^3#Q9+!32SGh!WI>f}mv-=qTv?U+!v@NwgUnN^<`aPcT-x~6sqUMeltC!U&(n5~p zKf5Q(#~E&tiH^{y?PgROo>swO`1%e?!kdD|?$7VW1~Q{#0bnfX1COskW%#6k$2;Hy zum#-`fkztn<3M**(3vOTB0MHw^Gx9}803dfOL%0&+ZKiH+`)GdHh3EVPr+Xp_yr!L z>b{6K=Y-4-G!HTMD{KS~S@7uoB<}90e6*#zLl|;pb3V?xV~@UG^x?|ES+7;A&7|KW z-+Ttn-)Q9_*(PyUjcFeucIogm+fXWR?I$&7jD8_8(mvPCklVVY;PT;KY}I(LUU`cv zNn7nJ)w0&r2mJ(g;bCwbQ zqQM>b(uW^gkPF*a2@mGDyC8Zri@WRM?inB}dJ_doVcV?1eb}r)a1NYDzkYzT@H7iQ zzu@N>-k`JKUGNRK2$I5=557A#f*kPn3~Ye68h9gg*v%^qc%kU@f#f7*xfAhso6>7l zrhny7mP|HMvz_nwlXlOSzut=cXhM2yX~{xS9MM=3o71VxKYtbiO=`%?X#QO)Iv+V! zWxB8Mse6-PyTF0u*vlgeWqKY9-jO*Wou-Yc!Bp`Xot~T%BYLsg=$8(>n81qxJn*6y z_3+>W56SS6JkSe z)pz8m+L%~%POy_6XR-3|Y|V8}58?uf`xJ~;Nbn@s(vzz74c zy?B8DBj=y%jAs1Um>}>VGVFqFvBC}MaYH9C2H8G~8*+j6xTPX8eH%Ar$F{r#W02ij z$SfUh+K!APzQX9F31#(=_Q7z9Zrnt$SCNaE=o)3DDw+%c3URP`AZNrE}0zV`=L1g zeTIYo`;5Hj#8HU}-Zn{*Da=M&#D^Ug+J#LzPi&qT85hqRkjfJsXt$gE`#yuU%I@!< zpfu4-Wi-Ms0|Mvs!@Ug7CJ=6pRUB|Ljh$Q|EGCZn@R=a^MASlme)NyEnU6QzQrgoV zBsSI$CT_MGOg;P1M^Nb-%zr3pVZ0|`_>8JmOwvaC1MjFLgL-v>|Nl`BPrt!u@U(+o zxuQQ$!GGX7yhX#;RrE>;-Yn3k5_qWqL$OtvU^h67p7Fp}KG*ew%V_#`;`&RU^+?q`4wouNi3lY+w^?OuGh(pUoL)T4I=?3= zyI(Ykw5`HVb?Hy)g|EG%mkrY-7J?RUl7G@!QoIqsnEe#prxXoh@bfLzFl2bcgJK+iSMb1(2D@}q#< zgd;CU(C@FHDZX1QgV&L#Z^)4rdae&TfvLz7FLFbLTug$?;6>!41#e;}azTMzNCmq= z66Apjh@|K=|y_#Fk;!6Vr9QE&=7u?YX!@J$5YCg3PM zU%*aW1Wm9LIqSz|0G#>&=yS5;B5(LfAjbbJZ&~ZJ*>AH~jFmF>?0! z*)pTf_tjkzauH*%5-9?dC8O&vcn>71-DMuPZgT&zolaIScDgKyUatD&Pf13rUjHKY zi8>EEG07JT|KvN(4(+MwmoP3`NbvnQYg<=6I<~il*#DMz+VjbZ>Bj_z*tg`0)?d_B zXDhQxjJ>Etm(RlCEJzK9BA`9!2DX9I;7hnBhHEkKBe)-~d(rI)a2u{^;P^5+8v=^J zX#>azhiq_04L6No5nOO%qYJ@7PypS#0!RJeH8}Eyqs5;=`=-;rOC7chE9whuqq=A* zceEro>)4~&He*z}-^h7$_}i!D1{E0-r(W8h(rL_3 z{)k|VAm~*1TP51O>9<-dNqhM6&0c8#n)7L7Ipah4%j`v8L2lD@_&BS~@|*9s!#R|= zgW+Qq+ZqQSgt+4++)*4f1RsLAU@cgR``*TeGGZHNaNiras}1-Dlt&k+(S?s-BRaA0 z-y4a$_n`~=xW5NjiMP`M-H^cj$#M5!4VqHBf`)GbLrH-Jg&D^u`q~dUba$AgYov39 zEiZh$w?@&q@`bE(TB9!D(m=;z>GJy~-jzVhYXhU-Q$sRZ?DE;_1=h^0Z-4sGK^fW@ z@15@zP}1Fzme!vWu&m*Co^s{KA%A4F1Q|6$_FjN5!9U=B+{_fz!0zON^Vl0QWYGt= zdW0K&!);P+)HuSj7FOUnFe2z>u8jH}>S~6X0+$TF;m*e^THpMMg zNpDZWhVRiOvRNXx2^KU?OP*0V+H|loqRz+U_J@@6z4EtIW=_30L^%HJ;8CMMHG9bb z^H85;m48xm>fX|Cl|sENsY9jG52i|ItH%?yvXtzb=JG8?2G3pH-7#nI8M2s%dluuK z3fOf++)omB>jfo|Jxz3+3-_}}2CpD_5K47 z;C>vBp1TC(KE66fkUSpLd9bIgS#7~GKJ~tBBTL@dW+gk4D0#b|wVg6^o$>`g&ex8z z&xTEsW=sg0Wy@=x&29>9z0#2PEQB?9E;ZS1(YL8Amn&#|&aAU6Xs(uyv$byNXRN%P zdG@0ZSK5Qh4*9(`%1ZOU_(PS|=|%hNGOOsHi60|U?b_c28NI|^S#i((xF-ef=!%Xv z;hq$@=RJ@Lcf5u>+JX0x%SCki7buMTPJ&JN-tz@y$Gy+u-u%e(b&v=5r^WrXK_TS& zI!KKikAfF%c0Dwr<6B@Nay$=ye_z)=KkLJB$Rc_AoYI8yjMC4M#l0;$0j|Qfp zIlik&sHD$${!Gl(KRd5PqNu<|!T#dOjUSoMm@^-}Am<|5KVthM%-piwn`CjcttH#6 zQ-Yn?XQ8@oM)_&&o1es9VIR)h&@&?R>>qd)ek~qrv76O9=^bPV?IgEMU@+h3(7{erWckcXoY_n= z!RCecyJn6Tp(D%LBkTcw3>Fsbv^TEoH8^ie)RQwOxj9Jc%dAM|D?Vbq*X@Sc+laFy zi3Y>_-@MyV+-G3XGUwJYpIyxOOfvRCU~{O>LCzh<%t!AOZAW8ut|XN_%&br7H)o0H zV1Mn_N=lsIe(24h(s%Y^oq!DHALrW!-8mzp9@wo5N( z&V24kJiASzCi}s>_)SudzLk)F* ziI-NH=`{gmuS*}!nK8`1$#m8uopU>T7x_s7cffh{zY4iJg2g9{+;-ki!7505n4`39u`=;3!Cme6oT(U=eaT4W2+g zWk5YJ5%fTAv%p^PFSvj_A4HxxKo!sz`5i)TUty2_fdSYhN94B~`~s%h?e10vxDWZ3 z1z&={!A`WS(uB;nYme2DRaG__>@qY8+Ge4)hxr&@^gLc<;KUWXfg1mJhXLpe= zdF03$XZzu0UH6K)fk4_SkOr87XlOIUzgUp}gSFPZfTxA3E%uaW){hD7#kg z)N-w4)JOJpJCdxcf-F8aB&`)QqTW8bdhMrDMbTU+%~FekPXEUbnlCLvi>h+d?o6tr zT`N->6^zY1QQ%Vk$R>6B~x{)maLD*3SBm8-iB2EoI4`>%rs;D!bK2d2T*M{opu0C(>|5^RMoT>gZ^ zb&v?1mj&P9ZK6c?N8pqWPPxG6cw-9TwgxVn(ZzANTn7d4mdJwU=wbu70B(bq;XVo- z+z;2PaNP>lqEpqbq8ep8-*`Id`ea$$ne9oheWsmIEn;01fE}PJZVdW}SGbXL>I7GfSmQ{9S8iTJ4#u{3l;a=umO! z7PAOe#b^)<#%bplj}X-e)ktMuEjY&d_u9SFLPrG7i-}98Y`gK@!S_B%xaWp*1&|Z2 z*Fixzy#~Gpo#9plyDtd_fuV5y7j8G;))l?|1kQm8a9j(=cId4m=n68xc^AkA_a8xb zxc>rsgIld02C^_{7$ z;JaAruk{-r|ISHVc4{`bTr~fe^>dJp{L4ibav4F9mX#J}mOM_8T(4ZALk>Y-{djFW zd?e5DwaLs0GI6ou`QN`at>%zq;MJA_Tb&6_LA`X|H#=GD50HV^$UrA} z0nU9uL-acleb$8ABDn1bA7PW9gSB8R+)si#pemeSK+k*Oehcn5(C;&FZU&x(<7~K8 zg|lgpAKw){!5;7{SP!><;I;~G+2Jk%d<%yW_X+<0M~3|_T~4RZ#anQMNSHVDs!ujN z`}U)D=G#XZ`Y&AawQkCfAH@}==f}TRqVJum9q_#6wIPzdm#fPB*;cdZv&Wyursk?& zllJN_$_;pA=O%peJ^g0r99{L$G->d-%)?A^o)F%TsidiR0C&}q!(&{!w z$Oy)w52W@cM2h@PO7*Gsu4B+H3xB-TvZ*Sm+ zA8xeZCJr0`S3wCl>vq_6mus3csd9bt>c_FO!Y#I5DHaQfzrJs0uD71G`5U0NV0UgV zsiu|Frhd_K>{p=beLakJ|k(?TApdku1p4p3I49Xm*;AUzq*= zU15cM#wIk#UUh_&HTc8X^!Y(j?QD+>lN8?8yV*8B)!r{W`AOjPM5ZGr_khN)tGtEcj<=>Sy+3= z`&V68l6&|q-UptrxKwGx-t=;mWM7zzc}mPl9qF!=;rgDZ43n?klM$CX-Mm~krpUE4 zIzQQ4aBh-HPVI4CCdtHRnw7~amDNJXdxqDsa;>$)gbcOiG|fgKd7gJmy<5+RB|YGW zvl8$FoDINHGy2#DSHD3KmzQd->l z3vNw>KDy(5RKun=;`Th~V-_5gp^rW2o7T#vzPg6R*dOZQYB~zqZT?RVQ+A(4#hjL6 z-i5#9+!7z;+$yN&t`v`RYN9E>|2t%acg{KFOks~c?seY8H* z^}?%1me*IW_33@>>i)IG6LRr5ukPlP`%5?I9UFO{MAVBngbv+a2Lov*ENE)I$&b zKyvgg7(4~XY2XB0AAn;8xHUtcGT`<$ws#3`3*dGQWVPMx6B}p=M#B9Bws->>NJbA+ zKrYAK|9->!z&A;UeLL7V6ytnPd zc?~@xNPH{fFT*s&Vl?Ncy8G*-SKH-vZ~^>)9L&T2SNOGo-z2afyo2rrgFnDu@azK5 zKR{J@K8Egc8twi%yg*%eE(EvW*9Kh{gl8wP8}x?vFpw1f6Tu7Uwha8ghIcL7-M{}! zcrF4*K?Cfr8$7RA9q13UJ(MRbL-9jPnzhIAH^&Z@X5IM9TTFr!w%?8TrR$u+wCma_ zZtV$Ovz4A_zD$|fre_mKrvICq5O6i^zS7sqZp!1W{SHZh#P0AGT8kb&2r z9Wp=)=c{n849CXc5OzEcu77}r*z+FnD|i>X{>6)4KFE}z^lUzRELSYzpQasG#E zZzGL3FNS8`l3baV_TB1|Nm^Ri*GS#(XjD07Pe>I&=oi{0+pyfIHTPxKTOPRy19Pw$ zsmO^1axw;rYVO{t2)Q_bO%O#s>_Bbg#1XmpitTqqE>=K#Y{Fa66mLKz$d0_6Ku+wz zTJRWhuhuWY~QWKcKxRJx>V*Q<`LRN%#>CEsscavUb*HtYso9~ zzCDa1;D?r6s=k&9ooARTu|>%NX(e8DiifK+&3a;NQU{9;G?D(19d)I3kh5T5?cfM^ ze6Lg>O`yg-UEi#(W<(b9hnSp!&DTs|#!lDiRw`4(eg$GN#{dRxav!roPOtgC(-dbJ zIL|9l-s05z2lpm$9|-q}AQjxxfTzJaum+h3#=ByKO=-cF@E|K>$chfAjEo#YHoCwt zWZ?)ha0J`If-J;?qu@W#4_Sx-he1YUqY~@|U67U2*pffs8ZzSu_mpru3o4`g^&mZ5 z+hu?ISui#z^yOAx$fa|e4asA_xx#<`&728{eJcLlgNv8Td8%k(twV7CmkR1|JB$=Rw^N0yrCHFLN0OJ@wY3f~WYTsu?x`dU_D zy5p_5;)|AR?)EtWTmp~6y*U^Q*V-DpKR*nvm%ws39|gz2L}Y*n z?@1x{feyRi1?Q>YCG0{B7!RH^+Wq@FA{z|IhB4gJ!1ZOgrG!fxP!0Y61}353J8;a7 zUUz`XaQ*4t?%$X3{w~?!I+({<#;?ld@Pt^NU7EoeqQd*kp>p>N2}f^GT_>db>`*Jh ztR?AEanj+E!^vL{YaHy#ogzk$Xo?fjF#E0u%Jij(35G5)2^LB61QQT(-%p>UXPC@) zuPQjqYqxgBq3k3PZ<#N@rZ~;ZuS@*$%qw=k^o_ZFALfl4!CMl1+{XR;aA#WFxfPw8 zLf0D6wRYTZ4ELJ?|AAuYT0EE!Zewp<|LYdIV}<+Lf?l8>?(B|T6~LWkKvCRz0(bs` zJL~^5hlp z89yGlpCK^Q@02_nGjB}#P4c~hh~)ZH`qydAA}vOl(WCPZ#T6IM>DJyj`-k(r=htVF zt?%}n_uQEvc6XJm7xoNP95k>VXRlfOpc<9Ys;algm{{!csKU);GYg%|MmOTq1#N}0 zMipaOCmCHcZ;FfwC zCDM^Fyd#(S@t1;+Ate!~(A5*Ay_X2utN%U~(>s-f}VK0PGUp%U_-Oe=O*wzdaZqb zw+G)qd-!$$72$gVoS8YZQ#|G5@n%X!*xLS-#gw$eH`BXhnF|emHY{@921X4=y7khs zI=-gFO4ehdnUZIS6v=0-tQ*u#_4Y|0G1#N6Wi#QZIyk1j?!NcHS;Z6kCoPNBPg;>p z`BtP)6Di(J_sYE2l)|3+M>3nOL7Z%_2~qoN(`)B1IGl+!QMd9iHI*~Ga{1x{A^a(V zZ0Io^{Dpx|n!BHG9VCX&H24d`cZoqz20ka@lODb{;lT~}4+2@yFFEiK-nL8N5AY4V zsA7*r;YSYq4xWOqj{km7VY~b5uLKj}Zyo-A!Hd1n@Lp~QVR^c%G*b8PE1Mj7;7(Y| zW55#TM0LyIc!C@)t$5gB*H95&7d<|1dbheG^nds+UZuTs*wexEFmD1YrO*+U;%f<} zR9bF)_Ke{o^lpDo^Dqw=Yge!Bxql>~lu4vYLsT?UTeN(T&EeP)LgyQl{93O3`{+EW z2zgx@ctj~Zj3th)2oU}6p9lAfkFYp1)fn?L^(Ap%4ZVIuaGR&ZAVF5cgP)K`XYEro zI=Kn@!JREOxCWghg~MB55gg{iVIJ587GaAcu(>SQ*i&F7$N=}GaLoaJ17+Ym2Q)!P zJ3$F_H4D6hY`B8wkc}tc6=dTXwwDl@5C^YmMKyy6Ow6BLnr8Z^?aF zCpuVU{R3aCg`GE%f1@DVG~uG6b|J@FKDon4wq@|t)LWI>>7ZB^Ws?Uc+HL1QXxGJ` zRd4#+H1&E$#gbh03c0`MxT(^)%jZo4*lw`|Tz05C-}F7boz>(SgMWi}JArC0gRd%! z`990jnacNAC5*I!n9n=Exzb>5YGGxsWL9VST4_@K#ZJmO3WLj>A4v$fJ}T|I&Y>(n zRZB*uve$}@&!jy?`Azft%c+BVf7LQRa-6b!J2TaKptw$LY3i}w-kczt%c-4;k1nUr zvLGMA$VVgcK@Q(^;7f25{0APwW^;f+;9D>sR6<_V!DR40auN!D1^@K1VJBu_yn)d&tHA{-tRD z|Dywbov;&6Ky{k4=kKE<#XULYwv7El^yP~X^c5x7q_$SBP7LD<#2ia|@Ms6brBj^W|d=VLrf3!%eP zvtPs)9gHbesu*18Rv27FTm(c~mbCBh&!DW1{w#ixsf*zOYej_qUB<}cAKjQeEIlFw z=?+U=%HC6* z)**X{sIfk0o;ZS?HO>CQn*|mdf_~?KCjs8M-bNYKDM!Bmn1)~|iN4=EB5a7v|}e(igP)v9@#jm0aQWg)XmzT9t` z+L|Qg?$akkrrBAeCj-4YA`b4Ap(IYrWX<#@ma}RO@Kwp2KHvzirSQrLpRM3eFce<9 z@jc)ND1g37fVJ>`7k#aQ|KsRu7}yM+L@r#w9FPb3AcFsAAR%&a3-kq}Kymc@9#{lE zL2e3=n`)2%xe)>>kslr~0&E56z+&WT0-Q&#@{p?`vx)r`kjnSDb&S>gOa{@=q2!4?IXpV>UP#KB@&cb3~EE#NK=!LsG^5x3%+iJX7cU zcdCPRg~t_wO3sS~^^mrc7D$M{{&Ph)h~fCdz&;B%juOwC9UiLfiAU93Q+GyUyh}bN zkZJ|$c-^-i^tu|;N$`s!ig?A$C18hS;L3f=ii|3SYM(#P#aj~2S0u+gcb~5sO!&Zj z?qk3^j{Yo<9M4>b){lX1f#1Ah=6SFarl2_1`QP^gj{pZQB~WeliyTa}&@J2*7-j=g(;{$S%Rp=UjO6K6}v zt8zh4LJ&+SfztQs2#K)pUJ?z{k!#&GeBH^clRo-ORn=dc+Z0&jR z!dj?h<=juRLgkI@)&0-T7cjLQ?BWSy59O+ROJ!TE5_2|1yf1G+PwW7ZBfm+e&xw3o*CL#CPFo z!ddQ%z5ydw<#H2{oHYR6b_krrE;Ez?VuTMpYg{EcOD6bah8czBytSgiTZlB%P z!kb1g&qL$S;bdmoa><7BBjt(oteYuElMNO`xJ0_NGWpZ4x7M5>Xgzk8#?ti;&-WYI z0OHh=V`DB;;f-a#9O^ z1C8;HJO#s%pU>bClroEtE$4{v=%tC#+oyZdKOA2@F8gPhQg+&vSLpf9)fV4HhG_YG1HMQx-6Nci zy5}B`T+{fsz`&GNEo>T-Z^+~;%1H0``2}J6o&WsiHuQZZI9GBKS%?D3k%b_T0+}!dmynG$ z@IJm%+`)E~f>g)~3$novN`ha(9%Li|87V*}SmB-q&f~yJa0FDr8*l_!IEoBB23fEj z?%*D5#X)2w5lqJ$!Hdi^BQtt<8(fi{GHgQ?NP`RsgEn@%*-8Qhk)?T1>HhAYKeXjb zb0sjPhpT)c*0%8d2b<%gFFB$V1}$`(f6bE3bDs|&T;ZzVyk_?PM}cbR?TTl?W*=Vs zXq24#m{X)uMqKeUfkZQNh(wbtV_HkGCv7b-W^d>r-OK{c7uhv|A6q3a480#A50^Sc zvT1hhLIKgKE63AhvRhAn$f-{|K^oe@ZI&}?JmxoDqw-hg8oB?6`YTDzCr%*)#ULp% z@EY!OKv%f;f%`N#r+~v?I6Q=2tHY%(ocV&m;2SUxJO+1WpgZ^x?}98`Ho@IVIEw`9 z!HaO_1pbAyyZC;W0~*53CAiT8--Df?FZy4cKP;xvFMghX^Ba?KB)_iu%Mp(0{HVZ^ zWnSy9E>W_TinV%*@Nd?m-6IQjm36Eb*;tw`Snoji!3A`Z`>i#@`;%5p{Bi( zNB!@hAJt2}OD_}J#-B6)3t3&`;`?Iob*(fcfa0 zF1(b2b@1~TU7NvsTZH=?qbpWmB<|0LJ4=AMU=gT^Jq`lp9CkmqIXGtgN$LGTTU})i zS7p}kH%Z=~&^{+gN^e1!6nC)h?JaUC!g~q?83XhCvbHj1Yuy7(0&JBfa~IW2_6U&3 z&K*B^iy)tYti|`y!m50)4(e575vqMgJ3#(DF(0Wpej7Zqh|#0NC|F$o%sIc zg{?HjHhRJDGW-s~YY6%^1m*7Y@f1hAb~yUdKbX(vkg)w=bm6@f zC4RomN`a}BOp0GIhQF-~s(U62>8-GbIiMYUdVpcqc5_$*Z%d#hynTVUPWa)4k5{-q z33l%^?tcRP83E7X?%7}ydPRnvBg0!|3QE9BKFEyy69OsWYYd)_!;dlid}DW12bRLOICj(p3_}lnk%Q+T6Fhr>eDEv-E`X=udkvnK;aLN{)CT84Gx!gM|7iGD zg8xCgNIBpdvtS9{SShdHTpeM!K zWA5kL;=Z*vQ}P9F->9~zVAe4B$V@l;ic-K}z5J#@w+<6=XMC@F^*iPV=e{K<8p7vW zkODpz;ZFqpvj+9xZw8!zKQ{C*5&Q-(Z{fio_ov7HiGh-!0+@@Q-a$XZKze*X83)a< zo3G$;6?_hVxu6m}3c!;WJki1vDR%QG_yGM31)D@4IyLT8I)~mgzr#&tzs4e}>n3UF z+HdNY#kr~#o^sJr#>(+v z#$}^KL5WkrzWH{Ns<&QplMh66t?SB6R&SIf4y%8@T{Xn)M;AT5B#_^gXfxD*`|ZYf zl85$>=uUN^BqD;QuORY@AEvoy_a67FR7ZxCXGpbJXlX9(uLw!|uH#81>h)$k?(>I_IIyngv;=79|co|#h$y)PaXuj#bfE3CeH%`Sh%VAvx( zVmQ33bm4G`$6vm0pMQmg#7EIqXbp;K)QsepMlCR}j07jV8mw~c{+vdguNA}J`>%)Z z3!jVd^4}HelAajt!N?TtaN$Je$e6Y2FU%44ojW6x%dxRV74N#-LPLAB^F^m$Rz!qq z_>Y7Z#Kgpkhca^uFzk#h=Nr(7Q781Rmh^d)mN9n~4E(uW6S-C)(#zYoToSYSFh1T+ zq^G3d;>z&O^;ZcaBFIZExB}{_?SB3TpaV7{4EzJyA!nIjIp~YLy+qDvvHervcYFt1 z1aBg5z97MW`2tCiFILbP^aSI;LFCQ?Z^bO~myNuUB5xOvFEua@97oPvusKm60rDmV z-usWp-2vpv6Fh+YdSiLYr!_&3k4l}X~k_m(D425e=A3I zwzeq#hqQxDs~p3QRjr7g#TjNn3Lib^&L+16=6i5n26qhDeFe?k45VQ9J>lvG9BJbn z_zqsg?SpXpcDx5!xcL}v9ERJm;C+1y_JRKB>VDiT0c;0LaYI(zC<|;`D<VACZI zr`A;(w4Al=qQ23xBx_@{B&%rV=jidYfQjSKr!1w}%_E)*U*;4~50)#cP}37|j4`lZV^rB7d6Lxoo^~E#L**ZXEj-fxM-GbGXfU+(hHi=Wqr|gAH2t zUUv_oS3(W}TTd7cp7x>eG9-^6SY9+#FyG>R6SqOZ!80YC`$B`NxISexPumW>c4#e6>*1QWJM3zkiqAVL?+7c`5W>1O|kz2 z`24B=?KwVID0-B8Z#R>s_?*4qetcfPX6dApRLTG9K1&@g2z@SI_o*TCYIwSXOh{l) zk-vP*biL1gyO_sCG95&-R}0AU_BZ+)?F$adkQv-}dvv6Z_kTavC79~*V13r}=`O!I zKlw%y+QWt3Mba<)x`L^E82w)yikJWPoX(`)H>N&3ef?5L+m2liNzuJWVK(&|O^Hpo z0~@+j3DV&no5({M?r{lSIgGnl;4aMAD_h*fAN=3H-R=K>c!KA#PaMd{E$}CDvJLv7 zTNlu+dN2|9&9mM8>vn7#_amFxJQTEAMnX+b0sBRoXDLsux2RILHJ)-Bnx&N+d2>o6I+x>2ciILdK zZ9Ki4^x24->eVa-&8I}lW7Q=4F1H0J%Y6#GEH|=ek!s+PsKfA28N$v^zKDtd0vh+) zBiBFI9=YY-uE))RYzo1J8~7XK$J>+QT_Hw9d@qc3ptb^q`G+^foVc>nN}uyM4Si*byci}%A@5eK5T84hea zUE|p(_F#)@;Jxlj-p5w$5aZqMF3i`$mA9|m{2h0krnvNom6e3ZmLxl*l##MWglxj^dw!m`e;%iC z?$PVaZj^!*U^?D*P1D_f?jhWl1ou_NhBBZ7BVaJ@*ophSLN{2^iApdB-JrsK-y-X^ zU>(>B@}UE^;D+`YyIzmgHp8WDqjlLYlqPc9>e~mrj$b({thUPHW%Bj(z=12yJ8ZYUd-(uC?KX50-(8n<8<~bqb zlb*C<6h=pqgYO!jQG3dm!n#A5ahV$d;ewyH;HLKOUAMqmo!#$8q9>f_i8Fj| zf?U`-I`ro!`jZaduJC6Af3{#Ocndz=;ZqL1Pyi>uYv{*aY~CsO{Q%O!vl!S6-zo6@ z9wdkF9{3&y_rd!=^yx7?4}x@fb96x(x83_xI2XBnm#i9S*RJU7W_kTS+2{53GUk6h zmur(n2aS8)eLAzmwez%(%}sk-*o5&3Tg^aUKnu$wlAng3KYTZFt@2=~(fr5A!W+!8 z-IFYRM)aw3RdTym&FNlA$toj;t1Q)$74gqb{S$r2C_J#{^V%!rbYJNwN&QJ*53kc3 zqGwjto-w8w-Yq3+W!YBRI;tPo&s=KN{4YgtlS=%>zwP)3cUX%u@@SSarm0G;9x}R) z&kBDos+M`A+952yk%R3#gzmP1qR7ZWWTO)lKqh8DEo7qu+4zD?*dh~?U@)?A7@5ce zSJ8O_WW)g+28of8OW;*xr3pNY&E*1>kRcXqf+sfj6S#;hT}75mk)1Ed$__FTii~uE zcaaTEZ0>zzL=)Lq0h6%>1z}L?vF?0e82THUiA2|>hn{glB1K@oLzC*NkGk#2Gmu~P)1>cY1djwR0Z|48rQZO4V z!sd5@#_)dzzKy`U;770-{*S`@Ecgd>hF4;E<@t};igb7!MAs+5EAaUcw1=Pi|2%ckSPbvpDklT+t8{zN}rpby=6QO89$RtqG4Mjouo252L-oVZ-Y#M&(4x+tSgh z#*9lYM`e!_xJl0_m+qW8>~5?XM|G5|``a@m_P55)5=q+vW(nJpC1=Wy$4LxYjI0`c zw~jZOm(knMWsj4&NnHG0P^NZc&6<9#Y?Wr?=3CYynsiz46AV9u@Nyhp^1&JSVS|_J zAU8Y&fGOa6@CrV^KLb0k<;3W#9K5{*@4_D^{2V~}1|M1IT@@IL%{E65 z_rnJxco2Q70K?#=K>U);59#(}wg0SdZOEkVEAMT%wYWxVS6iMHzTn$xDCRsdXk?ss zRm?NwY9UkR&C0vX7dGxhofndxV@aS_{Uk-xX!MLReY@%^k-&s;)iJ&^w;RsXglQ}|o+R^@ZogZ0D#(7B%7*_d>)ydy#)%(pniJ|aS1#Py6yn@h=BOC# z>3Ndh#f1MdgH)<#jWA(TyJkrHNcjnksyhc~7By|vhKxIy+C(ROd+!#U$Yu@`Sd})r zl0~07O@{7yz-cnLgzg2v@fUCl41;TaxRwA1Kv_7CL??ye_&jJ1mcVrjTz>&qz<*#c zobP}i;r=u_`V$$j#TKhzi#5Tc*x)Eo4jm0bCThVbWPuM`oCq?Y!|tFYI{W~9gN<$g zTR~=I$OD`}hD5R1C7>A1Cv^^uX>wgrLMDSpEq98jrtNh+#xEOChTmX4m}~p`Rg14& zc?O@{mfsy+#$N(1Ws{$Zx5gQ@O#V=6=N~`6Xn6MAZMpNtuExP_`#ZB=O^1n<(u~Z>gu*!8A0%Y6)WBuenPOT@Wr9y-HOzuSQk#e6VEwJikk= zXI7##=xsdM2WLcZCI}|M9TE1F9}cDA zt_sdb(c?V03POMB;7l7NMvte!P&m8~C(l57IPnKtzz{g1b=mX(-`YTJ^xhw=1SPcz zH+iHzCSru>*H4}LRT(WM(2y?8m7pTU)I7{8@Rj4pz5K#|9GB9izf(x;a5To>J-oH( zq4Fb3W0bjweoyUtq3^PZgYx~ljKfo!m#0JK@5+xbdbX5^%AQ*gGQRQH*^n}Sc>Be2 z;T_X4N@IB`D-*W43F($OuJX~b&)+9|%{6wv&S3BuycL7gn!7(A1&^&DKRh;}vrg#j zIdt+jye-4e75F#;A7S7j?Co(d72WCsKf)V1eDTB6Z;%bGl& zf%9sdnU5v7lzOS%$U1!uUJOc@eQcFeRu6KaGlr{JPzJ7q;3^O_g{yCH#ihIJQVzR% z89ayXC4s4+2)ZZ%hJgau(WhV!y6A=O)x)(j-qc2r6wWEYYB;xsYg)M00#Bf;MsUvs z=ba!Ix>*Bmg7k222=^%<8M>(o-asb2k%-jD?B?c9iUqWv;5|?oKG7N;Vte3cu(jFKTwR5NR@FxT3!|->}~w~`7YA;hRp^rOs+P6611BODL>iTf0Fak)JeI<%_t}H4l)H!*>DA>oyalb z>Pha%%ogH%56GsPYaN^}Olfd8I^;QYM5gQPI_!YU8T5_-F1f*O@FV*83zUY#T<{~< z1ulca*jr!l377(k!Z`<=cZ0Lwez-jeO2M%R+>*lWJFpx4irpQCOC9WOH1^dD?wa84 zFIWe62jQ;yk@KsO{;J=vB)=F`^IGdQBOB@S1pT>yJZIQ;&=9^6D6BnLH+f_0Y zO-(P6Wba@=yhc1hQ`k)1P8Qp#Y>cguqI{Y5pJdaMcg45s? z_zndr;oS&+Z-ANq5x#$dG?oI~G){FAJYs=#3BLZERIc~C3oq5Fl-dXI(9s?+py47W z6}RS9J~I&(r(@ADK}E}59PPc=V1>uO)#G90HsnSsk9z>+*_-Tk|Pr%#aix>%6bh!z{k z>~Y=w{`;Z^OZNVA`F^j13l+LLr5yjV4Jp35zwj>5H1AXp!B|WoSx$ZQjMSdLv_qsn z$r92__mmtcjNDQRB$;JDOcdka6Xl=wlOUooC8K`t1GWaG*gyGZ3+h9iov+5Y%EK4a z9t?Lm#XS$n{PKc9F@-YK>8pK6!@~WCT!GoW@|#f%N-6YD<$nfu4{s7L22peU?|*a% ztY3=eNq7y9TpXo6l+!*4S@_QE3#JWhg{@L3Jsgx7ko0R8<2eg`?x<9i?_{LjPR z7xb0^z63xa>@Fp|Xo1i0mNtTK;j10K$k0P}^pF#z#13D9KXLfe2cLpX!DanF_k@?6 z<9sfcd~Yb|Dv@Aq|Fr3pNArh>FC;Cso;SXq>_|Nq_+!ugg@I{~XP<^XMO6LXGut#J zIbxWa8@9%Nps|vVXRE{9K4KEGYxgm$X6$`-3a=bzm`|Y=TTP* z7mu}eGc*KB>+F8t6C{EIM%+{%JdX~gqdV`xkLXAkZfuAf_n{k#*uK-a^<~`l3V0N^ zwFgh*#$KQXZmf^n-otIfzE^{Zb$wjam!-lya!wbg^_zg+`0l}LB9RLY2;TPx30%tnc(J1xcO5s54Z0Cxv)oK z;Cbv)EtrSgGh(Nt{&N5p!ht99{sp_F1SfIeXV4mshLP`b*WGN@1)ll+;+%L0Nxr+? zyAb2vdwi>_W>dx?yf?q>Jl`+o@JrBLPJOt>NVP6Sjetz=w<>oEMI*OFGikb*?>)9< zIa9uG?f3b`e{mf0-hBzLXY-J|FF(-l6dd27O7bnVkv)EdAnRFMU6yODim6zwitTn> zBe}s;9Xc`xp2Th?gYV(*8+aTZ#lcX}1G_~DkGfzSD2+}L{^u9nx(05;_YrtrgkM*5 ziWHr?29AOR=vW;5-i6;*`27Z-bD$62n+$Lg6o=0=a2mV;zZc=R4;%n<;kylN9zD37 ze3DXl$Ew34Oe^e(q06MJ-lDN)?s@ zj?Ki1Y170ZD^IlUbNy5#`SpjG_n(gv=|DSiU0js+2eHSC6k6Wk4Z;e0r`((`QRK>(^eLnR1>!sa1 zYa<`=*w7^8V@hZD=X;S49poV#d58m(;C~VCR4{Td04{@Tpc8WO5X=WxzzXEW3wcpT zUe>|0$c+J5iJZt|7gWF`P!Rc%KyI`^9k3MnsRx%pS?oh7_!x9SZc0EFY_~4>3S0;O z;N84~T$v$H``mW#OXn(8Q{%=O&pbihnY6rBq~*0qL+d7U%EZCW(O|;Xt7IvMUfjJm zxn{|QM$9!vpTViC)V*;%n?_7#JT9X=d0E+et)^sM#c644DS?>pjnt~$cFA&=q^N4l z|Ng?4^$a=lD_*yi*PXo@bq3BDEUrpfPDwM!_I^2|D#PYE(O*QO(3>sVaP4)5p3N^e z2d6br-QJ91t=+F}6>cL6yDK?)EnP>&Ak%=g{jRz^P{lcIccm>X;|| z{O=ux>r-%B1Gg*S7RZXN;DzI4yw7hz4LIJ$MySK>70?+Qp$~_NU@aVqz~KkKY_UMD zm)!DX*#;RlYZ5BNzf|{XeBe>hkayqn&Qzax<~-;77a0U+k8_DUmaJfe0U_)hd(MA@|34kl_?1ohXo9T~&t1c+dsi%s0pV*0GRq&1&8G5?9kmJ3`z{%Wbz^B*o^(FI&R_0XPncuzl8LA&| zRa5pZ#|#+}`{a2)U?^C=Co~$9s+Skj(aZDrsg$kLgvmX-$F;*QBW}zK#J(>IUzogD z9Cx#+CU`m?6XC6{b<(%#+DEUrriGu}efRwJnbv*rvCVXHci%ygaM-q1N&cyAQXOs`No|BFR*JQX$zls-kk@Lz>k3 zYUsruP!7F#gdY3@2XJpa+}96xy@X(Etqilv6D)>PY?56+%2?Oa%UKo|r~m17l`~b>H_^!Xhn`9p zYcO%Cn-#v6%B%5XXrJ-5!dEm41PN4k)+wB+>kFNie@05%EG$c3o8n_wjIuV`dTe2` z_0?XkOKOI-aPGv9e%Uj)qXq7m4Ib3p&Gi%9wGkx1Jww0(+%pdQL5e$a;eKbqGLRha zg#*|PiXzX`$gvdeehEB|{C)gO}jpGFT1@VR!UE6Ho;E^Ao%Sf05v2 zc>Jf8$u6gm6|`ub<+kR!-_pokos_{SisvDZzgR8zrL^*fIl48~Eaf%5P?1%;5IsZX z%z_jOrEZ$LA+R>W2j;q#<1xQx#b+~|}oobQ8kUT_O!MW+LX$g zs8&~oe}wDitz=2OH?R`++=%ORE|y%=A)+mX7w!oyxcqM?Q_j=-56+>pb~0Nik+j~s9# zj(5cjq(whJfVOa!i+6tJX zn>;ba{K@P^K2ssjEWgxHz;h@#qqY0{wSw;l z@LdAm1nA-c_&x%k#h^aAb`u-`*U_~Acoc-UyI=*#iv7I>`hmmnIS-D*XBj-kz#|d- z9RwZG!7Wf4J9-;TgV%O2LhIS}ixVu95n`q9LrZ$>1(mc#vlRz|G+b-xZ5s8RFIt{? z!@u;G$KTkSK~j-7I?V!GLQ zM3`?j{ym?v@BqJ6vLm0_>sY&`zIS{IPi_mkeSIRR5PQ48A^t@Hcl<=??b5QFuF_UE z5}zjzSU#Ez9qk+4x0?8p4IbU$rw&{O)8K0q+zU_L=;2vx<~Oh#eYA(S4fIg~zFfdC za0C5(fL_|6e-iMs2b;+S=3qNNfoI|E=zqSzCGZ*ieFKx>uM{LfALl^=^ztxx0{%qN z$3ySP!T69tZE#3wls)t32c686q1oS9qDS*|B2Qg9LY_@Y|LMg+k(L&InrGt; zj8X5VgzIwGi^4iLb?SznQZ|XoGOqlYa492`r3*TDQY4iA$5-@93!e6(Po!Wgcmn+r z0)4>;aO}y)KExClfKfRy|;Iat-gn!=51lfDWbvOT-O&gKnnTe*!QAdIf^ND9I3zL1EndAv#n5Hlj=4K}|S0fDY-yg)dwrf^O(iBHT3L_G6$V98lo)Qs_u5 z$c>Kp!NCou-3<@K&GldC5te3%e5T1Yw@O83bgolgT;QNxw%j9a&XAE1)k~9Pdx7X^PWdVA--XX< zG6}3!xT!xZb5q^c3Fc1hnd*9dD{3h*pEF6*GL4qYL|S_q*Ujup6|4hu7%Dd-!O9hYm0n_ZLGK z48RQVEhq&q|NBEh{{PztumQY}H|rZZqleELUqD54=m}VcF5QGb8~Ag8KPz}E1&2XH zbSeV82A{IO-G z70ig->sJs_uO_A;9y@S!?XiNi#TYvkZS5az|Cs!{M6KkK517Y}GX02Ppg4H*GLHin z)qz%Z`hbp15lV_%M)E^sS43;WwK=3XoryyZh_GF1))s6%$)f&%!b8J^T+{EV8uR7K zTV995$f^A7{6!AjR}~?y%=J`H9bpkVFC*h`sle>GNt zNPZdG+2eNtBPQ^^t%8#1DjBjt1*)T?G2jL$kL;KtBh4TsvSI zU<0_2nR8$|=#1=?feOeFA2QSjl2}%;kf;c=y;<$iRs6I4?w86Emy!Xkq^70l_xZ-p zKB=za$?0Z^WznjqXO=9aY2H{I_AA!Ax*=})=+O)P)ADAGUcXdrJx|44boEoXD7nNz z^jg%pF`6xFV)Z?V`qE^&%d=Ar%V+*_@O_!DS2;~@;oa9aZZYtN$o+Ih!}z~b7ONJf zzer;{6_uZemY%FyyQre?sNP8Ty^b^~qhW$ZDZs3(&);o>tk;zqq^iL_eL27F}zXd7{9vFIRk&vg1g=t)I z&GD&d%)I5vMWXRgFreiOx4*rQGUv=E*~n|GV*XdQv;wclcptbnU_febWI-a}<^7wY z%ZilglNEvC=2ktWyIyM3kJ$){)3+uZt~scy$ry0XJR#nHZQC~PR=;9{_ceBYPY(xm zifa}h3@NZVT3``)0XY&yUfjW_;9=yZ2h>Jh{J>wJCvqc(yu^T{$PFXtjx7oUyTEbK z58E^X9>+F$fNXg8D3QBm&>8s)K+b5eJ!{BUCGxZgh9Fnpkt(2fuH_?;gq3LuTJg1VmcV*;rHRfMKUCk(7(K|ft0L6U zU~n8hcshJgO(t?J_cBRSj_{`xL6MKywr9>Ili$6>5~8c}BFdA{^SI>xe`0c7v;69lD+c7aiaYxDbX5 z5_CHZtOr{_UUc3S{0(Q-=z1+&@xj$2I7)yc^9XSpo)Z;UM%`|EUsu);a5iv1c2+~b zBjBFcop-lbf?bK-n}&Vk)$1CLQ1}^$lJA{5eTU<~f%9y30!Be6XuQYmL=EfhsQDFD z&oC-`Gnud}9Jx~ODqu%4tGr*CH<>TXq2$)m_^R3-Ctu=j*jNC-E6eC zJjQPC)s#l;c%Bs=vq1)QRvbRBp_{kC1W*kd{{|fmM@KtBM)<#n?y+Foy}@6gE%Go6 z{so=U$q&fEHaLgP=fvj$RnQbUhyusa(N^SO1v$8ZPL6>>@NEk2gZFGu;J?ly2S1U6 zMTgxU9LC0*g6znJ85j>%fraE!9^&=PgV%rcPHK|q+_bpo{eFq8KU5@C=D_nD@0%PS zOnlg)_#XxM8D148V}A6$&QjoWl#JTpx!yr%%0hDI1L{7pwYH4cGaXn0KUDWQ$LM7X zcgWcv+N1Wrzy8n3(K$?{r6;)Zu2Zha-{EHK-1t~2vbYD{eLW#v^V&^zxo7=-J#_=Q zUunjkJQLmGWp9c;KL-z>&*kuc5q`}SgonRjPy+fbFvAu5a^bWl~WFjUYEPB~n z|1QtIggeT<(k2Ivm&j=I1xQNVEE1L&G%#j49xv^!Cg!8hpD1(Ngpk3ArOfw2@-3e(J)ez^v*hu36NXz%YZ^X@hP0G4 zo}TBr;O-l^1_q$h0dQ)evzu8yboUfE15(1RBdCKed%*EekQtqJf$M6x9L6S-qNCz) z$`7Z*ASE`M5{~J>5U>p7f_ojf&Ig6ym}b`H{kY`wQ`fqa$6tw_bKSjknBCy|+!gvtjf3S{g4L{)5Ax*kymX90eE9 z(+RjuhC6Mzy9}CvKIrW!xa@&T2JG=wI4wbMz2NpUI10xsaJ&WT!mTwp1jlx8*$S7h z(9=9P^nf!0IAa3y!D^>nH$ULg=5oNoev^r$3qR`Y_}ZeLrLWCV*!34o*|Cfb<(FCi zh+qxuIQF+b=HSu5#jN#$2{ros{tK^C6D}ll)KNUzpJ!JVw^jIc?qSFk{#yIB)~}hY z_rGTMb0!TP2^-4SPR+W%k-Bx$vwr>9SI%z~wGCs+xUU@U>yEArf`@R|R4^O&{RQ^m z&f>W9b&v=9NQQfEfONR0BJSo1uHtTTxLXA{fcq)nUdq_DA7Cr?tq^yN!5w3eeR~Qu zMnOTlmftt&)lQz^Q!jge+NAxJ;NZUd*6rEDOc&b2^DmGG(c4YTP~B(=7QE9E&dWS? zkGm=S0nM$58ams5QA|x0L^MW`Gh7t5RdnGa8HPrcuPCRR=eV1ut7O|pDwIuTat@fx z2{5abzZbRRkD};rryy?HAIhuVQrloR^~8!XB8s-PWR_k%?}7S_=@ZoZT2F{Ezx>2Z zF`G$ulMgv>0R3=xY2;i4cPGcaD?ta`J>tL3LawEdYd>%Tj7Pr5!F}*?5)1=hg9q{N z0@2vGxA@#KkNndh|Chn5c(*99Ve#M_cs&50tza&E&VpX>c?UkN;E@ZP<_Mp&ASX6$ zrvIF>bpn-HkdCF8z*ovWWJ!m#)w?XOQv}VssOc~faPAOGkalS5oBk!xNiC;znd!bv zcm1=g%&pMNN0o{-^+x@ygzCH0IoKDKEK|D(i)a4sc}qM`l$QONYcKBuZu6I4h!g@l znap3rTDWn3cuB?9#3OOwr@uRKC%0-=hZ4JaUzq~&j(l9*yd?p_+9@;kH~!QgG7G3*oK^><3BEDQ~#>4JU!vqylgg+yRfmQ7Bjp zS7qR7ygO##b?_c|A0&o5WAF)B1Zu(Q7FYwf*NeJ2Cl-VUVMXaP_uMxfdQpqFw>EW=k^*#5&kG3!O*3+3a4i|gYLdiuAmf^@77 zcNVT>&3ii^U0h6)E7Wr1`BwSKwNK&&;aex6>(mY+E}ttuW)wYM5nG@m?14|7OS@hj z;VBkf)P%2SkRKb^3m%2XI&cD(IZbd1|A0gK>M@15+TAfe8DHE#jU^`WeM~0G{t;S!!Q~Htc!wj}ErvIAR=WCd#Ouq-Zscv6z|FG6d%*jf` ztcdt6`gh(2|1)GobJh}TXVe`bCTE1QYMlP(^C3*pIEgz zosMlMjQwM4oyfT41c$t4>j$nH#lviu%?UaU)k*$p2e_-2U2q{Z3NSEdRdM624kGyF z9B7`7Yz=`kAP2H02v%wCW^Wc`!nQbreb^S3|K4#h8uZ6|!j8-if|rolS#S%aMRpgE z)gO3YE+VtHz&tP#8LkEyk>PCc9Nv{5U^}v`h%Bdp@4yepGzT(030^^lXTd|r@EdFz z3ErU#U&MR_(;G zo%xwzuIGHif@dwBPn;#@SSi(ed8AH7 zd#>WA%+;95`@GbD%p;{vd4`9>hU2}8!l!!y*1_%{8(ih=k;6XZuOB)439f^D$k#R) zfNh)r6Opsi$kPb&^c=Z4iM*(R50MXf%ey!_y#nA_ZRTl3x5OPJbZ0{Y4ElV zvcaD=$OKQq7Az~$8OCp@U3H&m3*3DdN2@=tOG|s3?u47X=m}?2m$`xASP52F(Z*6& zXFUp&(MqzXbnLb}dk(U2IWIFs>-g5L#3&n=9?nw}M>ME_|Qe=YLw}8rUpb64o1J=N|=)OE0+yPb5 z`DVB{if(g(a&Yn*JPkJ-aAAY)-bGiB!-XnHgzlAsr_r^&xHS)W8Mj_?*zE!>x*~&H z*CO-JTSHez1LtTZ>;aeZ%+^#>{G$TyUwj`jP7xk< zkD@*>sXlT4#EtN%4>xoOCmJK`Y6V&qRm_@HNz~$0+mxGvX8l6zvi{+Y@wlHPva61} zgu+X?HOXcvhjm=$^|}^QX!`G-a{0z!D)!CXm%d9z^30bj zhRl7<6Z9KWa;pV(~|Z%o-!E*SPPgio;u;nwHDE8r|{KZML`!$A_50(SrR zir{IIJ{VrK+%&#b*w@cW^quO~*-EiXq#x*g z$HJbr3dGVLA1i#TVH(cloyn}nT%Vj`XE8vfasQcdn_{Wg@47@eiiUo5@}O?!Yfe>q zYO2(9mx*JZu-@x?`|59n2}Sx}x+|vr{Tf`YZw1W1xaX!O88&xz$=RwUn@sZr3Gt6s zt_yJJ$Q|dLH#iuyZLEGjrKE|gwKh`Vk#V!d8z$Lb$j4>)j|SsF5AEIiOn?-~haT9X zyZiGuke3Ru1)Ku)ks~+I13Zj($_RV_Zi8OPRVs4Dj$DO+U%@HR6gevbP4J#QL$0#H zT;$3Nd6Gqb4G@mimu#2`+{2WDYgpeB& z-Z%C^wn)lIvIAh=zP&&ZRXeGOOnWxmCe|7tDU`9J4r=8m!RP{l{qS z@k`aFw_|eW3nLUVPLTgO7H3!evg@GJd^x*bTBRNDbYSojVZ`*s^GP=@WuzBeoPL{c z{{4Qa`KzSg_U|aj5Be>Hn2*ODy!fkn((PtUNaOdy3uEse2cIw?1043 zkBE}dpOd7y6s;#z7H%EP?QOa9XNbb!a=}-;Pl4E9Hc&`?~EadD9a%P2m zIf1`GI^-%9JosO}Kxr@+oCfzGXGGw4FckUP0N*2LeOtyV6|!O#h8{bykEEWJl?!XI zwX^(qGkdp3{E4=aWR>^~j((ObSI@y*W0G!MmT3Fnx_#tS5jg|`j$xT=@7EJ8#D zM_Z|UYm!D}_%i4*Y04?od(2i`gC_MG6qKL6KSkV=L(jbS^? zAbMxEgy~7t-e?nQOPvE*GKY-k%-w(HBuQM(Q=z1?W{+XGC?j@yjAS#zyKZQP$V9$?$f#4PR`w34k;pZb5gdX;T8=xQl9UvUuX5h^fz3c_M;cpn+ zgMOBQR`ALNuY2$=B%`l8pb)%ngU0Ylj6OPowb=b$^vW1MBfu#1OA7t^0ggKF`VN5a zaBvljgZI0WFB3PzpZg8m%avbm`Yzh`i|qN+{gR^XglT?PPGl^#jXYnv>~~Y}@z9O< zf9x91zuTk@pJP9+RAu{ap#9gh{n&YpU9@5P&)m$|RMpCgR#WnXix93d?IXY2QC+3$tqPx4=T zIa))DFG!=$hh4=@@0x?VY_byyLfLc=NemT1AJ-U!!{&nr+YD9bO$CEo+WC zYqfRmJpE=zZjmPuo01^*+zzY&e}e0v7;;pE+?XIYUdW9Z^5BX*oQ7Y1_$~hLb0GZs zgO2bU1D1hJ;05%&1N;n{q3_?p=g7q|^xFkY0vAC6k*>m6vRvpOy?+ zk&Lx`+~#N9xu?uwfz84?rIUWL%buq7vC?y!xM}DA{WY4VIbAn5!WXPg4+Z7YXZDY4 zhCI5(RJeId^5Qy2*^Qs`Mft^S7VR6iDlYU+E`<(c&_@<`mNiv09s0L8s!7rHVSaAm z?5NE~_TSJSlYIrPWF9lrpQKyAko_z8Dk&Ly*u(Yw#w+QlOS@mEE^@(*TnvKu@jkSG zwmQ4N{uB5L`B6cB#<4d`;8Em=7`q{cJblMbY=c(F!xQj4@(>3;1Jl4}e4dm>Uev%F zU?IqeeK7^Yke^;~FY@DzcOwC0Lk`s8c>|vLdlf%-=*-Pf6cI~@m43Q;;b)^^ZXuNy zS${-sR7`$nc2eV+o3Y$2*`FW8Q+!KbihP^;p6|#TLqql=Vb6ByxPOxB)A{` z62KC?7tZj>hj-!`-UmYXrG#HD?8G7{3eSe7yZJc>A3oqLcpEBWf+(Csq@2bMGGQ8Z3{mL&GyX3= zI6XgK>c-)JySRy)$l}H)EBbTiZx0Pe7R4VYu`V9wIxG0X~W`@{AnbAU#JkS z?&pz6BBvoTf-fz2Awd6z;fDr&>jW>McVplQcya+{;E4*JzJhM>^%1Ov4_WN=8&D2C zJcGV@fFvEv_}T_p;YR~Z2OGfa*jZl3-JI|`?{Z|B_33*hZzHY= z+K3oZ16fB|y0|2XA2}~B^?pp#a_N$^l$cPo&>?lRS|}+I+k89ke$rp+;&PsFgXM2_ z%jLQEjX8xQ?%kOSdfgEj2DBv$q=m!;je~_Rd@Xy;6%98ti0$UyNJtd3Pi$p&&Pt^I z8l#TP&^2jfv+e(wwYnbTyeyHb=fVoTcESB$kOCPvjtr!OufRR%sv5Wo)*u5N;01J77MZXHzkmmkg$;CA5FMUF zXSI+CV`O3x^g$LrgDc=+WWoZxk8bCHe?b9crX1`CInn)BpaeF+3K;}4YR0kdxI}CqaU>@*#oSJ;6 z%dKi5QDJ_glJ{4CVT9zra))`3uj<*p+b4$~C+@GP*0FwHo?tgq6`4=J7QfGNd8c)< zBHrQAC5_!~>_JYHumz*Y!5{d42LCJIK77Wz2>@G>^q4m5`!O?dGIbHR3SFFbXCj@X2AZQVy7mx-`n>CjO&40xuv`BO}y zvQ0*$Hz}b$;RiFvrxg;D>xg8gFStbc?pRl(gZBIl9&OCf;Ks#?F^W)2) z&`6NC-kp^4qjGChLMd;aIx&2gII`XGFr77y)!a4W<_e4sX{iR)ZW8f0lt%==(OBrwpPV3?HFX#=YR&e?n+yo!Pu`l*N z1$+Z?p!1^WybO35?{*&83Q8j@pFm!00}VD|FS0U+jAWwgCI59C8OcYdd5{%DFap_V zfqOwX7X@E}Lg?sM&&T6|=ix1BZ*s}%X+A}~u$axwa{QEiP(E}hz#@=0@5mo=!q-W+ z0~fKJFb2p2MA;KpEUS8q7c^ z7eOOh_QL}|?wv%y)+2dnn(5c1%3$VR>0tJAH(yj==p4Lt-F15CIzdmd z-?8&!Xa5{rzTtUhfzWiK_K?!6Qv~!M7xsPcN#CD#pk%*3OCt8o3b&Kc+`U0IZa9pr zR^UdPxY6zZ-Y2jUH_Ag6@8K3-k-<9LA{f87efYglA~SQ}53QxLl+A}qM#o0<3~V%2 zuz1{Jep}XF@$Ylq_p75hn+Y_pib^-~H9zaB4gC96V3e{!Q91aJV)L`JR88sMN8Kf_ z3&N^ipZFddZ)+@S8nGS!q~f7=_AGP7utNk;IIR%iDHmq7yT0}b|}5qT0oo^FC+*aLa=cnP<%$89{38!7bk6-a|y zrGlkkByQ)9+lgc2Z-TDK6E$+Q0eT}ZxnL@8&4b*$0CTvF9kXus4%`Y+r;>a6@+Y?#pYn%_%yThkNf^z{B&tE1{Sm|aJkMO^1|s^u-0P0Gek=wy#%$rh=l zx{aFpRr@K7FfZvNL){=H?#Tv<;*JGiFz)yqcN4~r>VOu=-gDf~AK7|`yKVe;KlIQa z_p-))GMslkRv=?J3j%LyN;RyPJLP-YlZnnO^f(?)|6;|l9HS|b-o=%XUc~gdB9=`! zy;M|xVv|ESA%=@^r;tl-jZu(r`YTiX&RZJIuhDykmy>jdzrI$v{;ZqEy8o?(iqzlh zMZZ_H1j1SkC*}q;@aWoyW zR*xSMyT4K;rt<5Q9ar{<`uXH4>$KsLRnv`$tm~!=diH%^DL=j$;cZEN`=>KLTO!nP z+{!Om(q-?dBE1H!t>guX8Ds@XT zI$@mfN%|bkyLsD;=&Q(rD4fTFve+X9kP^;+!?h*)v<|Yu{X1|Oj7Q(*!7{vqli(d> zVjMI=HjW_+svtFX&I6P}MtZ>>>|YH&zxd;=xR1<4f_&(;JhJl`{Dxk?!XCZ`A0k`t z!L#W52*`qLT|}0$z(Tw|rQirS3O+&RM!|YyZW;_i=AMGVVrpTb`bWQM7;^I6q?O(O zyS9=dRHFQ1iw_0GoLmm8#t|d+P+!);$ZfX|=jEsc%b1Q*@}H71qVVBsw=tqE$fIRv zIPuTs(*<9{C^BKQ#&9EI=4>(QgE>al_Swcdat<0sEzL_d%~N!ie8VUosT}@GyIrvb-LM%Y$ju1&4|xedUVM;~KJW$dPz1Ii50&t* z4(}J>yBTDK?*xzm-ZQWj((o(>&$;mX6AXaoK=@3;R#d`U3H)4z7kQ`M-)|uHeF3}= zPov4rR8i#lY5Qg@_wwiSo^1)@R{Wi7t;ZI1&>+V@KW#QGPh~nM&PBbT*)4x>hkMyf zh*`VZ92Hl1of)5BJJHE}b&gw6vtl>u!ra5u8g;TsPFRIaO9>q(EZ~iLp`3m*V4oR( zJ$u^k7IVGk+$oL`q6>N(e=bl9rtym1Y?+lf9%jxHlAfP9YkI(?Y$}g)x~W~lfrMXm zwrRill)ojnWR-)0LzJq{%QtEU_S3(+9hw8#3E(ah9Ko(zqw8y+JX~Ezmy^Lx@E_bA zgF8j=JZOSW$ALs}YX|DXaU)!&!KEm=YYoo8Z8Y4<;G*7=rQ^<12}uQuUfs*8 zQ>*A3r@l9e$xFGM(%0OZu8Lqv^dH$oj917BR`JMumpf`EN9F1ps0X;`4$C!m=$zsm zye%0>sc&D$Ed4~eBkoGGF)OpmJ!aXuPuesGw#0oJ1Sn4tHzuhcv^z@c5SHY@CwRmo z?$4QPnH}P;%_pgZxI?wXEZY+q38JVya%`ElUPLAMKIqkv2oT87*!_C*z;npMDkz0+ zYk+ddNjEr*oLHml7m*iZ%npG47@ME`?cje)RoF6B8%45T75R& zG9~WR=CzFuN6Rhrgxl=8s5fnmM0$DDoh~c-Cbo}L(I%79xR@w-A8qBPI_qgJM%83S z#o02(t<~SiDkrOaTHnz84#9vb1C1{`ojbECotd$MF3+Yry}73nkyy7~f|IwE(Df^0 z8e$K*Wi5ZG^r~!`8)}_4drIib!?b4v4xO;S6>u~PD#B42D2rX@g|qu$Huw>)=HVzD zjtaqgP!F!|gOzZ`3TG>DMh9nm(cymZDjaHJpOxXt1+M;pB5?NDVK=kla3T#>p`)yD zQwZvG@2QUa%3XQra}$9?B03?4n0)YjK}@OAeRCwRE2<;cPvVQ&?PdZz4H< zEaJ6s)==t)G;wPAnzhMId$g=EKmzBE@PnK03#dE(&0;O5AJeZ5-W zo2k6lj^$`?L&{u!7rdCHc$sXkHIGyw(mHo0P2BPzME2ziMD{~#Y^=$}5A3VsKVqL=!hF-VV|I)I1K*LCm#`uYTY zwZ+D2BZr#U*h26u`Wy~E0(1WRapYA8IlYTs7lU_@*D}z>o7Pr(mXVxMwoF5sQnHDT zrREr8Zt?*gS>tO|#-%otFAT`3g-ZA99{YJ&U&Eb(D%t zlU|m*s_QN8KzS;`mY(vE(Msg)D~Fl?85X;hGKzRtTwSTAv6bLC!$%!)nnhpiuxBE7 z?0FpubsMouyWJr|Htrw`{$L=ufUXCj>#1=46Eub62Jiv4AQ?=A+ZSN<|J8Kf;auqd z8QWlWd~MC_=W9LPjMdD@igVL?KBwq0Fq35s~owUO&(2pZn73 zTqm#ld7k&D^T#=GYl}^I41R-44Y=ci8)3K+f}0R<9ee;c$#78Uz59Jx;O3*?G+5XW z7ddfSD^st&qk&I3J~wmxW{G=J7fpn{35RH@DgdJ{9rYh}(TDk`n;coW2f8m$ey*jgb@z$>6Dv)~tw5zl5h*(93A|`|QEnScoo?!`BP=DgnnpE_mAk z&%)bH_^Lx!8Q>`zlz^vouo4@79Ns+P?Hg!_O;17ho`4mg6gn6L&s|^=e7}X?Zjce3 zQ~=FE0lXD)U?{qmi5zIa`*YA9-6O*1UcF$tbY5L+J_=WHE%%FQeC`_Tvr%l`uJPh8 zZvQYj=AuCNNxHiJO6l-0@f#u6siBHjy}~AN zK}yhxI>lUX(#hXN_vQTT#ebByge0xBu7AEhd$op#=eQiloQGuxjnFk$?X$~+)W%ob zsnA0`&=VAccXRmt1iz2rR|Wp2;LjEQ2Ho?d5Z+`ILg8P2~ ze}apk7WyZT{!N2>v4v8gHN2$5!#cR2V0(@x;D?^x$vme@Ul)rR1vh7 z=6vhnX0y&mZMB!T*#5gK&-SQhmCj>bYUyV@4h$_8(t2ZLf{e<{)cy;6xhHKcpOo>m z+~OLD(zKk@5)%5PHRV{qwltmBvgGchRdXV*W!maP+^o(V`^38+%#$9cb)6pOX+8=1 zOs;wDaX^#)xPYf$i<1lesHWqUaSu+(rgKvgZw1K$@>=}iqz}9SH>v329;4kZ9syVI zzFNWE0c`1hxHCW(AAoXj*aL@*a7P4p`#^E91Kf))#(^bZ4;=TPn~89n0v3Tn=v*IY z0_Q(KEjT`nt{H$|!9=(ZLie=c-W@c9^ChrBI<4{iE15qx0wgDdzm;bn-7xlgEG2)S zKG4#kYe(G9%P%cgb*CnxkNK>c`bUeErS($ICfebgz0!3=7n$fvFM8h=3qpf0~*9W-GF$?9JNwvht$Ng5_U z56-`0PG&f|*(LJw!7J|L=4-TNb@HJ%t>x7kt-dfu^l#^Q1^JR3g|Bh;XD(r zo8fv6?1k$o~Zc0;#dH1=!hF zpbp$Nf*f$E0GAAKsSnnJC(z>za2t%p&VB*)(d!>2*Gfws)rFKLS%&^@@~K$sH5KEz zH%xjdO`hR}tD?U{Zrq49Y+gZM>i zS#}*=Maba_%W%Tw9`#Zqj*0ramPc}89*|zpBl!OxZ_wj8Q1;C3&zFD>aNP(h!TCi{ z9_}sS*cXmlKsz|5hC4m59Q~dH^Wc;Lz5NK632+#No~DB0*yeh;+d)6Q;qE7R8U6G1 z+Wo#F!Du*Agd-F1H`t7~(VFOPLe<;BZELnAd5`-{Kv%9Z*PGA0cZ zohob@FKeh)HhI0JC_ngdysoVF{HYcHy?>|lmA6CQ6qn_WP+EtzKKWK8o$C`~bK_dl zY-?GPRJ=*%4pEuf!Yt61<5`bm#X zmIW`s)hsB8J_^B^D5wIOfsx>Cum+TZTRYGL901oqb!@yF$YZCgLZv6|Sx*vs0)a_yjsf8V8MCZp;|Da-v~to;irn}5VL z*w3y}(H=~(ugZ9!5+JutT=(E*w(vvaFw3AzlXXFVZwATNsEj04Hi^+6%4Y2sR ztZ~rtg}cb3ac-%e!#T#L2i*>p$=RN@`l952?MkzGdZoIdja=qN?codJ{dpR`b=QK? z>rZeWfF1|JeLKhk=eNPvpg4NF2Kpci-;o7xY%>cShl0%LuPXQh&J5wq8B7He(d!YA z3QmuMsc>2Z_JP@OTL#X7ap?bF@GBfYhg(iK4aHWwV+R=FI2yfIL+{UnHQ=8eh8+{C zOKkM)mln1~rB3yFi!Lw()f5LA{tKZ$$h;wOPPlDawx+O7>e8yTtP{;2!%;zcV=h5| znSeqo?`0YmcAhE@E8{744qrBdGk!YEw4+wRmQts#Gg-L*u`+BkH(YK=5|vLiV*Nd0 zbM8uPav($Nn=|5tf5ezO14S)vvB~-A8!(ztR){_8C>4_!lBccyWkdUA!`EtkWW`WC zo+ZHWkp$D1Z{_e`1+pLq%3ul@hg|%@u7@BO$BYR6{|5s$;vI4^0LtM_uLYlD_bHGU zU*v-w-IheBxsZ#C$b}hpJ`g+q8&t)p@V*TO!S^sob9XeXU}J17CS|-tu>5oXt@Ngf%ty8>G#Lbc_<9GnsH2{gP3$c6 zJ6DZm@>aX8@Qx@}Y2O`)oqM2sFS;`(L3@#_ktXi+irX8yvgfZ|Rtj&cZb`R2E_Eq+ z-|V_r(0hA%pd`P0Us6=q+j~bcKJ+?0$g1K@dXg;^>D1}k=COMF&P+l<*Bp1;;)g16 zIL!b*gT!!22A6W6F-Q!jL~vLKcL(8)A3OoJqw{v?d^w!*qU%9$I|;YUaHbqXO02x+ zUXSflB(5B7CN6KJRGeahfnmzdV(<2PSa%SAq}KG(dSf3c z#1XiM#*c8N_)WMSjT|`%e=WsjUgp?id2Dv3t(F`_RkG0{g$G4UUNb6*I0rWn--2I1 z_%(u0bMO;50J5ROec%R22LG=>ZFD;ltUxX*kP9N@AQ(9?M-GhOe;7atfW_hpyiR&m%WM;3{|nIpRi+Y(YBYi5r{%myoOLcoXEX z375bruiboQVIxSe4IIcHC#VSSfJDhcmG6_qz9G1&a#)mh;9rOjMkV9AS1}KC4ZGjocnV0eI9qYkikQI5l4c-H5!B)@< zyR#p8%LD5`dF0O-><0<3OY?Yh4k3@dAPMs5h5Wq)C6L23a2cFJ9(}N1r;)o4pfvIp z0`?(i7RXsTa+Qu;y#g7KuL+P*Z{C)z{m5aKk@lyiZrQ|!w<9a}J!_6IsJcyjC_+1h zxjiIV?0M{dwo}u0WmrPxS4P?;4{qt-eL0ew%uq?3NUu|*XppFRBjMHb#eFrm|6XO8 zH#BA4_xs*fWEOiyzHhmu!`XfD#a&4Q5#z@D>@Ts_YAmvEOxgM}Yl||j-|AW&x$VnN zlXF#`U2U1RJ-@5J#=b`8=C3QXG@Nf_?jPIlYsq`Q8yPV~Ciswnk02>BKnKc#*WjKJ z8`A<_#@5tgYtrD}2adDBCb+$YjhO|N;8X)#1P{S!EBFf}htn8v0h{w1j)|}}W?&HL zhd)~^U~35fa}L)EaBTp$NuV^`He*8`T-ohJ&tHdL^XhXs>79(e#n&C z-(o)4ntraT{p(ur{Zy%wQ}Tm8@ef!Hem(dmyZVu-r{c7D-D`bm-gtAvjil?=RfQIo zYHZeLSfdpzlccw;jUQU{br1dt8Qw3U%k%K7g$`eW*KyDl9)G}_2E1JYjnUb{ z|GMkB`+bapw=V5|y$AkeKvnPw$OW$l;PnT{gwG_}O`6xAcS!S+9ZS%PO&ipE92cI4&1#fjg{$=g>1gi@Bi#K&7{3v_IJ(5+1W=A5v_Pjfifzi_ylgZhBj zNAge3pD5~fS|~O;1w8I?wCNV57YGgA*FCY*9~__a&6V%t>^T9dZfeR7SuO2{3T`e* z8RsbO`*^-WKh@!H29$=Uo7m`icw$2jjnTgr@F%zc54_mcV$i{M_g=1`AN+)(U#HQp zcz7{~7e}xNn_3D!MxUC&x9Al={G0~6;i(@UMnPZnt8gWTi~3>c5swP{iJX#nrTJx| zY>&Q76Y`|k%an`Zp%nd!T<$CSm!n@ExU5?_ui+FC%h)m0q2&DNwu)Xx%mFu}4pPdl zT*COTjhwL=%}PHW7N67{ZsjcQYUJYY2UJ` zZbrdbI1& z7W4thv61U=c^@t<;Lsl&24&H$AD{!A5~5qC;1n1P*GH!fGZl5KPdM0Fbc7dq-+RX? z+n5${%%FdV$W z$Kji*UYK0c@ZyWkQZbGk z(?5PM$NnNyxGrB9yZ&wuL_tl1-LJ2~;XiN(E_vWC8hj77!R0T|0ljnwzk^wDOov_` z0Bylnpa&c+VJ~&j%ZKROICfDT@7fBSQNh(AFdn3YD`NDI5w2$7s>rogKiZ>K-_^eN zTfV*Q&b+-rX0*o1ZpvRnHt`;v*_p29E1sO@&+Ij+^L(Sh32KAzBHqD!Kh=L0o)Ba#F8CEVqQ|{4p{+FHkWVZ< z#ZUA4VYJ|Do3C*73EQXuXG>rZoOOWNaKr-#s-P=etbhyX-R1wb6FuUClQ-zodANB2 zj$u2Gz*Rixi??kC?!Kd6PqC@2a488^f-`VigST!8Oo!uEP#yhrf#Wo=6K;LrHV0(C zyqj%z^zQ?>0oHt94yfh4=F)Co)BI7bXKS_jC3CR*9gCi;>~kB<<-giI#J{xKecjjQ zCaj-6&HixRu`JGyd;8oc>Po#YLXW<_{$p)9Kh5g-CAXUG)8%B3ws)*UgJX<3zwEE+ z{8AOSt}?A;x1732^+3?lt(g0Z>-=SA?RIWS_YUG$A4kU4G~4(~TmD`&mig$A7T3y| zHrK6G-P~{Yi0X~!w)qI>zv6AzvnPI$ic)l3-xgTa+x=eDkp(kw33Ns_w!x2vyT5)f zG9d^WfhC{<`l|sxL{@^4k$1>Q5;BqkI%0#Jz+hyD5!tZ>BS9}@MjIJnMn=j(FJ$Bj z*bQ3X{e6WD2*P1w)-ON$-YL zac`BnlYX8g?80GcI9j9i89*2d(B(kYVVl6r=lgSbLxWNxByO_;P5H<4dg|?r$8|{(+7#+E*hMMLm9YI z1B<{h^n4z4!n@fCXPoGF5=aJzMsQb+p0mJJJvN#I&UC;;I7)(}X)pn zq+Wg?qyLj8m~rPrbii59Ov_<2L2Fw*L79_eB(z^Ca#<5CHLrPB3Jjceq1x^-fBucj zLdV>Ng2v{dnGpT&ITu6ks0nXB%@b0eZ+l86Taby?XzBRLS?C_}{U;!6xZofwrA2L6 z%jam8Vksz9XR!@;t#HSJ9$Fgg=5HE&ZM6G!vhglS;V=($hOaZ1Pd`&e-uV&CKQHxtj1H+mBxl`y-p0H`H^{p zzd!y)TXrRBdsS3u$5Kq_2kC~}&z4@QEG&k`unA|~Y+sJL+483&Hm;Q7*7fYL+r3*e z5w}Z1j-Ptt6cJz2s#IGRK@nYZhp1iTrpoNn3*y-R&`|PqI*N=^vdE~Qw_)wC$aBbR z>l-#}azomrTS#}tW+OV*KM>DWgoeg%!8biTp8>hxSsGjf&%MR4!M^GusAqJLNX$~zui zw6#orquTj(?r`^V-iyth7be!-$6s1?JtN-P)at7)^|rNaJ74~ZWrk}#?aY~9pFUsx zcGtVoVmR;82%YG`lydLHwnW31DJ$bo1HQcU3EI3fo>Hy&Gz`wk(eWtkF)cc+2B((j zsyj#ww|w9MxP1u)|m3Iv?bL<2*Rlfy-;45IUX(x2MqYX*ec?+aB;W z9M^%&aJ?VhJ_shjbt$+5uE9A!Tx)`6;2F3#h3kcE_g~rsb~`7OcPc0ey%K2lWaJ7t zIe+3UU~D7bQ_|<5>`6oE@kgZkGdMIN0{09gbX>>7Jg`GL7?a@p(|S$GO2p4sg|6-b1PID#LLl>+14 zUsn#+f_tzJW*{#z)rFmKM~2Q}C$_)@WalC>^8s8%W}J|jH823#d4tSYAv3|C3^HSl z%t#?CHpqxONR6y$gH*`MIq)M$iM_A|E5W09CxXC>$kaD51lf{8mSjN zLDTAhy_+wIk_M9&?FmM+QaAQbB*$paAC)o=F`ANAmE7}tl#tV#N==Qvh4hH`X(LUE z_q5sKQb(t(J{wVsJay!GvzIXQpO%XBZ`D1VCT1iKzEKPr$b}>Fumk_s;PnZ}1;29O z8So|i?!{IZfUm$_Y=DM58oJqD7K?q-`|O)K&1s9v;qN`-OSBY(2_4 zBIlwPrk(|9q%_Fx82YwW4)PL|#p?K@A-Q+=7DD5XDU{@Q`oS)T)Kw#>AiF4k9LTVK(}o$iyZq+GKv zBr7$E5lk}5o3a+s6ne$bmh*s?hL=HuY?760fl^c=8t$wNcDou3=E9*QI{N?=Kxa+i zE)-k`iSQoqfr4NPI$Z^)$#AHN4qJc=;CHxviMKx)oz{oj0&p1o2FKQLya+O(+ah2U zsErKRgQ?&!D1a=O;j_RMa1@k6Hp-9<0%SoCS;#-B%NVD+b1YYBOM_D3K(Y>}^kq`6 zPKRQyB|=TN?wh=VmkIJOFiNz_c|9$@l21(594IE{H(z(PZrY< zPa75<3F+jYq^TnLuGf#an4CMxuV=tgeBDUHNuSA-hSWwW+sCe4bK1xBr|Bt;_=~A5 zdBF!9sYneZpV$vN7G1ZC&~-C6rBY#`8@ni`LcrO5lKMjW#o`kz$_~05Su|HS&T9P< zGf>jo^`D76dRhj)g%e?0}cXam#WT@{|K(Palv9lq(%;Ruipo*#f_@cjVHfcJ9n zB>d-soap)i_&){)g2Bkc6mpOT?}y`(1o`=E}OE`$@C!&vehTqZVho8Ym*kwI*(*_iVyL!0e!n?Z$SMT9y4lV?-zjL^KEp9)7+s}YG zaIgvzWa%;~2evsVS)+>jQ?HVfpTqL=nO&XH<$eCMb0Bt3_g zaF8=qlTC0-j(IQ@)mEqZF`3l3?=l?P1c!bybBPC2OflEG-FDL*#qb4J^jk?FBRfY@F56pAWeGS={~*Zk-6G z8}0V!8@PsDy#p8d;4kz_1WsnaJh;(;8+P>R`hUH`uEv00{@YnNt3#hYfSaHNTn2zG z;2*ekN8g@Dj{R)#+`UUH$btUtARE-^k>YgQ zvBlq>>Kdxy3=PxnDj{Cf5>xboS3^nNRVJsR?WT3_ne1687NIf_Bn-LIY}#yhqO{(` z{Yj(>ErYVIf~k^PgzTb;D`$>DzQ(cyB|)UFE74~qR~B`(27~Z2clu*Wq#~Msa+DvN z##~<3RlUrm>UwlsBb9Vnjg+|Y-KG+e>j`_?cO6fge^Wa;=r(vAIoYb*DA8e}Bhf5& z{++w89lW=KQ{X(Pgf2$Ge?6Fh9J~g-@y^bHzrX{?!DVm?G>3m*@DW%5u7aNEG8=Ni z2L__sG{^}Jyt~5pSC9nW<-nKlO$D#*@Hq=o!{=*wtVPG4T;BCP2KvEoVl}tmlN4DS zhvXvNBRzK74U1}4lf&)bvP(~}o!{oAQ7)AZd%GM?DLUlpe)E5S+(~@RJMuO{*EQm^ z`MIo8%?*va($tC_EYvv%9Cf=M(Jt8a^TtO!V)7(S@N{49;{4WhAU5Ofea_;hSo_(V zYpD+jQs&)5`t4_%KeXMdM28>2)fR648(kE_8}|&|Q^PHra622^E(Dz_1MP9kCftk) zok;*&!7rc$x-^3Bkm9y#U?{q?2J+(8nxFt~{_fK5jsN2Ia=5)8xP+TuAYe<^$r3A+ zQj{*VYbfDt)-ottd_3D6c4KE=Y21C{M%0o}XlVa*Xy)n^@!r;0VMXcg9CEP}q>+P> z5l=UBNyw}U4^sq|MP!NHyciWYF~0X)TcfgITf@xOR78H~v&I*%9kN3`iwW~R_k7nf zDGh&|UJ+I-G9iz9@5jAe(G6R4A`cwG-6@duQ1BDB&;{APge(ie#~qLxUVK1CY?}*6 zhPyunKO)n~*en^`xeIi}og=|FU!(&hr=j{^x-E+I9Ib@3ZUZeL=c-3( zg92g%odbxN*ayfPwZBBGaSZXRaD1)T+v%>4wiuwu|8zP=x2+?Se5j*=lD%y>4FZSf8 z_Jj>xPi-%4DJ>ivPRq^D=!zUPzf&}SeUW@NV~Duh?0;XIB~VLSEs3S3l}2u)w^4OZ zbdt{3esMg}{)K4PvV=V8I^EB(YhR~sor`EVb$YGi-bgIJ^n;#;Ti44^C0M=J&ZzAY z>+Yb-$+Y~|kYL$H68*C?Vxzx1Kg4Fq_+4+w)XJaEcc&E488@&9OoCHgbjJyd2kYQ= z4Lpl&qx^5%z-3SgUHb`|z;y_y1?Lyx)*0l1<1lnE1*`+@;d}&~1Z~mDPvAFD0GY@E zEs=>?um+pSfQ(duf!NH$$i`h{;w!p30}5Q)?Swwq3%kmVM{8*BMfFoJFXWYok&yiAvr}FzS*;(GN4K+)hj!#)54yc&y!-pygnub`wt-J^ z_}l~u;BznDIu@`Jeh;F<^oO@pFc{uO;fo!AM)(ST!1nG(r(c4@@K+6gC*aQ% zT!TLmcnIX&vMIM0u`p<6^7nCObP2jhOUCHq)51I{5|Dgq&@9Pug{t38#AfBfj+ulm z3&jgkY3FJNVoc!CJB; zJEr#gS9N0&xUUKLPK=yp`7XgPqoI%{J|(Rw@vcPY9JdMCu-@*Cb>Sio4!*(xGj6X8 zW`WM=A~{_2ff?wGAZ|Sm*5cOxaNCc#B?WG23+kW?Ss*X=^CjqmTbJR+(ztCgZaauB z+(!1(kbNTDyb}BhZh?!pNH*RXH?)opGz=~cXAdr3X?@-G@RrT@)y$-9EA64ZMI?f+ zIJ6&@Txn+;`=M?1Vrx(M4Vu=6VOMUkO~yns3F|aRKh`0gZ^~(i=DK+7*W1PyqM9kr#L$`~+9!=m70-YY!6~?kg&QICAQp~tzzVq1f+J^89gYsdg)KgVTmeaacE9iOrqh#IqitI5z>c;Jz3f0B;}*k3eE<%hCnq5(3_rkX*adzEH~;&2WReV-^cGgpZmQCD$~tw7Y}qW6g2%d; zg7aDq^_az5G9IS4#ic*!AcUCW%e%U zm%wob$KZM~0_uwap#_n$G;EXN?JnQh2nEL&rcZH8>9^=GXzSYlyU9E*(`emg*e-ZX zR3k`DhRWTJA&iDoX4<03{~qrT;SdU2W}1b^tU8*{J*19SNA#nvRkb0+8u&-cMJ@H6-e?*t+I%Yt`6YvkbpSPwRU^vKC!pG}L?eO~IKS2d5Gs^G~YWi3KDYo1OX|KW~qVvs%EgW*(sCg@FW#ScxjlSp+%FGtp`^y%(3ID8nFT)?-$k@te=NER~k zOd<;>unh%ZCNi-GKEXRAglyagmyr!pWa20o0QQ4B;BjQ-3qDJ{MP@EyBW{C9U^@5< zSz^S7M1pbzOH) z{wkHEtL}QFpzM?0cfOhgdMOd~f04vb|^N8K0qLLzcO&H2Zm@>e7zHYPFyDYh>G- z{Cr-ArTDbmv1S;2F?`{5Pj&LlfxgJ%-j@vXmGTFQA`-c)OYaa0>hJ!3ufz8jydgU9 zeHFY8YQz6suo0g1;nfNZhu@#zDQrLh_#FHVzq;@n3Z94OM|dl^;aeXx#a5WYb09ny zfv-Rhc>V~F&Da7rbee zbC-t6Ahf7DxQBO}joq_~KJR(DGy~_qQ+GT@4!z8OBt7XN@3=V2W+XnfbLtY=U+Kd_ z>Hf<+R=O{F2bPFWbUK#vZogimOcyNB>nsuX=&Cv-xN~4X|8wU{JUjYd-8!rk`8$28 zpXt~O-yU@6;~P@(c4g!Cb&a=rA~dvhMqq?ilDv#|lBS>K6&bVn{(_pSu3UI!La&w4 zV|9=Yo`pbpkP4pV!Ax)*yo{b}z`MnNJqHEg)d{=>E`ik8{(Mjlp6B8DH~dD!?$PEdnu*GpJ)%dJ$8FzofX_&8=z&wKJLHH_}(?(+(LmR`}&tpVxu;legr{p81kZm zx5oWvSjqUJYzD}$>k+t}3y5%QH&k_bBbH^hxkcdLWA@a)+k1@PT1qjf?V5|nY2neY z*K8EE+x_#Lm}DQfwE7+Q7(fm@@y0&`&mtH4|Lr{J3g*CfJvaouLhtWm|0j@#9r))( z|IqKdMh+~%H=ro;kOdw_ zE;2wq*O|Qu{{M$P$lAR6NmC=ahtWsQ28g zv^er+k$m#IjBD8}b6`%Rl=cN`TOF!g>z2qPW)#^EnfYcGq)t=Ma_RgWJ03JftfMzE zdzR9jSH|;6>vy+_C!YgJVy;+>wFi*%gj}%BY*!?o%4Farx*^V&8~2!O`n#%5$g?}A z5655O<<7~nb|_wqS<2D#CyENta+?BIo_Cxop;Wige`Qh{lsDuqLf!lC&{w4Sp z-QNL^!nG0{r@-kxxReEdqxlxmAwD+f%>oBA_eS|XUQH-?$3L3_AFsdGFyY? zi|gdu+hT-Yu9y;?^(oI>PPuyH@8Y4bF5!NPHN&JafZJ##4@9jQRSm01cnD|=Kd<~&kg$D{{}v>yjN51f(QlO zVdLV`G)eM*DKZ~^CobvjX7xV&7lJJyJ+`3;w8bVAArBnz&V(({1R3C88SKY4Y=d0L zg)?&D3HpO(*o+ro3-}#*X+&P+kdu0_6I=$jkRKxC<^*z+i=2of9}3_t&=TG61ZnYE zAOjo#hr!?A59DYITfmBZ1cDVT7Hh`di^8J9@`@5NX}))bkFU!x39r4PXZ}&np8V<% z3)k2C|6V@$bFKUpZLPS}W!dr+W7;&oWa$SUHVool_DdyC?)M%@VL$7gC?ox&|A^W-7x04Z@lhJckoxvnShx`AFR z!z&rQHiL}tYYyHu-pxrGd@IBACVUB?&lz9~JoSK5w!447D7+b?=e+Rb4_3h!89Wi7 e-z4BYc;i8jpMz=ebOj#D(Bnbeo!w{mpZ|X!%kFdl literal 0 HcmV?d00001 diff --git a/demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex b/demos/offline_ivf/tests/test_data/coco_lang/OPQ4_IVF256_PQ4.faissindex new file mode 100644 index 0000000000000000000000000000000000000000..582159767d472205c57fbb311e0c176816dcb1c0 GIT binary patch literal 23188 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%0DOio^_klJw}YY;T! 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 hOZ>yMg6^ar(+oW1ww^VtjIJ-mf^czC3AxNraS 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