51 Commits

Author SHA1 Message Date
Matthijs Douze
9db182460c Relax IVFFlatDedup test (#3077)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/3077

This diff relaxes some IVFFlatDedup tests where distances are slighlty different over runs.
Should fix

https://app.circleci.com/pipelines/github/facebookresearch/faiss/4709/workflows/8c8213bf-8fe0-4c4e-9a7d-991f44bf1010/jobs/25551

https://app.circleci.com/pipelines/github/facebookresearch/faiss/4709/workflows/8c8213bf-8fe0-4c4e-9a7d-991f44bf1010/jobs/25547

Reviewed By: algoriddle

Differential Revision: D49732349

fbshipit-source-id: 728b9885c6b7d6ba697ccb6bacc0abd0ee2b0679
2023-09-29 01:16:59 -07:00
Matthijs Douze
687457b2f4 Access graph structure for NSG (#2984)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2984

It is not entirely trivial to access the NSG graph structure from Python (although it is a fixed size N-by-K matrix of vector ids).
This diff adds an inspect_tools function to do that.

Reviewed By: algoriddle

Differential Revision: D48026775

fbshipit-source-id: 94cd7be7f656bcd333d62586531f287ea8e052e5
2023-08-04 06:55:24 -07:00
Matthijs Douze
07fe2b622f Binary cloning and GPU range search (#2916)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2916

Overall better support for binary indexes:
- cloning (to CPU and GPU), only for BinaryFlat for now
- fix bug in reconstruct_n
- range_search_max_results

Reviewed By: algoriddle

Differential Revision: D46755778

fbshipit-source-id: 777ad90aff5c54a77f9685ed6512247a922c6ef5
2023-06-19 06:05:14 -07:00
Gergely Szilvasy
092606b293 bbs producer/consumer threading (#2901)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2901

This diff allows each GPU to work independently, a hot centroid (eg. out-of-distribution queries that hit a centroid heavily) will only block the one GPU that is processing it, others will continue to pick up work independently.

Reviewed By: mdouze

Differential Revision: D46521298

fbshipit-source-id: 171cb06cce8b2d16b7bd744799b105b3cd525be3
2023-06-14 07:58:44 -07:00
Matthijs Douze
6800ebef83 Support independent IVF coarse quantizer
Summary: In the IndexIVFIndepenentQuantizer, the coarse quantizer is applied on the input vectors, but the encoding is performed on a vector-transformed version of the database elements.

Reviewed By: alexanderguzhva

Differential Revision: D45950970

fbshipit-source-id: 30f6cf46d44174b1d99a12384b7d5e2d475c1f88
2023-05-26 02:59:01 -07:00
Matthijs Douze
b9ea339617 support range search from GPU (#2860)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2860

Optimized range search function where the GPU computes by default and falls back on gpu for queries where there are too many results.

Parallelize the CPU to GPU cloning, it seems to work.

Support range_search_preassigned in Python

Fix long-standing issue with SWIG exposed functions that did not release the GIL (in particular the MapLong2Long).

Adds a MapInt64ToInt64 that is more efficient than MapLong2Long.

Reviewed By: algoriddle

Differential Revision: D45672301

fbshipit-source-id: 2e77397c40083818584dbafa5427149359a2abfd
2023-05-16 00:27:53 -07:00
Matthijs Douze
2d8886cd4f IVF sorting routine (#2846)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2846

Adds a function to ivf_contrib to sort the inverted lists by size without changing the results. Also moves big_batch_search to its own module.

Reviewed By: algoriddle

Differential Revision: D45565880

fbshipit-source-id: 091a1c1c074f860d6953bf20d04523292fb55e1a
2023-05-04 09:59:06 -07:00
Matthijs Douze
3704bbe4a7 Add GIST1M to datasets
Summary: GIST1M is on the fair cluster but was not added to the datsets.py

Reviewed By: alexanderguzhva

Differential Revision: D45276664

fbshipit-source-id: 8db41d61b78983f5d01dedca1790618f80f6bc78
2023-04-26 02:07:11 -07:00
Matthijs Douze
016aa04602 make balanced clusters the default (#2796)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2796

This diff makes balanced clusters the default for 2-level clustering. This seems to improve a bit over the default uniform clusters, see

https://github.com/fairinternal/faiss_improvements/blob/master/better_coarse_quantizer/two_level_clustering.ipynb

Warning: the nc2 argument of two_level_clustering becomes the *total* number of clusters.

Reviewed By: algoriddle

Differential Revision: D44421222

fbshipit-source-id: 951b7fc043be4a41762a7e6f7a6fcfb71e303832
2023-03-28 07:23:30 -07:00
Matthijs Douze
581760302f evaluation script + IVF block search (#2781)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2781

This is a benchmarking script for keypoint matching with labelled ground-truth.

Reviewed By: alexanderguzhva

Differential Revision: D44036091

fbshipit-source-id: d9d7c089c4d172b66f33dc968c00713a1b79c2d1
2023-03-24 13:54:08 -07:00
Matthijs Douze
0200d131fc fix windows test (#2775)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2775

Reviewed By: algoriddle

Differential Revision: D44210010

fbshipit-source-id: b9b620a4b0a874e09ee2f6082ff0f9463716fdf4
2023-03-21 05:34:50 -07:00
Matthijs Douze
2d7dd5b0a6 support checkpointing in big batch search
Summary: Big batch search can be running for hours so it's useful to have a checkpointing mechanism in case it's run on a best-effort cluster queue.

Reviewed By: algoriddle

Differential Revision: D44059758

fbshipit-source-id: 5cb5e80800c6d2bf76d9f6cb40736009cd5d4b8e
2023-03-14 11:11:50 -07:00
Iurii Makarov
8ccd800986 Implemented Jaccard distance (#2684)
Summary:
**Summary**
Implemented Jaccard distance requested in this issue: https://github.com/facebookresearch/faiss/issues/1299
**Test plan**
Run: make -C build test
Output: 100% tests passed, 0 tests failed out of 174

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

Reviewed By: mdouze

Differential Revision: D43398833

Pulled By: lvoursl

fbshipit-source-id: b38cf27a7858842efe967bcb1033977863716a76
2023-02-27 07:49:42 -08:00
Matthijs Douze
a80c96c0de Evaluation script for hybrid CPU / GPU search
Summary:
Implementation of various combinations of coarse quantization / scaning code on CPU and GPU.

Used to generate the results of

https://github.com/facebookresearch/faiss/wiki/Hybrid-CPU-GPU-search-and-multiple-GPUs

Reviewed By: alexanderguzhva

Differential Revision: D43041802

fbshipit-source-id: 12608812ab351d60d4a6dc45be1ca493f76d4375
2023-02-15 12:55:06 -08:00
Matthijs Douze
8fc3775472 building blocks for hybrid CPU / GPU search (#2638)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2638

This diff is a more streamlined way of searching IVF indexes with precomputed clusters.
This will be used for experiments with hybrid CPU / GPU search.

Reviewed By: algoriddle

Differential Revision: D41301032

fbshipit-source-id: a1d645fd0f2bf806454dfd04971edc0a6200d20d
2023-01-12 13:34:44 -08:00
Jeff Johnson
590f6fb47d Faiss pytorch bridge: revert to TypedStorage (#2631)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2631

The pytorch in fbcode complains about `storage()` saying it is deprecated and we need to move to UntypedStorage `_storage()`, while github CI is using an older version of pytorch where `_storage()` doesn't exist.

As it is only a warning not an error in fbcode, revert to the old form, but we'll likely have to change to `_storage()` eventually.

Reviewed By: alexanderguzhva

Differential Revision: D42107029

fbshipit-source-id: 699c15932e6ae48cd1c60ebb7212dcd9b47626f6
2022-12-16 15:38:08 -08:00
Jeff Johnson
4bb7aa4b77 Faiss + Torch fixes, re-enable k = 2048
Summary:
This diff fixes four separate issues:

- Using the pytorch bridge produces the following deprecation warning. We switch to `_storage()` instead.
```
torch_utils.py:51: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor._storage() instead of tensor.storage()
  x.storage().data_ptr() + x.storage_offset() * 4)
```
- The `storage_offset` for certain types was wrong, but this would only affect torch tensors that were a view into a storage that didn't begin at the beginning.
- The `reconstruct_n` numpy pytorch bridge function allowed passing `-1` for `ni` which indicated that all vectors should be reconstructed. The torch bridge didn't follow this and throw an error:
```
TypeError: torch_replacement_reconstruct_n() missing 2 required positional arguments: 'n0' and 'ni'
```
- Choosing values in the range (1024, 2048] for `k` or `nprobe` were broken in D37777979; this is now fixed again.

Reviewed By: alexanderguzhva

Differential Revision: D42041239

fbshipit-source-id: c7d9b4aba63db8ac73e271c8ef34e231002963d9
2022-12-14 16:21:22 -08:00
Matthijs Douze
fa53e2c941 Implementation of big-batch IVF search (single machine) (#2567)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2567

Intuitively, it should be easier to handle big-batch searches because all distance computations for a set of queries can be done locally within each inverted list.

This benchmark implements this in pure python (but should be close to optimal in terms of speed), on CPU for IndexIVFFlat, IndexIVFPQ and IndexIVFScalarQuantizer. GPU is also supported.

The results are not systematically better, see https://docs.google.com/document/d/1d3YuV8uN7hut6aOATCOMx8Ut-QEl_oRnJdPgDBRF1QA/edit?usp=sharing

Reviewed By: algoriddle

Differential Revision: D41098338

fbshipit-source-id: 479e471b0d541f242d420f581775d57b708a61b8
2022-12-09 08:53:13 -08:00
Matthijs Douze
a996a4a052 Put idx_t in the faiss namespace (#2582)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2582

A few more or less cosmetic improvements
* Index::idx_t was in the Index object, which does not make much sense, this diff moves it to faiss::idx_t
* replace multiprocessing.dummy with multiprocessing.pool
* add Alexandr as a core contributor of Faiss in the README ;-)

```
for i in $( find . -name \*.cu -o -name \*.cuh -o -name \*.h -o -name \*.cpp ) ; do
  sed -i s/Index::idx_t/idx_t/ $i
done
```

For the fbcode deps:
```
for i in $( fbgs Index::idx_t --exclude fbcode/faiss -l ) ; do
   sed -i s/Index::idx_t/idx_t/ $i
done
```

Reviewed By: algoriddle

Differential Revision: D41437507

fbshipit-source-id: 8300f2a3ae97cace6172f3f14a9be3a83999fb89
2022-11-30 08:25:30 -08:00
Jeff Johnson
e3d12c7133 Faiss GPU: add device specifier for bfKnn (#2584)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2584

The `bfKnn` C++ function and `knn_gpu` Python functions for running brute-force k-NN on the GPU did not have a way to specify the GPU device on which the search should run, as it simply used the current thread-local `cudaGetDevice(...)` setting in the CUDA runtime API.

This is unlike the GPU index classes which takes a device argument in the index config struct. Now, both the C++ and Python interface to bfKnn have an optional argument to specify the device.

Default behavior is the current behavior; if the `device` is -1 then the current CUDA thread-local device is used, otherwise we perform the work on the desired device.

Reviewed By: mdouze

Differential Revision: D41448254

fbshipit-source-id: a63c68c12edbe4d725b9fc2a749d5dc935574e12
2022-11-21 18:20:32 -08:00
Matthijs Douze
dd814b5f14 IVF filtering based on IDSelector (no init split) (#2483)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2483

This diff changes the following:
1. all search functions now take a `SearchParameters` argument that overrides the internal search parameters
2. the default implementation for most classes throws when the params argument is non-nullptr / non-None
3. the IndexIVF and IndexHNSW classes have functioning SearchPArameters
4. the SearchParameters includes an IDSelector that can search only in a subset of the index based on a defined subset of ids

There is also some refactoring: the IDSelector was moved to its own .h/.cpp and python/__init__.py is spit in parts.

The diff is quite bulky because the search function prototypes need to be changed in all index classes.

Things to fix in subsequent diffs:

- support SearchParameters for more index types (Flat variants)

- better sub-object ownership for SearchParams (with std::unique_ptr?)

- special handling of IDSelectorRange to make it faster

Reviewed By: alexanderguzhva

Differential Revision: D39852589

fbshipit-source-id: 4988bdb5b9bee1207cd327d3f80bf5e0e2467fe1
2022-09-30 06:40:03 -07:00
François Travais
b74ac352d3 Fix RPC lib logging (#2433)
Summary:
I couldn't run the client-server implementation because of the logging. Indeed `LOG.info('Connected by', addr, end=' ')` raised an exception (`end` is not recognised as a valid argument).

Other warnings are also showing up. This PR clean things up a bit and fixes the client-server.

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

Reviewed By: alexanderguzhva

Differential Revision: D39167576

Pulled By: mdouze

fbshipit-source-id: 6f74d582f14e353e04029e6465bd6e488a865289
2022-09-08 01:05:52 -07:00
Ryan Russell
d2806286d2 docs: Improve readability (#2378)
Summary:
Signed-off-by: Ryan Russell <git@ryanrussell.org>

Various readability fixes focused on `.md` files:
- Grammar
- Fix some incorrect command references to `distributed_kmeans.py`
- Styling the markdown bash code snippets sections so they format

Attempted to put a lot of little things into one PR and commit; let me know if any mods are needed!

Best,
Ryan

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

Reviewed By: alexanderguzhva

Differential Revision: D37717671

Pulled By: mdouze

fbshipit-source-id: 0039192901d98a083cd992e37f6b692d0572103a
2022-07-08 09:19:07 -07:00
Matthijs Douze
b8fe92dfee contrib clustering module (#2217)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2217

This diff introduces a new Faiss contrib module that contains:
- generic k-means implemented in python (was in distributed_ondisk)
- the two-level clustering code, including a simple function that runs it on a Faiss IVF index.
- sparse clustering code (new)

The main idea is that that code is often re-used so better have it in contrib.

Reviewed By: beauby

Differential Revision: D34170932

fbshipit-source-id: cc297cc56d241b5ef421500ed410d8e2be0f1b77
2022-02-28 14:18:47 -08:00
Matthijs Douze
eb8781557f Fix exhaustive search GT computation with IP distance (#2212)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2212

Fixes issue

https://github.com/facebookresearch/faiss/issues/2205

clear bug report
easy fix
easy to accept ;-)

Reviewed By: beauby

Differential Revision: D33975281

fbshipit-source-id: 088e1f3078dc79402563be7fac3530d76b197006
2022-02-07 19:36:21 -08:00
Ben Mann
30abcd6a86 Add assertion to merge_ondisk.py (#2190)
Summary:
Fixes https://github.com/facebookresearch/faiss/issues/2188

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

Reviewed By: beauby

Differential Revision: D33975889

Pulled By: mdouze

fbshipit-source-id: 364eeac8de02f3ae00c9676198ed2ce27cfcd12b
2022-02-03 05:14:22 -08:00
Matthijs Douze
c0052c1533 IndexFlatCodes: a single parent for all flat codecs (#2132)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2132

This diff adds the class IndexFlatCodes that becomes the parent of all "flat" encodings.
IndexPQ
IndexFlat
IndexAdditiveQuantizer
IndexScalarQuantizer
IndexLSH
Index2Layer

The other changes are:
- for IndexFlat, there is no vector<float> with the data anymore. It is replaced with a `get_xb()` function. This broke quite a few external codes, that this diff also attempts to fix.
- I/O functions needed to be adapted. This is done without changing the I/O format for any index.
- added a small contrib function to get the data from the IndexFlat
- the functionality has been made uniform, for example remove_ids and add are now in the parent class.

Eventually, we may support generic storage for flat indexes, similar to `InvertedLists`, eg to memmap the data, but this will again require a big change.

Reviewed By: wickedfoo

Differential Revision: D32646769

fbshipit-source-id: 04a1659173fd51b130ae45d345176b72183cae40
2021-12-07 01:31:07 -08:00
Matthijs Douze
bef12cf51b Implement LCC's RCQ + ITQ in Faiss (#2123)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2123

One of the encodings used by LCC is based on a RCQ coarse quantizer and a "payload" of ITQ. The codes are compared with Hamming distances.

The index type `IndexIVFSpectralHash` can be re-purposed to perfrorm this type of index.

This diff contains a small demo demo_rcq_itq script in python to show how:
* the RCQ + ITQ are trained
* the RCQ + ITQ index add and search work (with a very inefficient python implementation)
* they can be transferred to an `IndexIVFSpectralHash`
* the python implementation and `IndexIVFSpectralHash` give the same results

The advantage of using to an `IndexIVFSpectralHash` is that in C++ it offers an `InvertedListScanner` object that can be used to compute query to code distances with its `distance_to_code` method. This is generic and will generalize to  other types of encodings and coarse quantizers.

What is missing is an index_factory to make instanciation easier.

Reviewed By: sc268

Differential Revision: D32642900

fbshipit-source-id: 284f3029d239b7946bbca44a748def4e058489bd
2021-11-25 15:59:18 -08:00
Lucas Hosseini
b4eb51dae8 Change default branch references from master to main. (#2029)
Summary:
This is required for the renaming of the default branch from `master` to `main`, in accordance with the new Facebook OSS guidelines.

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

Reviewed By: mdouze

Differential Revision: D30672862

Pulled By: beauby

fbshipit-source-id: 0b6458a4ff02a12aae14cf94057e85fdcbcbff96
2021-09-01 09:26:20 -07:00
Matthijs Douze
760cce7f3a Support for additive quantizer search (#1961)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1961

This diff implements LUT-based search for additive quantizers.
It also further merges code for LSQ and the RedisualQuantizer.

The documentation + evaluation is on github:

https://github.com/facebookresearch/faiss/wiki/Additive-quantizers

Reviewed By: wickedfoo

Differential Revision: D29395079

fbshipit-source-id: b8a24a647bbdc4cda2a699e791ffdb2a12bfa9c6
2021-08-20 01:00:10 -07:00
Check Deng
48ae55348a Update codebooks with double type (#1975)
Summary:
## Description

The process of updating the codebook in LSQ may be unstable if the data is not zero-centering. This diff fixed it by using `double` instead of `float` during codebook updating. This would not affect the performance since the update process is quite fast.

Users could switch back to `float` mode by setting `update_codebooks_with_double = False`

## Changes

1. Support `double` during codebook updating.
2. Add a unit test.
3. Add `__init__.py` under `contrib/` to avoid warnings.

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

Reviewed By: wickedfoo

Differential Revision: D29565632

Pulled By: mdouze

fbshipit-source-id: 932d7932ae9725c299cd83f87495542703ad6654
2021-07-07 03:29:49 -07:00
Matthijs Douze
1829aa92a1 three small fixes (#1972)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1972

This fixes a few issues that I ran into + adds tests:

- range_search_max_results with IP search

- a few missing downcasts for VectorTRansforms

- ResultHeap supports max IP search

Reviewed By: wickedfoo

Differential Revision: D29525093

fbshipit-source-id: d4ff0aff1d83af9717ff1aaa2fe3cda7b53019a3
2021-07-01 16:08:45 -07:00
Chengqi Deng
c087f87730 Add LocalSearchQuantizer (#1906)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1906

This PR implemented LSQ/LSQ++, a vector quantization technique described in the following two papers:

1. Revisiting additive quantization
2. LSQ++: Lower running time and higher recall in multi-codebook quantization

Here is a benchmark running on SIFT1M for 64 bits encoding:
```
===== lsq:
        mean square error = 17335.390208
        training time: 312.729779958725 s
        encoding time: 244.6277096271515 s
===== pq:
        mean square error = 23743.004672
        training time: 1.1610801219940186 s
        encoding time: 2.636141061782837 s
===== rq:
        mean square error = 20999.737344
        training time: 31.813055515289307 s
        encoding time: 307.51959800720215 s
```

Changes:

1. Add LocalSearchQuantizer object
2. Fix an out of memory bug in ResidualQuantizer
3. Add a benchmark for evaluating quantizers
4. Add tests for LocalSearchQuantizer

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

Test Plan:
```
buck test //faiss/tests/:test_lsq

buck run mode/opt //faiss/benchs/:bench_quantizer -- lsq pq rq
```

Reviewed By: beauby

Differential Revision: D28376369

Pulled By: mdouze

fbshipit-source-id: 2a394d38bf75b9de0a1c2cd6faddf7dd362a6fa8
2021-05-21 01:33:55 -07:00
Jeff Johnson
b544db24a8 Raw all-pairwise distance function on GPU
Summary:
This diff implements brute-force all-pairwise distances between two different sets of vectors using any of the Faiss supported metrics on the GPU (L2, IP, L1, Lp, Linf, etc).

It is implemented using the same C++ interface as `bfKnn`, except when `k == -1`, all pairwise distances will be returned (no k-selection is made). A restriction exists at present where the entire output data must be able to reside on the same GPU which may be lifted at a subsequent point.

This interface is available in python via `faiss.pairwise_distance_gpu(res, xq, xb, D, metric)` with both numpy and pytorch support which will return all of the distances in D.

Also cleaned up CUDA stream usage a little bit in Distance.cu/Distance.cuh in the C++ implementation.

Reviewed By: mdouze

Differential Revision: D27686773

fbshipit-source-id: 8de6a699cda5d7077f0ab583e9ce76e630f0f687
2021-04-13 12:06:04 -07:00
Matthijs Douze
3f2ebf4b1c Add preassigned functions to contrib
Summary:
Adds the preassigned add and search python wrappers to contrib.
Adds the preassigned search for the binary case (was missing before).
Also adds a real test for that functionality.

Reviewed By: beauby

Differential Revision: D26560021

fbshipit-source-id: 330b715a9ed0073cfdadbfbcb1c23b10bed963a5
2021-02-25 11:39:07 -08:00
Lucas Hosseini
6d51766607 Fix unused variables in python
Reviewed By: mdouze

Differential Revision: D26633983

fbshipit-source-id: 32b9f95ed9647716f65b93f2713a8d5bad6abe78
2021-02-24 11:52:18 -08:00
Matthijs Douze
5602724979 make calling conventions uniform between faiss.knn and faiss.knn_gpu
Summary: The order of xb an xq was different between `faiss.knn` and `faiss.knn_gpu`. Also the metric argument was called distance_type. This diff fixes both. Hopefully not too much external code depends on it.

Reviewed By: wickedfoo

Differential Revision: D26222853

fbshipit-source-id: b43e143d64d9ecbbdf541734895c13847cf2696c
2021-02-03 12:21:40 -08:00
Matthijs Douze
c7fd8d7ac3 improved range search evaluation functions
Summary: For range search evaluation, this diff adds optimized functions for ground-truth generation (on GPU).

Reviewed By: beauby

Differential Revision: D25822716

fbshipit-source-id: c5278dfad0510d24c2a5c87c1f8c81161fa8c5d3
2021-01-11 08:12:10 -08:00
Matthijs Douze
3dd7ba8ff9 Add range search accuracy evaluation
Summary:
Added a few functions in contrib to:
- run range searches by batches on the query or the database side
- emulate range search on GPU: search on GPU with k=1024, if the farthest neighbor is still within range, re-perform search on CPU
- as reference implementations for precision-recall on range search datasets
- optimized code to plot precision-recall plots (ie. sweep over thresholds)

The new functions are mainly in a new `evaluation.py`

Reviewed By: wickedfoo

Differential Revision: D25627619

fbshipit-source-id: 58f90654c32c925557d7bbf8083efbb710712e03
2020-12-17 17:17:09 -08:00
Matthijs Douze
c5975cda72 PQ4 fast scan benchmarks (#1555)
Summary:
Code + scripts for Faiss benchmarks around the  Fast scan codes.

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

Test Plan: buck test //faiss/tests/:test_refine

Reviewed By: wickedfoo

Differential Revision: D25546505

Pulled By: mdouze

fbshipit-source-id: 902486b7f47e36221a2671d124df8c114f25db58
2020-12-16 01:18:58 -08:00
Matthijs Douze
6d0bc58db6 Implementation of PQ4 search with SIMD instructions (#1542)
Summary:
IndexPQ and IndexIVFPQ implementations with AVX shuffle instructions.

The training and computing of the codes does not change wrt. the original PQ versions but the code layout is "packed" so that it can be used efficiently by the SIMD computation kernels.

The main changes are:

- new IndexPQFastScan and IndexIVFPQFastScan objects

- simdib.h for an abstraction above the AVX2 intrinsics

- BlockInvertedLists for invlists that are 32-byte aligned and where codes are not sequential

- pq4_fast_scan.h/.cpp:  for packing codes and look-up tables + optmized distance comptuation kernels

- simd_result_hander.h: SIMD version of result collection in heaps / reservoirs

Misc changes:

- added contrib.inspect_tools to access fields in C++ objects

- moved .h and .cpp code for inverted lists to an invlists/ subdirectory, and made a .h/.cpp for InvertedListsIOHook

- added a new inverted lists type with 32-byte aligned codes (for consumption by SIMD)

- moved Windows-specific intrinsics to platfrom_macros.h

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

Test Plan:
```
buck test mode/opt  -j 4  //faiss/tests/:test_fast_scan_ivf //faiss/tests/:test_fast_scan
buck test mode/opt  //faiss/manifold/...
```

Reviewed By: wickedfoo

Differential Revision: D25175439

Pulled By: mdouze

fbshipit-source-id: ad1a40c0df8c10f4b364bdec7172e43d71b56c34
2020-12-03 10:06:38 -08:00
Jeff Johnson
8d776e6453 PyTorch tensor / Faiss index interoperability (#1484)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1484

This diff allows for native usage of PyTorch tensors for Faiss indexes on both CPU and GPU. It is currently only implemented in this diff for things that inherit from `faiss.Index`, which covers the non-binary indices, and it patches the same functions on `faiss.Index` that were also covered by `__init__.py` for numpy interoperability.

There must be uniformity among the inputs: if any array input is a Torch tensor, then all array inputs must be Torch tensors. Similarly, if any array input is a numpy ndarray, then all array inputs must be numpy ndarrays.

If `faiss.contrib.torch_utils` is imported, it ensures that `import faiss` has already been performed to patch all of the functions using the base `__init__.py` numpy wrappers, and then patches the following functions again:

```
add
add_with_ids
assign
train
search
remove_ids
reconstruct
reconstruct_n
range_search
update_vectors
search_and_reconstruct
sa_encode
sa_decode
```

to allow usage of PyTorch CPU tensors, and additionally PyTorch GPU tensors if the index being used is on the GPU.

numpy functionality is still available when `faiss.contrib.torch_utils` is imported; we pass through to the original patched numpy function when we detect numpy inputs.

In addition, to allow for better (asynchronous) GPU usage without requiring the CPU to be involved, all of these functions which construct tensors/arrays for output now take optional arguments for storage (numpy or torch.Tensor) to be provided that will contain the output data. `range_search` is the only exception to this, as the size of the output data is indeterminate. The eventual GPU implementation will likely require the user to provide a maximum cap on the output size, and allow that to be passed instead. If the optional pre-allocated output values are presented by the user, they are used; otherwise, new return ndarray / Tensors are constructed as before and used for the return. If this feature were not provided on the GPU, then every execution would be completely serial as we would depend upon the CPU to allocate GPU memory before every operation. Instead, now this can function much like NN graph execution on the GPU, assuming that all of the data requirements are pre-allocated, so the execution will run at the full speed of the GPU and not be stalled sequentially launching kernels.

This diff also exposes the `GpuResources` shared_ptr object owned by a GPU index. This is required for pytorch GPU so that we can perform proper stream ordering in Faiss with respect to the current pytorch stream. So, Faiss indices now perform more or less as any NN operation in Torch does.

Note, however, that a Faiss index has its own setting on current device, and if the pytorch GPU tensor inputs are resident on a different device than what the Faiss index expects, a cross-device copy will be initiated. I may choose to make this an error in the future and require matching device to device.

This diff also found a bug when passing GPU data directly to `train()` for `GpuIndexIVFFlat` and `GpuIndexIVFScalarQuantizer`, as I guess we never tested passing GPU data directly to these functions before. `GpuIndexIVFPQ` was doing the right thing however.

The assign function is now also implemented on the GPU as well, and is now marked `const` to be in line with the `search` function.

Also added better checking of non-contiguous inputs for both Torch tensors and numpy ndarrays.

Updated the `knn_gpu` function with a base implementation always present that allows for usage of numpy arrays, which is overridden when `torch_utils` is imported to allow torch usage. This supports row/column major layout, float32/float16 data and int64/int32 indices for both numpy and torch.

Reviewed By: mdouze

Differential Revision: D24299400

fbshipit-source-id: b4f117b9c120bd1ad83e7702087051ab7b303b29
2020-10-23 22:24:22 -07:00
Matthijs Douze
f2369fcc82 benchmark SSD IndexIVF
Summary: This is some code for benchmakring the SSD reads.

Reviewed By: MDSilber

Differential Revision: D24457715

fbshipit-source-id: 475668e4dc450dc4652ef8828111335c236bfa44
2020-10-21 18:21:39 -07:00
Matthijs Douze
92306e3a69 Synthetic dataset with inner product option
Summary: The synthetic dataset can now have IP groundtruth

Reviewed By: wickedfoo

Differential Revision: D24219860

fbshipit-source-id: 42e094479311135e932821ac0a97ed0fb237bf78
2020-10-20 03:46:26 -07:00
Lucas Hosseini
70eaa9b1a3 Add missing copyright headers. (#1460)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1460

Reviewed By: wickedfoo

Differential Revision: D24278804

Pulled By: beauby

fbshipit-source-id: 5ea96ceb63be76a34f1eb4da03972159342cd5b6
2020-10-13 11:15:59 -07:00
Jeff Johnson
e796f4f9df Improve Faiss / PyTorch GPU interoperability
Summary:
PyTorch GPU in general is free to use whatever stream it currently wants, based on `torch.cuda.current_stream()`. Due to C++/python language barrier issues, we couldn't previously pass the actual `cudaStream_t` that is currently in use on a given device from PyTorch C++ to Faiss C++ via python.

This diff adds conversion functions to convert a Python integer representing a pointer to a `cudaStream_t` (which is itself a `CUstream_st*`), so we can pass the stream specified in `torch.cuda.current_stream()` to `StandardGpuResources::setDefaultStream`. We thus guarantee that all Faiss work is ordered on the same stream that is in use in PyTorch.

For use in Python, there is now the `faiss.contrib.pytorch_tensors.using_stream` context object which automatically sets and unsets the current PyTorch stream within Faiss. This takes a `StandardGpuResources` object in Python, and an optional `torch.cuda.Stream` if one wants to use a different stream, otherwise it uses the current one. This is how it is used:

```
# Create a non-default stream
s = torch.cuda.Stream()

# Have Torch use it
with torch.cuda.stream(s):

  # Have Faiss use the same stream as the above
  with faiss.contrib.pytorch_tensors.using_stream(res):
    # Do some work on the GPU
    faiss.bfKnn(res, args)
```

`using_stream` uses the same pattern as the Pytorch `torch.cuda.stream` object.

This replaces any brute-force GPU/CPU synchronization work that was necessary before.

Other changes in this diff:
- cleans up the config objects in the GpuIndex subclasses, to distinguish between read-only parameters that can only be set upon index construction, versus those that can be changed at runtime.
- StandardGpuResources now more properly distinguishes between user-supplied streams (like the PyTorch one) which will not be destroyed upon resources destruction, versus internal streams.
- `search_index_pytorch` now needs to take a `StandardGpuResources` object as well, there is no way to get this from an index instance otherwise (or at least, I would have to return a `shared_ptr`, in which case we should just update the Python SWIG stuff to use `shared_ptr` for GpuResources or something.

Reviewed By: mdouze

Differential Revision: D24260026

fbshipit-source-id: b18bb0eb34eb012584b1c923088228776c10b720
2020-10-13 09:11:19 -07:00
Matthijs Douze
8b05434a50 Remove useless function
Summary:
Removed an unused function that caused compile errors in some configurations.
Added contrib function (exhaustive_search.knn) to compute the k nearest neighbors without constructing an index.
Renamed the equivalent GPU function as exhaustive_search.knn_gpu (it does not make much sense to mention numpy in the name as all functions take numpy arguments by default).

Reviewed By: beauby

Differential Revision: D24215427

fbshipit-source-id: 6d8e1eafa7c57593304b7b76f83b3015e4d2a2bb
2020-10-09 07:57:04 -07:00
Jeff Johnson
0412d761e5 GPU brute-force kNN can take int32 indices (#1445)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1445

As requested in https://github.com/facebookresearch/faiss/issues/1304, `bfKnn` can now produce int32 indices for output.

The native kernels themselves for brute-force kNN only operate on int32 indices in any case, so this is faster.

Also added a SWIG definition for float16 numpy arrays. As there is not a native half type, the reverse definition is undefined, so this is only really used for taking float16 data (e.g., from numpy) as input when in Python.

Added a `knn_numpy_gpu` wrapper as well that handles calling the `bfKnn` GPU implementation using CPU numpy arrays. This handles transposition and f32/f16/i32 data types as needed.

Reviewed By: mdouze

Differential Revision: D24152296

fbshipit-source-id: caa7daea23438cf26aa248e380f0dab2b6b907fd
2020-10-08 17:50:42 -07:00
Matthijs Douze
8dfd51d3a7 Moved pytorch interop code to contrib
Summary:
The pytorch interop code was in a test until now. However, it is better if people can rely on it to be updated when the API is updated. Therefore, we move it into contrib.
Also added a README.md

Reviewed By: wickedfoo

Differential Revision: D23392962

fbshipit-source-id: 9b7c0e388a7ea3c0b73dc0018322138f49191673
2020-08-28 17:50:49 -07:00
Matthijs Douze
f849680777 Dataset access in contrib
Summary:
This diff adds an object for a few useful dataset in faiss.contrib.
This includes synthetic datasets and the classic ones.
It is intended to work on:
- the FAIR cluster
- gluster
- manifold

Reviewed By: wickedfoo

Differential Revision: D23378763

fbshipit-source-id: 2437a7be9e712fd5ad1bccbe523cc1c936f7ab35
2020-08-27 19:19:33 -07:00