faiss 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/faiss/extconf.rb +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/benchs/bench_6bit_codec.cpp +80 -0
- data/vendor/faiss/c_api/AutoTune_c.h +2 -0
- data/vendor/faiss/c_api/IndexShards_c.cpp +0 -6
- data/vendor/faiss/c_api/IndexShards_c.h +1 -4
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +4 -2
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +1 -1
- data/vendor/faiss/demos/demo_imi_flat.cpp +5 -2
- data/vendor/faiss/demos/demo_imi_pq.cpp +6 -2
- data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +7 -2
- data/vendor/faiss/{AutoTune.cpp → faiss/AutoTune.cpp} +9 -9
- data/vendor/faiss/{AutoTune.h → faiss/AutoTune.h} +0 -0
- data/vendor/faiss/{Clustering.cpp → faiss/Clustering.cpp} +13 -12
- data/vendor/faiss/{Clustering.h → faiss/Clustering.h} +0 -0
- data/vendor/faiss/{DirectMap.cpp → faiss/DirectMap.cpp} +0 -0
- data/vendor/faiss/{DirectMap.h → faiss/DirectMap.h} +0 -0
- data/vendor/faiss/{IVFlib.cpp → faiss/IVFlib.cpp} +86 -11
- data/vendor/faiss/{IVFlib.h → faiss/IVFlib.h} +26 -8
- data/vendor/faiss/{Index.cpp → faiss/Index.cpp} +0 -0
- data/vendor/faiss/{Index.h → faiss/Index.h} +1 -1
- data/vendor/faiss/{Index2Layer.cpp → faiss/Index2Layer.cpp} +12 -11
- data/vendor/faiss/{Index2Layer.h → faiss/Index2Layer.h} +0 -0
- data/vendor/faiss/{IndexBinary.cpp → faiss/IndexBinary.cpp} +2 -1
- data/vendor/faiss/{IndexBinary.h → faiss/IndexBinary.h} +0 -0
- data/vendor/faiss/{IndexBinaryFlat.cpp → faiss/IndexBinaryFlat.cpp} +0 -0
- data/vendor/faiss/{IndexBinaryFlat.h → faiss/IndexBinaryFlat.h} +0 -0
- data/vendor/faiss/{IndexBinaryFromFloat.cpp → faiss/IndexBinaryFromFloat.cpp} +1 -0
- data/vendor/faiss/{IndexBinaryFromFloat.h → faiss/IndexBinaryFromFloat.h} +0 -0
- data/vendor/faiss/{IndexBinaryHNSW.cpp → faiss/IndexBinaryHNSW.cpp} +1 -2
- data/vendor/faiss/{IndexBinaryHNSW.h → faiss/IndexBinaryHNSW.h} +0 -0
- data/vendor/faiss/{IndexBinaryHash.cpp → faiss/IndexBinaryHash.cpp} +16 -7
- data/vendor/faiss/{IndexBinaryHash.h → faiss/IndexBinaryHash.h} +2 -1
- data/vendor/faiss/{IndexBinaryIVF.cpp → faiss/IndexBinaryIVF.cpp} +10 -16
- data/vendor/faiss/{IndexBinaryIVF.h → faiss/IndexBinaryIVF.h} +1 -1
- data/vendor/faiss/{IndexFlat.cpp → faiss/IndexFlat.cpp} +0 -0
- data/vendor/faiss/{IndexFlat.h → faiss/IndexFlat.h} +0 -0
- data/vendor/faiss/{IndexHNSW.cpp → faiss/IndexHNSW.cpp} +63 -32
- data/vendor/faiss/{IndexHNSW.h → faiss/IndexHNSW.h} +0 -0
- data/vendor/faiss/{IndexIVF.cpp → faiss/IndexIVF.cpp} +129 -46
- data/vendor/faiss/{IndexIVF.h → faiss/IndexIVF.h} +7 -3
- data/vendor/faiss/{IndexIVFFlat.cpp → faiss/IndexIVFFlat.cpp} +6 -5
- data/vendor/faiss/{IndexIVFFlat.h → faiss/IndexIVFFlat.h} +0 -0
- data/vendor/faiss/{IndexIVFPQ.cpp → faiss/IndexIVFPQ.cpp} +9 -8
- data/vendor/faiss/{IndexIVFPQ.h → faiss/IndexIVFPQ.h} +4 -2
- data/vendor/faiss/{IndexIVFPQR.cpp → faiss/IndexIVFPQR.cpp} +3 -1
- data/vendor/faiss/{IndexIVFPQR.h → faiss/IndexIVFPQR.h} +0 -0
- data/vendor/faiss/{IndexIVFSpectralHash.cpp → faiss/IndexIVFSpectralHash.cpp} +1 -1
- data/vendor/faiss/{IndexIVFSpectralHash.h → faiss/IndexIVFSpectralHash.h} +0 -0
- data/vendor/faiss/{IndexLSH.cpp → faiss/IndexLSH.cpp} +0 -0
- data/vendor/faiss/{IndexLSH.h → faiss/IndexLSH.h} +0 -0
- data/vendor/faiss/{IndexLattice.cpp → faiss/IndexLattice.cpp} +0 -0
- data/vendor/faiss/{IndexLattice.h → faiss/IndexLattice.h} +0 -0
- data/vendor/faiss/{IndexPQ.cpp → faiss/IndexPQ.cpp} +6 -6
- data/vendor/faiss/{IndexPQ.h → faiss/IndexPQ.h} +3 -1
- data/vendor/faiss/{IndexPreTransform.cpp → faiss/IndexPreTransform.cpp} +0 -0
- data/vendor/faiss/{IndexPreTransform.h → faiss/IndexPreTransform.h} +0 -0
- data/vendor/faiss/{IndexReplicas.cpp → faiss/IndexReplicas.cpp} +102 -10
- data/vendor/faiss/{IndexReplicas.h → faiss/IndexReplicas.h} +6 -0
- data/vendor/faiss/{IndexScalarQuantizer.cpp → faiss/IndexScalarQuantizer.cpp} +3 -3
- data/vendor/faiss/{IndexScalarQuantizer.h → faiss/IndexScalarQuantizer.h} +0 -0
- data/vendor/faiss/{IndexShards.cpp → faiss/IndexShards.cpp} +37 -12
- data/vendor/faiss/{IndexShards.h → faiss/IndexShards.h} +3 -4
- data/vendor/faiss/{InvertedLists.cpp → faiss/InvertedLists.cpp} +2 -2
- data/vendor/faiss/{InvertedLists.h → faiss/InvertedLists.h} +1 -0
- data/vendor/faiss/{MatrixStats.cpp → faiss/MatrixStats.cpp} +0 -0
- data/vendor/faiss/{MatrixStats.h → faiss/MatrixStats.h} +0 -0
- data/vendor/faiss/{MetaIndexes.cpp → faiss/MetaIndexes.cpp} +5 -3
- data/vendor/faiss/{MetaIndexes.h → faiss/MetaIndexes.h} +0 -0
- data/vendor/faiss/{MetricType.h → faiss/MetricType.h} +0 -0
- data/vendor/faiss/{OnDiskInvertedLists.cpp → faiss/OnDiskInvertedLists.cpp} +141 -3
- data/vendor/faiss/{OnDiskInvertedLists.h → faiss/OnDiskInvertedLists.h} +27 -7
- data/vendor/faiss/{VectorTransform.cpp → faiss/VectorTransform.cpp} +4 -3
- data/vendor/faiss/{VectorTransform.h → faiss/VectorTransform.h} +0 -0
- data/vendor/faiss/{clone_index.cpp → faiss/clone_index.cpp} +0 -0
- data/vendor/faiss/{clone_index.h → faiss/clone_index.h} +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.cpp +14 -14
- data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.h +6 -7
- data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuDistance.h +12 -4
- data/vendor/faiss/{gpu → faiss/gpu}/GpuFaissAssert.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndex.h +3 -9
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexBinaryFlat.h +7 -7
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexFlat.h +35 -10
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVF.h +1 -2
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFFlat.h +4 -3
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFPQ.h +21 -4
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFScalarQuantizer.h +4 -3
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndicesOptions.h +0 -0
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +200 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +264 -0
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +572 -0
- data/vendor/faiss/{gpu → faiss/gpu}/StandardGpuResources.h +83 -15
- data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper-inl.h +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper.h +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfIVFPQAdd.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/perf/WriteIndex.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexBinaryFlat.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexFlat.cpp +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFFlat.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFPQ.cpp +141 -52
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuMemoryException.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.cpp +4 -2
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/demo_ivfpq_indexing_gpu.cpp +7 -5
- data/vendor/faiss/{gpu → faiss/gpu}/utils/DeviceUtils.h +1 -1
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +213 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/StackDeviceMemory.h +25 -40
- data/vendor/faiss/{gpu → faiss/gpu}/utils/StaticUtils.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.cpp +1 -0
- data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.h +3 -1
- data/vendor/faiss/{impl → faiss/impl}/FaissAssert.h +1 -0
- data/vendor/faiss/{impl → faiss/impl}/FaissException.cpp +26 -0
- data/vendor/faiss/{impl → faiss/impl}/FaissException.h +4 -0
- data/vendor/faiss/{impl → faiss/impl}/HNSW.cpp +26 -26
- data/vendor/faiss/{impl → faiss/impl}/HNSW.h +19 -11
- data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.cpp +1 -1
- data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.h +1 -1
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer-inl.h +0 -1
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.cpp +9 -9
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.cpp +63 -39
- data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.h +1 -1
- data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex-inl.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/index_read.cpp +99 -116
- data/vendor/faiss/{impl → faiss/impl}/index_write.cpp +15 -50
- data/vendor/faiss/{impl → faiss/impl}/io.cpp +15 -10
- data/vendor/faiss/{impl → faiss/impl}/io.h +22 -8
- data/vendor/faiss/faiss/impl/io_macros.h +57 -0
- data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.cpp +52 -36
- data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.h +3 -3
- data/vendor/faiss/faiss/impl/platform_macros.h +24 -0
- data/vendor/faiss/{index_factory.cpp → faiss/index_factory.cpp} +33 -12
- data/vendor/faiss/{index_factory.h → faiss/index_factory.h} +0 -0
- data/vendor/faiss/{index_io.h → faiss/index_io.h} +55 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +112 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +45 -0
- data/vendor/faiss/{utils → faiss/utils}/Heap.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/Heap.h +1 -3
- data/vendor/faiss/{utils → faiss/utils}/WorkerThread.cpp +0 -0
- data/vendor/faiss/{utils → faiss/utils}/WorkerThread.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/distances.cpp +28 -13
- data/vendor/faiss/{utils → faiss/utils}/distances.h +2 -1
- data/vendor/faiss/{utils → faiss/utils}/distances_simd.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/extra_distances.cpp +8 -7
- data/vendor/faiss/{utils → faiss/utils}/extra_distances.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/hamming-inl.h +1 -3
- data/vendor/faiss/{utils → faiss/utils}/hamming.cpp +8 -7
- data/vendor/faiss/{utils → faiss/utils}/hamming.h +7 -1
- data/vendor/faiss/{utils → faiss/utils}/random.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/random.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/utils.cpp +27 -28
- data/vendor/faiss/{utils → faiss/utils}/utils.h +4 -0
- data/vendor/faiss/misc/test_blas.cpp +4 -1
- data/vendor/faiss/tests/test_binary_flat.cpp +0 -2
- data/vendor/faiss/tests/test_dealloc_invlists.cpp +6 -1
- data/vendor/faiss/tests/test_ivfpq_codec.cpp +4 -1
- data/vendor/faiss/tests/test_ivfpq_indexing.cpp +6 -4
- data/vendor/faiss/tests/test_lowlevel_ivf.cpp +12 -5
- data/vendor/faiss/tests/test_merge.cpp +6 -3
- data/vendor/faiss/tests/test_ondisk_ivf.cpp +7 -2
- data/vendor/faiss/tests/test_pairs_decoding.cpp +5 -1
- data/vendor/faiss/tests/test_params_override.cpp +7 -2
- data/vendor/faiss/tests/test_sliding_ivf.cpp +10 -4
- data/vendor/faiss/tutorial/cpp/1-Flat.cpp +14 -8
- data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +11 -7
- data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +12 -7
- data/vendor/faiss/tutorial/cpp/4-GPU.cpp +6 -3
- data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +7 -3
- metadata +154 -153
- data/vendor/faiss/gpu/GpuResources.cpp +0 -52
- data/vendor/faiss/gpu/GpuResources.h +0 -73
- data/vendor/faiss/gpu/StandardGpuResources.cpp +0 -303
- data/vendor/faiss/gpu/utils/DeviceMemory.cpp +0 -77
- data/vendor/faiss/gpu/utils/DeviceMemory.h +0 -71
- data/vendor/faiss/gpu/utils/MemorySpace.cpp +0 -89
- data/vendor/faiss/gpu/utils/MemorySpace.h +0 -44
- data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +0 -239
@@ -5,11 +5,11 @@
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
6
6
|
*/
|
7
7
|
|
8
|
-
// Copyright 2004-present Facebook. All Rights Reserved
|
9
8
|
// -*- c++ -*-
|
10
9
|
|
11
10
|
#include <faiss/IndexBinaryIVF.h>
|
12
11
|
|
12
|
+
#include <cinttypes>
|
13
13
|
#include <cstdio>
|
14
14
|
#include <omp.h>
|
15
15
|
|
@@ -97,7 +97,7 @@ void IndexBinaryIVF::add_core(idx_t n, const uint8_t *x, const idx_t *xids,
|
|
97
97
|
n_add++;
|
98
98
|
}
|
99
99
|
if (verbose) {
|
100
|
-
printf("IndexBinaryIVF::add_with_ids: added %ld / %
|
100
|
+
printf("IndexBinaryIVF::add_with_ids: added %ld / %" PRId64 " vectors\n",
|
101
101
|
n_add, n);
|
102
102
|
}
|
103
103
|
ntotal += n_add;
|
@@ -222,7 +222,7 @@ void IndexBinaryIVF::train(idx_t n, const uint8_t *x) {
|
|
222
222
|
}
|
223
223
|
} else {
|
224
224
|
if (verbose) {
|
225
|
-
printf("Training quantizer on %
|
225
|
+
printf("Training quantizer on %" PRId64 " vectors in %dD\n", n, d);
|
226
226
|
}
|
227
227
|
|
228
228
|
Clustering clus(d, nlist, cp);
|
@@ -333,7 +333,7 @@ struct IVFBinaryScannerL2: BinaryInvertedListScanner {
|
|
333
333
|
const uint8_t *codes,
|
334
334
|
const idx_t *ids,
|
335
335
|
int radius,
|
336
|
-
RangeQueryResult &result) const
|
336
|
+
RangeQueryResult &result) const override
|
337
337
|
{
|
338
338
|
size_t nup = 0;
|
339
339
|
for (size_t j = 0; j < n; j++) {
|
@@ -351,12 +351,6 @@ struct IVFBinaryScannerL2: BinaryInvertedListScanner {
|
|
351
351
|
};
|
352
352
|
|
353
353
|
|
354
|
-
template <bool store_pairs>
|
355
|
-
BinaryInvertedListScanner *select_IVFBinaryScannerL2 (size_t code_size) {
|
356
|
-
|
357
|
-
}
|
358
|
-
|
359
|
-
|
360
354
|
void search_knn_hamming_heap(const IndexBinaryIVF& ivf,
|
361
355
|
size_t n,
|
362
356
|
const uint8_t *x,
|
@@ -383,7 +377,7 @@ void search_knn_hamming_heap(const IndexBinaryIVF& ivf,
|
|
383
377
|
(ivf.get_InvertedListScanner (store_pairs));
|
384
378
|
|
385
379
|
#pragma omp for
|
386
|
-
for (
|
380
|
+
for (idx_t i = 0; i < n; i++) {
|
387
381
|
const uint8_t *xi = x + i * ivf.code_size;
|
388
382
|
scanner->set_query(xi);
|
389
383
|
|
@@ -407,7 +401,7 @@ void search_knn_hamming_heap(const IndexBinaryIVF& ivf,
|
|
407
401
|
}
|
408
402
|
FAISS_THROW_IF_NOT_FMT
|
409
403
|
(key < (idx_t) ivf.nlist,
|
410
|
-
"Invalid key=%
|
404
|
+
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
411
405
|
key, ik, ivf.nlist);
|
412
406
|
|
413
407
|
scanner->set_list (key, coarse_dis[i * nprobe + ik]);
|
@@ -481,7 +475,7 @@ void search_knn_hamming_count(const IndexBinaryIVF& ivf,
|
|
481
475
|
size_t nlistv = 0, ndis = 0;
|
482
476
|
|
483
477
|
#pragma omp parallel for reduction(+: nlistv, ndis)
|
484
|
-
for (
|
478
|
+
for (int64_t i = 0; i < nx; i++) {
|
485
479
|
const idx_t * keysi = keys + i * nprobe;
|
486
480
|
HCounterState<HammingComputer>& csi = cs[i];
|
487
481
|
|
@@ -495,7 +489,7 @@ void search_knn_hamming_count(const IndexBinaryIVF& ivf,
|
|
495
489
|
}
|
496
490
|
FAISS_THROW_IF_NOT_FMT (
|
497
491
|
key < (idx_t) ivf.nlist,
|
498
|
-
"Invalid key=%
|
492
|
+
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
499
493
|
key, ik, ivf.nlist);
|
500
494
|
|
501
495
|
nlistv++;
|
@@ -669,7 +663,7 @@ void IndexBinaryIVF::range_search(
|
|
669
663
|
if (key < 0) return;
|
670
664
|
FAISS_THROW_IF_NOT_FMT (
|
671
665
|
key < (idx_t) nlist,
|
672
|
-
"Invalid key=%
|
666
|
+
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
673
667
|
key, ik, nlist);
|
674
668
|
const size_t list_size = invlists->list_size(key);
|
675
669
|
|
@@ -686,7 +680,7 @@ void IndexBinaryIVF::range_search(
|
|
686
680
|
};
|
687
681
|
|
688
682
|
#pragma omp for
|
689
|
-
for (
|
683
|
+
for (idx_t i = 0; i < n; i++) {
|
690
684
|
scanner->set_query (x + i * code_size);
|
691
685
|
|
692
686
|
RangeQueryResult & qres = pres.new_result (i);
|
File without changes
|
File without changes
|
@@ -14,6 +14,7 @@
|
|
14
14
|
#include <cassert>
|
15
15
|
#include <cstring>
|
16
16
|
#include <cstdio>
|
17
|
+
#include <cinttypes>
|
17
18
|
#include <cmath>
|
18
19
|
#include <omp.h>
|
19
20
|
|
@@ -22,7 +23,6 @@
|
|
22
23
|
|
23
24
|
#include <sys/types.h>
|
24
25
|
#include <sys/stat.h>
|
25
|
-
#include <unistd.h>
|
26
26
|
#include <stdint.h>
|
27
27
|
|
28
28
|
#ifdef __SSE__
|
@@ -119,7 +119,7 @@ void hnsw_add_vertices(IndexHNSW &index_hnsw,
|
|
119
119
|
size_t ntotal = n0 + n;
|
120
120
|
double t0 = getmillisecs();
|
121
121
|
if (verbose) {
|
122
|
-
printf("hnsw_add_vertices: adding %
|
122
|
+
printf("hnsw_add_vertices: adding %zd elements on top of %zd "
|
123
123
|
"(preset_levels=%d)\n",
|
124
124
|
n, n0, int(preset_levels));
|
125
125
|
}
|
@@ -289,7 +289,7 @@ void IndexHNSW::search (idx_t n, const float *x, idx_t k,
|
|
289
289
|
{
|
290
290
|
FAISS_THROW_IF_NOT_MSG(storage,
|
291
291
|
"Please use IndexHSNWFlat (or variants) instead of IndexHNSW directly");
|
292
|
-
size_t nreorder = 0;
|
292
|
+
size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0;
|
293
293
|
|
294
294
|
idx_t check_period = InterruptCallback::get_period_hint (
|
295
295
|
hnsw.max_level * d * hnsw.efSearch);
|
@@ -297,22 +297,26 @@ void IndexHNSW::search (idx_t n, const float *x, idx_t k,
|
|
297
297
|
for (idx_t i0 = 0; i0 < n; i0 += check_period) {
|
298
298
|
idx_t i1 = std::min(i0 + check_period, n);
|
299
299
|
|
300
|
-
#pragma omp parallel
|
300
|
+
#pragma omp parallel
|
301
301
|
{
|
302
302
|
VisitedTable vt (ntotal);
|
303
303
|
|
304
304
|
DistanceComputer *dis = storage_distance_computer(storage);
|
305
305
|
ScopeDeleter1<DistanceComputer> del(dis);
|
306
306
|
|
307
|
-
#pragma omp for
|
307
|
+
#pragma omp for reduction (+ : n1, n2, n3, ndis, nreorder)
|
308
308
|
for(idx_t i = i0; i < i1; i++) {
|
309
309
|
idx_t * idxi = labels + i * k;
|
310
310
|
float * simi = distances + i * k;
|
311
311
|
dis->set_query(x + i * d);
|
312
312
|
|
313
313
|
maxheap_heapify (k, simi, idxi);
|
314
|
-
hnsw.search(*dis, k, idxi, simi, vt);
|
315
|
-
|
314
|
+
HNSWStats stats = hnsw.search(*dis, k, idxi, simi, vt);
|
315
|
+
n1 += stats.n1;
|
316
|
+
n2 += stats.n2;
|
317
|
+
n3 += stats.n3;
|
318
|
+
ndis += stats.ndis;
|
319
|
+
nreorder += stats.nreorder;
|
316
320
|
maxheap_reorder (k, simi, idxi);
|
317
321
|
|
318
322
|
if (reconstruct_from_neighbors &&
|
@@ -341,7 +345,7 @@ void IndexHNSW::search (idx_t n, const float *x, idx_t k,
|
|
341
345
|
}
|
342
346
|
}
|
343
347
|
|
344
|
-
hnsw_stats.
|
348
|
+
hnsw_stats.combine({n1, n2, n3, ndis, nreorder});
|
345
349
|
}
|
346
350
|
|
347
351
|
|
@@ -416,6 +420,8 @@ void IndexHNSW::search_level_0(
|
|
416
420
|
{
|
417
421
|
|
418
422
|
storage_idx_t ntotal = hnsw.levels.size();
|
423
|
+
size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0;
|
424
|
+
|
419
425
|
#pragma omp parallel
|
420
426
|
{
|
421
427
|
DistanceComputer *qdis = storage_distance_computer(storage);
|
@@ -423,7 +429,7 @@ void IndexHNSW::search_level_0(
|
|
423
429
|
|
424
430
|
VisitedTable vt (ntotal);
|
425
431
|
|
426
|
-
#pragma omp for
|
432
|
+
#pragma omp for reduction (+ : n1, n2, n3, ndis, nreorder)
|
427
433
|
for(idx_t i = 0; i < n; i++) {
|
428
434
|
idx_t * idxi = labels + i * k;
|
429
435
|
float * simi = distances + i * k;
|
@@ -447,10 +453,17 @@ void IndexHNSW::search_level_0(
|
|
447
453
|
|
448
454
|
candidates.push(cj, nearest_d[i * nprobe + j]);
|
449
455
|
|
456
|
+
HNSWStats search_stats;
|
450
457
|
nres = hnsw.search_from_candidates(
|
451
458
|
*qdis, k, idxi, simi,
|
452
|
-
candidates, vt, 0, nres
|
459
|
+
candidates, vt, search_stats, 0, nres
|
453
460
|
);
|
461
|
+
n1 += search_stats.n1;
|
462
|
+
n2 += search_stats.n2;
|
463
|
+
n3 += search_stats.n3;
|
464
|
+
ndis += search_stats.ndis;
|
465
|
+
nreorder += search_stats.nreorder;
|
466
|
+
|
454
467
|
}
|
455
468
|
} else if (search_type == 2) {
|
456
469
|
|
@@ -464,10 +477,17 @@ void IndexHNSW::search_level_0(
|
|
464
477
|
if (cj < 0) break;
|
465
478
|
candidates.push(cj, nearest_d[i * nprobe + j]);
|
466
479
|
}
|
480
|
+
|
481
|
+
HNSWStats search_stats;
|
467
482
|
hnsw.search_from_candidates(
|
468
483
|
*qdis, k, idxi, simi,
|
469
|
-
candidates, vt, 0
|
484
|
+
candidates, vt, search_stats, 0
|
470
485
|
);
|
486
|
+
n1 += search_stats.n1;
|
487
|
+
n2 += search_stats.n2;
|
488
|
+
n3 += search_stats.n3;
|
489
|
+
ndis += search_stats.ndis;
|
490
|
+
nreorder += search_stats.nreorder;
|
471
491
|
|
472
492
|
}
|
473
493
|
vt.advance();
|
@@ -477,7 +497,7 @@ void IndexHNSW::search_level_0(
|
|
477
497
|
}
|
478
498
|
}
|
479
499
|
|
480
|
-
|
500
|
+
hnsw_stats.combine({n1, n2, n3, ndis, nreorder});
|
481
501
|
}
|
482
502
|
|
483
503
|
void IndexHNSW::init_level_0_from_knngraph(
|
@@ -488,9 +508,9 @@ void IndexHNSW::init_level_0_from_knngraph(
|
|
488
508
|
#pragma omp parallel for
|
489
509
|
for (idx_t i = 0; i < ntotal; i++) {
|
490
510
|
DistanceComputer *qdis = storage_distance_computer(storage);
|
491
|
-
float vec
|
492
|
-
storage->reconstruct(i, vec);
|
493
|
-
qdis->set_query(vec);
|
511
|
+
std::vector<float> vec(d);
|
512
|
+
storage->reconstruct(i, vec.data());
|
513
|
+
qdis->set_query(vec.data());
|
494
514
|
|
495
515
|
std::priority_queue<NodeDistFarther> initial_list;
|
496
516
|
|
@@ -533,14 +553,14 @@ void IndexHNSW::init_level_0_from_entry_points(
|
|
533
553
|
|
534
554
|
DistanceComputer *dis = storage_distance_computer(storage);
|
535
555
|
ScopeDeleter1<DistanceComputer> del(dis);
|
536
|
-
float vec
|
556
|
+
std::vector<float> vec(storage->d);
|
537
557
|
|
538
558
|
#pragma omp for schedule(dynamic)
|
539
559
|
for (int i = 0; i < n; i++) {
|
540
560
|
storage_idx_t pt_id = points[i];
|
541
561
|
storage_idx_t nearest = nearests[i];
|
542
|
-
storage->reconstruct (pt_id, vec);
|
543
|
-
dis->set_query (vec);
|
562
|
+
storage->reconstruct (pt_id, vec.data());
|
563
|
+
dis->set_query (vec.data());
|
544
564
|
|
545
565
|
hnsw.add_links_starting_from(*dis, pt_id,
|
546
566
|
nearest, (*dis)(nearest),
|
@@ -624,7 +644,7 @@ void IndexHNSW::link_singletons()
|
|
624
644
|
}
|
625
645
|
}
|
626
646
|
|
627
|
-
printf(" Found %d / %
|
647
|
+
printf(" Found %d / %" PRId64 " singletons (%d appear in a level above)\n",
|
628
648
|
n_sing, ntotal, n_sing_l1);
|
629
649
|
|
630
650
|
std::vector<float>recons(singletons.size() * d);
|
@@ -721,7 +741,7 @@ void ReconstructFromNeighbors::reconstruct(storage_idx_t i, float *x, float *tmp
|
|
721
741
|
x[l] += w * tmp[l];
|
722
742
|
}
|
723
743
|
} else {
|
724
|
-
const float
|
744
|
+
std::vector<const float *> betas(nsq);
|
725
745
|
{
|
726
746
|
const float *b = codebook.data();
|
727
747
|
const uint8_t *c = &codes[i * code_size];
|
@@ -948,6 +968,7 @@ int search_from_candidates_2(const HNSW & hnsw,
|
|
948
968
|
idx_t *I, float * D,
|
949
969
|
MinimaxHeap &candidates,
|
950
970
|
VisitedTable &vt,
|
971
|
+
HNSWStats &stats,
|
951
972
|
int level, int nres_in = 0)
|
952
973
|
{
|
953
974
|
int nres = nres_in;
|
@@ -996,15 +1017,9 @@ int search_from_candidates_2(const HNSW & hnsw,
|
|
996
1017
|
}
|
997
1018
|
}
|
998
1019
|
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
hnsw_stats.n1 ++;
|
1003
|
-
if (candidates.size() == 0)
|
1004
|
-
hnsw_stats.n2 ++;
|
1005
|
-
}
|
1006
|
-
}
|
1007
|
-
|
1020
|
+
stats.n1 ++;
|
1021
|
+
if (candidates.size() == 0)
|
1022
|
+
stats.n2 ++;
|
1008
1023
|
|
1009
1024
|
return nres;
|
1010
1025
|
}
|
@@ -1019,6 +1034,7 @@ void IndexHNSW2Level::search (idx_t n, const float *x, idx_t k,
|
|
1019
1034
|
IndexHNSW::search (n, x, k, distances, labels);
|
1020
1035
|
|
1021
1036
|
} else { // "mixed" search
|
1037
|
+
size_t n1 = 0, n2 = 0, n3 = 0, ndis = 0, nreorder = 0;
|
1022
1038
|
|
1023
1039
|
const IndexIVFPQ *index_ivfpq =
|
1024
1040
|
dynamic_cast<const IndexIVFPQ*>(storage);
|
@@ -1044,7 +1060,7 @@ void IndexHNSW2Level::search (idx_t n, const float *x, idx_t k,
|
|
1044
1060
|
int candidates_size = hnsw.upper_beam;
|
1045
1061
|
MinimaxHeap candidates(candidates_size);
|
1046
1062
|
|
1047
|
-
#pragma omp for
|
1063
|
+
#pragma omp for reduction (+ : n1, n2, n3, ndis, nreorder)
|
1048
1064
|
for(idx_t i = 0; i < n; i++) {
|
1049
1065
|
idx_t * idxi = labels + i * k;
|
1050
1066
|
float * simi = distances + i * k;
|
@@ -1081,10 +1097,16 @@ void IndexHNSW2Level::search (idx_t n, const float *x, idx_t k,
|
|
1081
1097
|
// reorder from sorted to heap
|
1082
1098
|
maxheap_heapify (k, simi, idxi, simi, idxi, k);
|
1083
1099
|
|
1100
|
+
HNSWStats search_stats;
|
1084
1101
|
hnsw.search_from_candidates(
|
1085
1102
|
*dis, k, idxi, simi,
|
1086
|
-
candidates, vt, 0, k
|
1103
|
+
candidates, vt, search_stats, 0, k
|
1087
1104
|
);
|
1105
|
+
n1 += search_stats.n1;
|
1106
|
+
n2 += search_stats.n2;
|
1107
|
+
n3 += search_stats.n3;
|
1108
|
+
ndis += search_stats.ndis;
|
1109
|
+
nreorder += search_stats.nreorder;
|
1088
1110
|
|
1089
1111
|
vt.advance();
|
1090
1112
|
|
@@ -1098,9 +1120,16 @@ void IndexHNSW2Level::search (idx_t n, const float *x, idx_t k,
|
|
1098
1120
|
// reorder from sorted to heap
|
1099
1121
|
maxheap_heapify (k, simi, idxi, simi, idxi, k);
|
1100
1122
|
|
1123
|
+
HNSWStats search_stats;
|
1101
1124
|
search_from_candidates_2 (
|
1102
1125
|
hnsw, *dis, k, idxi, simi,
|
1103
|
-
candidates, vt, 0, k);
|
1126
|
+
candidates, vt, search_stats, 0, k);
|
1127
|
+
n1 += search_stats.n1;
|
1128
|
+
n2 += search_stats.n2;
|
1129
|
+
n3 += search_stats.n3;
|
1130
|
+
ndis += search_stats.ndis;
|
1131
|
+
nreorder += search_stats.nreorder;
|
1132
|
+
|
1104
1133
|
vt.advance ();
|
1105
1134
|
vt.advance ();
|
1106
1135
|
|
@@ -1109,6 +1138,8 @@ void IndexHNSW2Level::search (idx_t n, const float *x, idx_t k,
|
|
1109
1138
|
maxheap_reorder (k, simi, idxi);
|
1110
1139
|
}
|
1111
1140
|
}
|
1141
|
+
|
1142
|
+
hnsw_stats.combine({n1, n2, n3, ndis, nreorder});
|
1112
1143
|
}
|
1113
1144
|
|
1114
1145
|
|
File without changes
|
@@ -11,7 +11,10 @@
|
|
11
11
|
|
12
12
|
|
13
13
|
#include <omp.h>
|
14
|
+
#include <mutex>
|
14
15
|
|
16
|
+
#include <algorithm>
|
17
|
+
#include <cinttypes>
|
15
18
|
#include <cstdio>
|
16
19
|
#include <memory>
|
17
20
|
|
@@ -72,7 +75,7 @@ void Level1Quantizer::train_q1 (size_t n, const float *x, bool verbose, MetricTy
|
|
72
75
|
"nlist not consistent with quantizer size");
|
73
76
|
} else if (quantizer_trains_alone == 0) {
|
74
77
|
if (verbose)
|
75
|
-
printf ("Training level-1 quantizer on %
|
78
|
+
printf ("Training level-1 quantizer on %zd vectors in %zdD\n",
|
76
79
|
n, d);
|
77
80
|
|
78
81
|
Clustering clus (d, nlist, cp);
|
@@ -87,7 +90,7 @@ void Level1Quantizer::train_q1 (size_t n, const float *x, bool verbose, MetricTy
|
|
87
90
|
} else if (quantizer_trains_alone == 2) {
|
88
91
|
if (verbose)
|
89
92
|
printf (
|
90
|
-
"Training L2 quantizer on %
|
93
|
+
"Training L2 quantizer on %zd vectors in %zdD%s\n",
|
91
94
|
n, d,
|
92
95
|
clustering_index ? "(user provided index)" : "");
|
93
96
|
FAISS_THROW_IF_NOT (metric_type == METRIC_L2);
|
@@ -188,7 +191,7 @@ void IndexIVF::add_with_ids (idx_t n, const float * x, const idx_t *xids)
|
|
188
191
|
for (idx_t i0 = 0; i0 < n; i0 += bs) {
|
189
192
|
idx_t i1 = std::min (n, i0 + bs);
|
190
193
|
if (verbose) {
|
191
|
-
printf(" IndexIVF::add_with_ids %
|
194
|
+
printf(" IndexIVF::add_with_ids %" PRId64 ":%" PRId64 "\n", i0, i1);
|
192
195
|
}
|
193
196
|
add_with_ids (i1 - i0, x + i0 * d,
|
194
197
|
xids ? xids + i0 : nullptr);
|
@@ -238,7 +241,7 @@ void IndexIVF::add_with_ids (idx_t n, const float * x, const idx_t *xids)
|
|
238
241
|
|
239
242
|
|
240
243
|
if (verbose) {
|
241
|
-
printf(" added %
|
244
|
+
printf(" added %zd / %" PRId64 " vectors (%zd -1s)\n", nadd, n, nminus1);
|
242
245
|
}
|
243
246
|
|
244
247
|
ntotal += n;
|
@@ -253,6 +256,8 @@ void IndexIVF::make_direct_map (bool b)
|
|
253
256
|
}
|
254
257
|
}
|
255
258
|
|
259
|
+
|
260
|
+
|
256
261
|
void IndexIVF::set_direct_map_type (DirectMap::Type type)
|
257
262
|
{
|
258
263
|
direct_map.set_type (type, invlists, ntotal);
|
@@ -278,7 +283,6 @@ void IndexIVF::search (idx_t n, const float *x, idx_t k,
|
|
278
283
|
}
|
279
284
|
|
280
285
|
|
281
|
-
|
282
286
|
void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
283
287
|
const idx_t *keys,
|
284
288
|
const float *coarse_dis ,
|
@@ -295,15 +299,18 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
295
299
|
using HeapForL2 = CMax<float, idx_t>;
|
296
300
|
|
297
301
|
bool interrupt = false;
|
302
|
+
std::mutex exception_mutex;
|
303
|
+
std::string exception_string;
|
298
304
|
|
299
305
|
int pmode = this->parallel_mode & ~PARALLEL_MODE_NO_HEAP_INIT;
|
300
306
|
bool do_heap_init = !(this->parallel_mode & PARALLEL_MODE_NO_HEAP_INIT);
|
301
307
|
|
302
308
|
// don't start parallel section if single query
|
303
|
-
bool do_parallel =
|
304
|
-
|
305
|
-
|
306
|
-
|
309
|
+
bool do_parallel = omp_get_max_threads() >= 2 && (
|
310
|
+
pmode == 0 ? n > 1 :
|
311
|
+
pmode == 1 ? nprobe > 1 :
|
312
|
+
nprobe * n > 1);
|
313
|
+
|
307
314
|
|
308
315
|
#pragma omp parallel if(do_parallel) reduction(+: nlistv, ndis, nheap)
|
309
316
|
{
|
@@ -327,6 +334,19 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
327
334
|
}
|
328
335
|
};
|
329
336
|
|
337
|
+
auto add_local_results = [&](
|
338
|
+
const float * local_dis, const idx_t * local_idx,
|
339
|
+
float *simi, idx_t *idxi)
|
340
|
+
{
|
341
|
+
if (metric_type == METRIC_INNER_PRODUCT) {
|
342
|
+
heap_addn<HeapForIP>
|
343
|
+
(k, simi, idxi, local_dis, local_idx, k);
|
344
|
+
} else {
|
345
|
+
heap_addn<HeapForL2>
|
346
|
+
(k, simi, idxi, local_dis, local_idx, k);
|
347
|
+
}
|
348
|
+
};
|
349
|
+
|
330
350
|
auto reorder_result = [&] (float *simi, idx_t *idxi) {
|
331
351
|
if (!do_heap_init) return;
|
332
352
|
if (metric_type == METRIC_INNER_PRODUCT) {
|
@@ -346,7 +366,7 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
346
366
|
return (size_t)0;
|
347
367
|
}
|
348
368
|
FAISS_THROW_IF_NOT_FMT (key < (idx_t) nlist,
|
349
|
-
"Invalid key=%
|
369
|
+
"Invalid key=%" PRId64 " nlist=%zd\n",
|
350
370
|
key, nlist);
|
351
371
|
|
352
372
|
size_t list_size = invlists->list_size(key);
|
@@ -360,18 +380,27 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
360
380
|
|
361
381
|
nlistv++;
|
362
382
|
|
363
|
-
|
383
|
+
try {
|
384
|
+
InvertedLists::ScopedCodes scodes (invlists, key);
|
364
385
|
|
365
|
-
|
366
|
-
|
386
|
+
std::unique_ptr<InvertedLists::ScopedIds> sids;
|
387
|
+
const Index::idx_t * ids = nullptr;
|
367
388
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
389
|
+
if (!store_pairs) {
|
390
|
+
sids.reset (new InvertedLists::ScopedIds (invlists, key));
|
391
|
+
ids = sids->get();
|
392
|
+
}
|
393
|
+
|
394
|
+
nheap += scanner->scan_codes (list_size, scodes.get(),
|
395
|
+
ids, simi, idxi, k);
|
372
396
|
|
373
|
-
|
374
|
-
|
397
|
+
} catch(const std::exception & e) {
|
398
|
+
std::lock_guard<std::mutex> lock(exception_mutex);
|
399
|
+
exception_string =
|
400
|
+
demangle_cpp_symbol(typeid(e).name()) + " " + e.what();
|
401
|
+
interrupt = true;
|
402
|
+
return size_t(0);
|
403
|
+
}
|
375
404
|
|
376
405
|
return list_size;
|
377
406
|
};
|
@@ -383,7 +412,7 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
383
412
|
if (pmode == 0) {
|
384
413
|
|
385
414
|
#pragma omp for
|
386
|
-
for (
|
415
|
+
for (idx_t i = 0; i < n; i++) {
|
387
416
|
|
388
417
|
if (interrupt) {
|
389
418
|
continue;
|
@@ -429,7 +458,7 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
429
458
|
init_result (local_dis.data(), local_idx.data());
|
430
459
|
|
431
460
|
#pragma omp for schedule(dynamic)
|
432
|
-
for (
|
461
|
+
for (long ik = 0; ik < nprobe; ik++) {
|
433
462
|
ndis += scan_one_list
|
434
463
|
(keys [i * nprobe + ik],
|
435
464
|
coarse_dis[i * nprobe + ik],
|
@@ -447,20 +476,42 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
447
476
|
#pragma omp barrier
|
448
477
|
#pragma omp critical
|
449
478
|
{
|
450
|
-
|
451
|
-
|
452
|
-
(k, simi, idxi,
|
453
|
-
local_dis.data(), local_idx.data(), k);
|
454
|
-
} else {
|
455
|
-
heap_addn<HeapForL2>
|
456
|
-
(k, simi, idxi,
|
457
|
-
local_dis.data(), local_idx.data(), k);
|
458
|
-
}
|
479
|
+
add_local_results (local_dis.data(), local_idx.data(),
|
480
|
+
simi, idxi);
|
459
481
|
}
|
460
482
|
#pragma omp barrier
|
461
483
|
#pragma omp single
|
462
484
|
reorder_result (simi, idxi);
|
463
485
|
}
|
486
|
+
} else if (pmode == 2) {
|
487
|
+
std::vector <idx_t> local_idx (k);
|
488
|
+
std::vector <float> local_dis (k);
|
489
|
+
|
490
|
+
#pragma omp single
|
491
|
+
for (int64_t i = 0; i < n; i++) {
|
492
|
+
init_result (distances + i * k, labels + i * k);
|
493
|
+
}
|
494
|
+
|
495
|
+
#pragma omp for schedule(dynamic)
|
496
|
+
for (int64_t ij = 0; ij < n * nprobe; ij++) {
|
497
|
+
size_t i = ij / nprobe;
|
498
|
+
size_t j = ij % nprobe;
|
499
|
+
|
500
|
+
scanner->set_query (x + i * d);
|
501
|
+
init_result (local_dis.data(), local_idx.data());
|
502
|
+
ndis += scan_one_list (
|
503
|
+
keys [ij], coarse_dis[ij],
|
504
|
+
local_dis.data(), local_idx.data());
|
505
|
+
#pragma omp critical
|
506
|
+
{
|
507
|
+
add_local_results (local_dis.data(), local_idx.data(),
|
508
|
+
distances + i * k, labels + i * k);
|
509
|
+
}
|
510
|
+
}
|
511
|
+
#pragma omp single
|
512
|
+
for (int64_t i = 0; i < n; i++) {
|
513
|
+
reorder_result (distances + i * k, labels + i * k);
|
514
|
+
}
|
464
515
|
} else {
|
465
516
|
FAISS_THROW_FMT ("parallel_mode %d not supported\n",
|
466
517
|
pmode);
|
@@ -468,7 +519,12 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|
468
519
|
} // parallel section
|
469
520
|
|
470
521
|
if (interrupt) {
|
471
|
-
|
522
|
+
if (!exception_string.empty()) {
|
523
|
+
FAISS_THROW_FMT ("search interrupted with: %s",
|
524
|
+
exception_string.c_str());
|
525
|
+
} else {
|
526
|
+
FAISS_THROW_MSG ("computation interrupted");
|
527
|
+
}
|
472
528
|
}
|
473
529
|
|
474
530
|
indexIVF_stats.nq += n;
|
@@ -503,11 +559,18 @@ void IndexIVF::range_search (idx_t nx, const float *x, float radius,
|
|
503
559
|
void IndexIVF::range_search_preassigned (
|
504
560
|
idx_t nx, const float *x, float radius,
|
505
561
|
const idx_t *keys, const float *coarse_dis,
|
506
|
-
RangeSearchResult *result
|
562
|
+
RangeSearchResult *result,
|
563
|
+
bool store_pairs,
|
564
|
+
const IVFSearchParameters *params) const
|
507
565
|
{
|
566
|
+
long nprobe = params ? params->nprobe : this->nprobe;
|
567
|
+
long max_codes = params ? params->max_codes : this->max_codes;
|
508
568
|
|
509
569
|
size_t nlistv = 0, ndis = 0;
|
510
|
-
|
570
|
+
|
571
|
+
bool interrupt = false;
|
572
|
+
std::mutex exception_mutex;
|
573
|
+
std::string exception_string;
|
511
574
|
|
512
575
|
std::vector<RangeSearchPartialResult *> all_pres (omp_get_max_threads());
|
513
576
|
|
@@ -527,26 +590,36 @@ void IndexIVF::range_search_preassigned (
|
|
527
590
|
if (key < 0) return;
|
528
591
|
FAISS_THROW_IF_NOT_FMT (
|
529
592
|
key < (idx_t) nlist,
|
530
|
-
"Invalid key=%
|
593
|
+
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
531
594
|
key, ik, nlist);
|
532
595
|
const size_t list_size = invlists->list_size(key);
|
533
596
|
|
534
597
|
if (list_size == 0) return;
|
535
598
|
|
536
|
-
|
537
|
-
|
599
|
+
try {
|
600
|
+
|
601
|
+
InvertedLists::ScopedCodes scodes (invlists, key);
|
602
|
+
InvertedLists::ScopedIds ids (invlists, key);
|
603
|
+
|
604
|
+
scanner->set_list (key, coarse_dis[i * nprobe + ik]);
|
605
|
+
nlistv++;
|
606
|
+
ndis += list_size;
|
607
|
+
scanner->scan_codes_range (list_size, scodes.get(),
|
608
|
+
ids.get(), radius, qres);
|
609
|
+
|
610
|
+
} catch(const std::exception & e) {
|
611
|
+
std::lock_guard<std::mutex> lock(exception_mutex);
|
612
|
+
exception_string =
|
613
|
+
demangle_cpp_symbol(typeid(e).name()) + " " + e.what();
|
614
|
+
interrupt = true;
|
615
|
+
}
|
538
616
|
|
539
|
-
scanner->set_list (key, coarse_dis[i * nprobe + ik]);
|
540
|
-
nlistv++;
|
541
|
-
ndis += list_size;
|
542
|
-
scanner->scan_codes_range (list_size, scodes.get(),
|
543
|
-
ids.get(), radius, qres);
|
544
617
|
};
|
545
618
|
|
546
619
|
if (parallel_mode == 0) {
|
547
620
|
|
548
621
|
#pragma omp for
|
549
|
-
for (
|
622
|
+
for (idx_t i = 0; i < nx; i++) {
|
550
623
|
scanner->set_query (x + i * d);
|
551
624
|
|
552
625
|
RangeQueryResult & qres = pres.new_result (i);
|
@@ -565,7 +638,7 @@ void IndexIVF::range_search_preassigned (
|
|
565
638
|
RangeQueryResult & qres = pres.new_result (i);
|
566
639
|
|
567
640
|
#pragma omp for schedule(dynamic)
|
568
|
-
for (
|
641
|
+
for (int64_t ik = 0; ik < nprobe; ik++) {
|
569
642
|
scan_list_func (i, ik, qres);
|
570
643
|
}
|
571
644
|
}
|
@@ -574,9 +647,9 @@ void IndexIVF::range_search_preassigned (
|
|
574
647
|
RangeQueryResult *qres = nullptr;
|
575
648
|
|
576
649
|
#pragma omp for schedule(dynamic)
|
577
|
-
for (
|
578
|
-
|
579
|
-
|
650
|
+
for (idx_t iik = 0; iik < nx * (idx_t)nprobe; iik++) {
|
651
|
+
idx_t i = iik / (idx_t)nprobe;
|
652
|
+
idx_t ik = iik % (idx_t)nprobe;
|
580
653
|
if (qres == nullptr || qres->qno != i) {
|
581
654
|
FAISS_ASSERT (!qres || i > qres->qno);
|
582
655
|
qres = &pres.new_result (i);
|
@@ -597,6 +670,16 @@ void IndexIVF::range_search_preassigned (
|
|
597
670
|
|
598
671
|
}
|
599
672
|
}
|
673
|
+
|
674
|
+
if (interrupt) {
|
675
|
+
if (!exception_string.empty()) {
|
676
|
+
FAISS_THROW_FMT ("search interrupted with: %s",
|
677
|
+
exception_string.c_str());
|
678
|
+
} else {
|
679
|
+
FAISS_THROW_MSG ("computation interrupted");
|
680
|
+
}
|
681
|
+
}
|
682
|
+
|
600
683
|
indexIVF_stats.nq += nx;
|
601
684
|
indexIVF_stats.nlist += nlistv;
|
602
685
|
indexIVF_stats.ndis += ndis;
|