106 Commits

Author SHA1 Message Date
Matthijs Douze
8eab15eca3 LUT based search for additive quantizers (#1908)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1908

To search the best combination of codebooks, the method that was implemented so far is via a beam search.

It is possible to make this faster for a query vector q by precomputing look-up tables in the form of

LUT_m = <q, cent_m>

where cent_m is the set of centroids for quantizer m=0..M-1.

The LUT can then be used as

inner_prod = sum_m LUT_m[c_m]

and

L2_distance = norm_q + norm_db - 2 * inner_prod

This diff implements this computation by:

- adding the LUT precomputation

- storing an exhaustive table of all centroid norms (when using L2)

This is only practical for small additive quantizers, eg. when a residual vector quantizer is used as coarse quantizer (ResidualCoarseQuantizer).

This diff is based on AdditiveQuantizer diff because it applies equally to other quantizers (eg. the LSQ).

Reviewed By: sc268

Differential Revision: D28467746

fbshipit-source-id: 82611fe1e4908c290204d4de866338c622ae4148
2021-05-25 01:54:53 -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
Chengqi Deng
d7f2dff589 Add tests for avx2 building (#1905)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1905

This PR added some tests to make sure the building with AVX2 works as we expected in Linux.

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

Test Plan: buck test //faiss/tests/:test_fast_scan -- test_PQ4_speed

Reviewed By: beauby

Differential Revision: D27435796

Pulled By: mdouze

fbshipit-source-id: 901a1d0abd9cb45ccef541bd7a570eb2bd8aac5b
2021-05-20 22:16:06 -07:00
Matthijs Douze
3eb82e32dc Range search bug
Summary:
This diff fixes a serious bug in the range search implementation.

During range search in a flat index, (exhaustive_L2sqr_seq and exhaustive_inner_product_seq) when running in multiple threads, the per-thread results are collected into RangeSearchPartialResult structures.

When the computation is finished, they are aggregated into a RangeSearchResult. In the previous version of the code, this loop was nested into a second loop that is used to check for KeyboardInterrupts. Thus, at each iteration, the results were overwritten.

The fix removes the outer loop. It is most likely useless anyways because the sequential code is called only for a small number of queries, for a larger number the BLAS version is used.

Reviewed By: wickedfoo

Differential Revision: D28486415

fbshipit-source-id: 89a52b17f6ca1ef68fc5e758f0e5a44d0df9fe38
2021-05-17 23:10:20 -07:00
Matthijs Douze
2d380e992b Add manifold check for size 0 (#1867)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1867

Merging code for the 1T photodna index seems to fail at

https://www.internalfb.com/phabricator/paste/view/P412975011?lines=174

with
```
terminate called after throwing an instance of 'facebook::manifold::blobstore::StorageException'
  what():  [400] Begin offset and/or length were invalid -- Begin offset must be positive and length must be non-negative. Received: offset = 2642410612, length = 0
Aborted (core dumped)
```
traces back to

https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/fbcode/manifold/blobstore/BlobstoreThriftHandler.cpp?lines=671%2C700%2C732

There is a single case where we don't check if the read or write size is 0. So let's try this fix.

In the process I realized that the Manifold tests were non functional due to a name collision on common.py. Also fix this in all dependent files.

Differential Revision: D28231710

fbshipit-source-id: 700ffa6ca0c82c49e7d1eae9e76549ec5ff16332
2021-05-09 22:30:31 -07:00
Matthijs Douze
441ccebbff Make more Residual quantizer more memory efficient (#1865)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1865

This diff chunks vectors to encode to make it more memory efficient.

Reviewed By: sc268

Differential Revision: D28234424

fbshipit-source-id: c1afd2aaff953d4ecd339800d5951ae1cae4789a
2021-05-07 02:12:27 -07:00
Matthijs Douze
4dc5b27a38 Fix test failure in OSX with OpenMP called from multiple threads (#1849)
Summary:
Need to add an ssh key to the circleci to be able to debug

For my own ref, how to connect to the job:
```
[matthijs@matthijs-mbp /Users/matthijs/Desktop/faiss_github/circleci_keys] ssh -p 54782 38.39.188.110 -i id_ed25519
```

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

Reviewed By: wickedfoo

Differential Revision: D28234897

Pulled By: mdouze

fbshipit-source-id: 6827fa45f24b3e4bf586315bd38f18608d07ecf9
2021-05-06 05:18:34 -07:00
Matthijs Douze
bb3c52a057 IndexResidual codec
Summary:
This diff adds the following to bring the residual quantizer support on-par with PQ:
- IndexResidual can be built with index factory, serialized and used as a Faiss codec.
- ResidualCoarseQuantizer can be used as a coarse quantizer for inverted files.

The factory string looks like "RQ1x16_6x8" which means a first 16-bit quantizer then 6 8-bit ones. For IVF it's "IVF4096(RQ2x6),Flat".

Reviewed By: sc268

Differential Revision: D27865612

fbshipit-source-id: f9f11d29e9f89d3b6d4cd22e9a4f9222422d5f26
2021-04-26 20:26:43 -07:00
Chengqi Deng
c62ab3a696 Use BLAS to compute sdc table (#1809)
Summary:
This PR used BLAS to compute sdc table in ProductQuantizer.

Here is the time of computing sdc tables:

```
nbits=8, d=128 (this commit)
M: 2, sdc: 0.0001361370086669922s
M: 4, sdc: 8.273124694824219e-05s
M: 8, sdc: 7.867813110351562e-05s
M: 16, sdc: 0.0001227855682373047s
M: 32, sdc: 0.0001697540283203125s
M: 64, sdc: 0.0007395744323730469s
```

```
nbits=8, d=128 (master)
M: 2,  sdc: 0.0055773258209228516s
M: 4,  sdc: 0.005366802215576172s
M: 8,  sdc: 0.0050809383392333984s
M: 16, sdc: 0.005639791488647461s
M: 32, sdc: 0.006036281585693359s
M: 64, sdc: 0.009720802307128906s
```

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

Reviewed By: beauby

Differential Revision: D27706249

Pulled By: mdouze

fbshipit-source-id: 102ae0c1c157e244e40557656934062f537b74d4
2021-04-16 00:17:51 -07:00
Matthijs Douze
7559cf5c5b add ResidualQuantizer
Summary:
This diff includes:
- progressive dimension k-means.
- the ResidualQuantizer object
- GpuProgressiveDimIndexFactory so that it can be trained on GPU
- corresponding tests
- reference Python implementation of the same in scripts/matthijs/LCC_encoding

Reviewed By: wickedfoo

Differential Revision: D27608029

fbshipit-source-id: 9a8cf3310c8439a93641961ca8b042941f0f4249
2021-04-14 13:11:54 -07:00
H. Vetinari
9c58ae00f1 Portable SWIG Vectors (#1742)
Summary:
After initial positive feedback to the idea in https://github.com/facebookresearch/faiss/issues/1741 from mdouze, here are the patches
I currently have as a basis for discussion.

Matthijs suggests to not bother with the deprecation warnings at all, which is fine for me
as well, though I would normally still advocate to provide users with _some_ advance notice
before removing parts of an interface.

Fixes https://github.com/facebookresearch/faiss/issues/1741

PS. The deprecation warning is only shown once per session (per class)
PPS. I have tested in https://github.com/conda-forge/faiss-split-feedstock/pull/32 that the respective
classes remain available both through `import faiss` and `from faiss import *`.

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

Reviewed By: mdouze

Differential Revision: D26978886

Pulled By: beauby

fbshipit-source-id: b52e2b5b5b0117af7cd95ef5df3128e9914633ad
2021-04-02 07:11:47 -07:00
Lucas Hosseini
c65f670523 Add separate targets for libfaiss/libfaiss_avx2. (#1772)
Summary:
This should fix the conda builds.

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

Reviewed By: mdouze

Differential Revision: D27365772

Pulled By: beauby

fbshipit-source-id: 12b9d488d475842030feb1a0452acf26dbe6ac01
2021-03-26 14:28:16 -07:00
Check Deng
c37c2fa393 Support I/O and clone for NSG (#1766)
Summary:
This PR added IO and clone support to NSG.

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

Test Plan: buck test //faiss/tests/:test_index -- TestNSG

Reviewed By: beauby

Differential Revision: D27189414

Pulled By: mdouze

fbshipit-source-id: c35c253d043c711d09a675f4ba5c3317b9423b5b
2021-03-23 09:18:15 -07:00
Check Deng
885d87f712 Support NSG in the index factory (#1758)
Summary:
## Description
This PR added NSG into the index factory. Here are the supported index strings:
1. `NSG{0}` or `NSG{0},Flat`: Create an IndexNSGFlat with `R = {0}`.
2. `IVF{0}_NSG{1},{2}`: Create an IndexIVF using NSG as a coarse quantizer where `ncentroids = {0}`, `R = {1}` and `{2}` is the second level quantizer.

These two types of indexes may be the most useful ones. Other composite indexes could be supported in the future.

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

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

Reviewed By: beauby

Differential Revision: D27189479

Pulled By: mdouze

fbshipit-source-id: b60000f985c490ef2e7bc561b4e209f9f61c3cc8
2021-03-23 07:28:20 -07:00
Check Deng
b35103a138 Add NSG (#1707)
Summary:
## Description:
This diff implemented Navigating Spreading-out Graph (NSG) which accepts a KNN graph as input.
Here is the interface of building an NSG graph:
``` c++
void IndexNSG::build(idx_t n, const float *x, idx_t *knn_graph, int GK);
```
where `GK` is the nb of neighbors per node and `knn_graph[i * GK + j]` is the j-th neighbor of node i.

The `add` method is not implemented yet.

The unit tests could be found in `tests/test_nsg.cpp`.

mdouze beauby Maybe I need some advice on how to design the interface and support python.

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

Test Plan: buck test //faiss/tests/:test_index -- TestNSG

Reviewed By: beauby

Differential Revision: D26748498

Pulled By: mdouze

fbshipit-source-id: 3280f705fb1b5f9c8cc5efeba63b904c3b832544
2021-03-10 15:03:00 -08:00
Matthijs Douze
189aecb224 Fix polysemous OOM
Summary: Polysemous training can OOM because it uses tables of size n^2 with n is 2**nbit of the PQ. This throws and exception when the table threatens to become too large. It also reduces the number of threads when this would make it possible to fit the computation within max_memory bytes.

Reviewed By: wickedfoo

Differential Revision: D26856747

fbshipit-source-id: bd98e60293494e2f4b2b6d48eb1200efb1ce683c
2021-03-06 00:40:05 -08:00
Matthijs Douze
f2464141a7 Add docstrings for most of the replaced index methods
Summary:
This adds docstrings for most of the replaced methods.
This will make the doc visible in notebooks.

Reviewed By: wickedfoo

Differential Revision: D26856664

fbshipit-source-id: da05cf8ac8380ee06a94a380d2547991b0c0a3be
2021-03-05 17:19:17 -08:00
H. Vetinari
42c6175535 fix warning about deprecate assertEquals (#1738)
Summary:
There's an annoying warning on every test run that I'd like to fix
```
=============================== warnings summary ===============================
tests/test_index_accuracy.py::TestRefine::test_IP
tests/test_index_accuracy.py::TestRefine::test_L2
  $SRC_DIR/tests/test_index_accuracy.py:726: DeprecationWarning: Please use assertEqual instead.
    self.assertEquals(recall1, recall2)
```

I've tried sneaking this into https://github.com/facebookresearch/faiss/issues/1704 & https://github.com/facebookresearch/faiss/issues/1717 already, but the first needs more time and
in the second, beauby asked me to keep this separate, so here's a new PR. :)

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

Reviewed By: wickedfoo

Differential Revision: D26855644

Pulled By: mdouze

fbshipit-source-id: 1198a9d9b3a79dfeb1d69513a61229fb45924f89
2021-03-05 13:46:35 -08:00
Dikpal Reddy
2b1194a3fa Ensure that invalid k/nprobe search input parameters to Faiss / Faiss GPU don't crash
Summary: Checking for invalid parameters (number of nearest neighbors and number of probes where applicable) in the indices and throwing. Along with unit tests.

Reviewed By: wickedfoo

Differential Revision: D26582467

fbshipit-source-id: e345635d2f0f44ddcecc3f3314b2b9113359a787
2021-03-03 21:17:28 -08:00
Matthijs Douze
64dcdbed95 Fix inefficient float / binary conversion
Summary: A test was timing out but the culprit was not the functionality being tested but instead a very slow list comprehension. Also relaxed the test very slightly as it failed from time to time.

Reviewed By: wickedfoo

Differential Revision: D26727507

fbshipit-source-id: 5b3352674fbef1f0cb6155452e4a93adc631d6a7
2021-03-01 21:43:31 -08:00
Check Deng
d6535a3d87 Add NNDescent to faiss (#1654)
Summary:
As discussed in https://github.com/facebookresearch/faiss/issues/685, I'm going to add an NSG index to faiss. This PR which adds an NNDescent index is the first step as I commented [here ](https://github.com/facebookresearch/faiss/issues/685#issuecomment-760608431).

**Changes:**
1. Add an `IndexNNDescent` and an `IndexNNDescentFlat` which allow users to construct a KNN graph on a million scale dataset using CPU and search NN on it. The implementation part is put under `faiss/impl`.
2. Add compilation entries to `CMakeLists.txt` for C++ and `swigfaiss.swig` for Python. `IndexNNDescentFlat` could be directly called by users in C++ and Python.
3. `VisitedTable` struct in `HNSW.h` is moved into `AuxIndexStructures.h`.
3. Add a demo `demo_nndescent.cpp` to demonstrate the effectiveness.

**TODO**
1. Support index factor.
2. Implement `IndexNNDescentPQ` and `IndexNNDescentSQ`
3. More comments in the code.

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

Test Plan:
buck test //faiss/tests/:test_index_accuracy -- TestNNDescent

buck test //faiss/tests/:test_build_blocks -- TestNNDescentKNNG

Reviewed By: wickedfoo

Differential Revision: D26309716

Pulled By: mdouze

fbshipit-source-id: 2abade9708d29023f8bccbf77143e8eea14f66c4
2021-02-25 16:48:28 -08: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
e86bf8cae1 Enable clang-format + autofix.
Summary: Format whole codebase with clang-format.

Reviewed By: mdouze

Differential Revision: D22891341

fbshipit-source-id: 673032b2444d61026d1e2c3fa2c5659f178cf58b
2021-02-25 04:46:10 -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
Check Deng
55c93f3cde Handle the situation where nprobe > nlist in IndexBinaryIVF (#1695)
Summary:
## Description

It is the same as https://github.com/facebookresearch/faiss/pull/1673 but for `IndexBinaryIVF`. Ensure that `nprobe` is no more than `nlist`.

## Changes
1. Replace `nprobe` with `min(nprobe, nlist)`
2. Replace `long` with `idx_t` in `IndexBinaryIVF.cpp`
3. Add a unit test
4. Fix a small bug in https://github.com/facebookresearch/faiss/pull/1673, `index` should be replaced by `gt_index`

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

Reviewed By: wickedfoo

Differential Revision: D26603278

Pulled By: mdouze

fbshipit-source-id: a4fb79bdeb975e9d8ec507177596c36da1195646
2021-02-23 12:20:37 -08:00
Matthijs Douze
57e29a5cb7 Implement serialization of indexes
Summary: add getstate / setstate to serialize indexes. Seems to work properly with object ownership etc.

Reviewed By: wickedfoo

Differential Revision: D26521228

fbshipit-source-id: ebbe08cfe2c15af2aa5b7ea1fc1bf87546066c23
2021-02-19 12:08:27 -08:00
Chengqi Deng
b4a0a9c617 Handle the situation where nprobe > nlist in IndexIVF (#1673)
Summary:
## Description

Fix the bug mentioned in https://github.com/facebookresearch/faiss/issues/1010. When `nprobe` is greater than `nlist` in `IndexIVF`, the program will crash because the index will ask the quantizer to return more centroids than it owns.

## Changes:
1. Set `nprobe` as `nlist` if it is greater than `nlist` during searching.
2. Add one test to detect this bug.
3. Fix typo in `IndexPQ.cpp`.

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

Reviewed By: wickedfoo

Differential Revision: D26454420

Pulled By: mdouze

fbshipit-source-id: d1d0949e30802602e975a94ba873f9db29abd5ab
2021-02-16 09:54:23 -08:00
Matthijs Douze
13e3039d5e Fix copy construction of AlignedTable
Summary: Copy construction of Aligned table was wrong, which crashed cloning of IVFPQ.

Reviewed By: wickedfoo

Differential Revision: D26426400

fbshipit-source-id: 1d43ea6309d0a56eb592f9d6c5b52282f494e653
2021-02-15 00:13:50 -08:00
Matthijs Douze
10c8583b2d Fix order of results for IndexBinaryHash and IndexBinaryMultiHash
Summary: The IndexBinaryHash and IndexBinaryMultiHash knn search functions returned results in a random order. This diff fixes that to the standard decreasing Hamming distance order + adds a test for that. I noticed on a notebook from sc268.

Reviewed By: sc268

Differential Revision: D26324795

fbshipit-source-id: 1444e26950e24bfac297f34f3d481d902d8ee769
2021-02-08 18:22:55 -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
04f777ead5 Re-enable fast scan on Windows tests (#1663)
Summary:
Fast-scan tests were disabled on windows because of a heap corruption. This diff enables them because the free_aligned bug was fixed in the meantime.

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

Reviewed By: beauby

Differential Revision: D26201040

Pulled By: mdouze

fbshipit-source-id: 8d6223b4e42ccb1ce2da6e2c51d9e0833199bde7
2021-02-03 07:48:52 -08:00
Matthijs Douze
27077c4627 Small fixes for compilation on ARM (#1655)
Summary:
This PR fixes a few small issues with compilation on ARM.
It has been tested on an AWS c6g.8xlarge machine with Ubuntu 18.04.5 LTS.
Compilation instructions are here: https://github.com/facebookresearch/faiss/wiki/Installing-Faiss#compiling-faiss-on-arm

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

Reviewed By: wickedfoo

Differential Revision: D26145921

Pulled By: mdouze

fbshipit-source-id: 007e57a610f489885e78ba22bc82605d67661c44
2021-01-29 10:06:45 -08:00
shengjun.li
908812266c Add heap_replace_top to simplify heap_pop + heap_push (#1597)
Summary:
Signed-off-by: shengjun.li <shengjun.li@zilliz.com>

Add heap_replace_top to simplify heap_pop + heap_push

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

Test Plan:
OMP_NUM_THREADS=1 buck run mode/opt //faiss/benchs/:bench_heap_replace
OMP_NUM_THREADS=8 buck run mode/opt //faiss/benchs/:bench_heap_replace

Reviewed By: beauby

Differential Revision: D25943140

Pulled By: mdouze

fbshipit-source-id: 66fe67779dd281a7753f597542c2e797ba0d7df5
2021-01-20 11:28:08 -08:00
Matthijs Douze
a2791322d9 Update ProductQuantizer.cpp (#1634)
Summary:
Make error message more clear.
See https://github.com/facebookresearch/faiss/issues/1632

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

Reviewed By: beauby

Differential Revision: D25942961

Pulled By: mdouze

fbshipit-source-id: e96ca808a9a0dcd1de5417a5e048d39431b30a5e
2021-01-20 00:12:54 -08:00
Matthijs Douze
950c831d45 Fix number of threads in test_ivfpq_codec when running in sandcastle
Summary: When running in a heavily parallelized env, the test becomes very slow and causes timeouts. Here we reduce the nb of threads.

Reviewed By: wickedfoo, Ben0mega

Differential Revision: D25921771

fbshipit-source-id: 1e0aacbb3e4f6e8f33ec893984b343eb5a610424
2021-01-17 13:42:06 -08:00
Matthijs Douze
9b2384f305 Fix serialization of large hash indexes
Summary:
64-bit cleanness issue for BitstringWriter.
Shows in HashIndex I/O, see https://github.com/facebookresearch/faiss/issues/1532

Reviewed By: beauby

Differential Revision: D25804891

fbshipit-source-id: d4cd3714d116a1b2fe1c9446eb1e9d3a8acf854e
2021-01-11 05:48:12 -08:00
Lucas Hosseini
e6a19f190a Replace tempnam with mkstemp in tests. (#1596)
Summary:
This avoids triggering the following warnings:
```
tests/test_ondisk_ivf.cpp:36:24: warning: 'tempnam' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead. [-Wdeprecated-declarations]
        char *cfname = tempnam (nullptr, prefix);
                       ^
tests/test_merge.cpp:34:24: warning: 'tempnam' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead. [-Wdeprecated-declarations]
        char *cfname = tempnam (nullptr, prefix);
```

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

Reviewed By: wickedfoo

Differential Revision: D25710654

Pulled By: beauby

fbshipit-source-id: 2aa027c3b32f6cf7f41eb55360424ada6d200901
2020-12-29 13:37:05 -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
Matthijs Douze
25adab7425 fix 64-bit arrays on the Mac (#1531)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1531

vector_to_array assumes that long is 64 bit. Fix this and test it.

Reviewed By: wickedfoo

Differential Revision: D25022363

fbshipit-source-id: f51f723d590d71ee5ef39e3f86ef69426df833fa
2020-11-17 09:00:06 -08:00
Matthijs Douze
fa85ddf8fa reduce nb of pq training iterations in test
Summary:
The tests TestPQTables are very slow in dev mode with BLAS. This seems to be due to the training operation of the PQ. However, since it does not matter if the training is accurate or not, we can just reduce the nb of training iterations from the default 25 to 4.

Still unclear why this happens, because the runtime is spent in BLAS, which should be independend of mode/opt or mode/dev.

Reviewed By: wickedfoo

Differential Revision: D24783752

fbshipit-source-id: 38077709eb9a6432210c11c3040765e139353ae8
2020-11-08 22:26:08 -08:00
Matthijs Douze
e1adde0d84 Faster brute force search (#1502)
Summary:
This diff streamlines the code that collects results for brute force distance computations for the L2 / IP and range search / knn search combinations.

It introduces a `ResultHandler` template class that abstracts what happens with the computed distances and ids. In addition to the heap result handler and the range search result handler, it introduces a reservoir result handler that improves the search speed for  large k (>=100).

Benchmark results (https://fb.quip.com/y0g1ACLEqJXx#OCaACA2Gm45) show that on small datasets (10k) search is 10-50% faster (improvements are larger for small k). There is room for improvement in the reservoir implementation, whose implementation is quite naive currently, but the diff is already useful in its current form.

Experiments on precomputed db vector norms for L2 distance computations were not very concluding performance-wise, so the implementation is removed from IndexFlatL2.

This diff also removes IndexL2BaseShift, which was never used.

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

Test Plan:
```
buck test //faiss/tests/:test_product_quantizer
buck test //faiss/tests/:test_index -- TestIndexFlat
```

Reviewed By: wickedfoo

Differential Revision: D24705464

Pulled By: mdouze

fbshipit-source-id: 270e10b19f3c89ed7b607ec30549aca0ac5027fe
2020-11-04 22:16:23 -08:00
Matthijs Douze
698a4592e8 fix clustering objective for inner product use cases
Summary: When an INNER_PRODUCT index is used for clustering, higher objective is better, so when redoing clusterings the highest objective should be retained (not the lowest). This diff fixes this and adds a test.

Reviewed By: wickedfoo

Differential Revision: D24701894

fbshipit-source-id: b9ec224cf8f4ffdfd2b8540ce37da43386a27b7a
2020-11-03 09:44:09 -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
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
Matthijs Douze
28edc56fa8 Search in sharded invlists
Summary:
This diff adds a CombinedIndexSharded1T class to combined_index that uses the 30 shards from the Spark reducer.
The metadata is stored in pickle files on manifold.

Differential Revision: D24018824

fbshipit-source-id: be4ff8b38c3d6e1bb907e02b655d0e419b7a6fea
2020-10-19 10:39:22 -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
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
Matthijs Douze
5ad630635c expose threat-safe stats (#1438)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1438

This diff changes Faiss and the `combined_index.py` to propagate thread-safe stats to handler.py

Reviewed By: MDSilber

Differential Revision: D24082543

fbshipit-source-id: 944e6b7630daeede5eb9501b81557a6fe5afec44
2020-10-03 23:26:36 -07:00