faiss 0.3.0 → 0.3.2
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 +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/ext/faiss/extconf.rb +9 -2
- data/ext/faiss/index.cpp +1 -1
- data/ext/faiss/index_binary.cpp +2 -2
- data/ext/faiss/product_quantizer.cpp +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +7 -7
- data/vendor/faiss/faiss/AutoTune.h +1 -2
- data/vendor/faiss/faiss/Clustering.cpp +39 -22
- data/vendor/faiss/faiss/Clustering.h +40 -21
- data/vendor/faiss/faiss/IVFlib.cpp +26 -12
- data/vendor/faiss/faiss/Index.cpp +1 -1
- data/vendor/faiss/faiss/Index.h +40 -10
- data/vendor/faiss/faiss/Index2Layer.cpp +7 -7
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +176 -166
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +15 -15
- data/vendor/faiss/faiss/IndexBinary.cpp +9 -4
- data/vendor/faiss/faiss/IndexBinary.h +8 -19
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +24 -31
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +25 -50
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +107 -188
- data/vendor/faiss/faiss/IndexFastScan.cpp +95 -146
- data/vendor/faiss/faiss/IndexFastScan.h +9 -8
- data/vendor/faiss/faiss/IndexFlat.cpp +206 -10
- data/vendor/faiss/faiss/IndexFlat.h +20 -1
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +170 -5
- data/vendor/faiss/faiss/IndexFlatCodes.h +23 -4
- data/vendor/faiss/faiss/IndexHNSW.cpp +231 -382
- data/vendor/faiss/faiss/IndexHNSW.h +62 -49
- data/vendor/faiss/faiss/IndexIDMap.cpp +69 -28
- data/vendor/faiss/faiss/IndexIDMap.h +24 -2
- data/vendor/faiss/faiss/IndexIVF.cpp +162 -56
- data/vendor/faiss/faiss/IndexIVF.h +46 -6
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +33 -26
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +6 -2
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +19 -46
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -3
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +502 -401
- data/vendor/faiss/faiss/IndexIVFFastScan.h +63 -26
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +15 -5
- data/vendor/faiss/faiss/IndexIVFFlat.h +3 -2
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +172 -0
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +56 -0
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +79 -125
- data/vendor/faiss/faiss/IndexIVFPQ.h +6 -7
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +39 -52
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +4 -3
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +45 -29
- data/vendor/faiss/faiss/IndexIVFPQR.h +5 -2
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +25 -27
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +6 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +14 -16
- data/vendor/faiss/faiss/IndexLattice.cpp +1 -19
- data/vendor/faiss/faiss/IndexLattice.h +3 -22
- data/vendor/faiss/faiss/IndexNNDescent.cpp +3 -33
- data/vendor/faiss/faiss/IndexNNDescent.h +1 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +11 -27
- data/vendor/faiss/faiss/IndexNSG.h +11 -11
- data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +56 -0
- data/vendor/faiss/faiss/IndexNeuralNetCodec.h +49 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +72 -88
- data/vendor/faiss/faiss/IndexPQ.h +1 -4
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +1 -1
- data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -31
- data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +54 -24
- data/vendor/faiss/faiss/IndexRefine.h +7 -0
- data/vendor/faiss/faiss/IndexReplicas.cpp +23 -26
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +25 -17
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -4
- data/vendor/faiss/faiss/IndexShards.cpp +21 -29
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +1 -2
- data/vendor/faiss/faiss/MatrixStats.cpp +17 -32
- data/vendor/faiss/faiss/MatrixStats.h +21 -9
- data/vendor/faiss/faiss/MetaIndexes.cpp +35 -35
- data/vendor/faiss/faiss/MetricType.h +7 -2
- data/vendor/faiss/faiss/VectorTransform.cpp +13 -26
- data/vendor/faiss/faiss/VectorTransform.h +7 -7
- data/vendor/faiss/faiss/clone_index.cpp +15 -10
- data/vendor/faiss/faiss/clone_index.h +3 -0
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +95 -17
- data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +152 -0
- data/vendor/faiss/faiss/cppcontrib/factory_tools.h +24 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +83 -30
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +123 -8
- data/vendor/faiss/faiss/gpu/GpuCloner.h +22 -0
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +13 -0
- data/vendor/faiss/faiss/gpu/GpuDistance.h +46 -38
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndex.h +30 -12
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +282 -0
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +4 -4
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +14 -9
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +20 -3
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -11
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +1 -3
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +24 -3
- data/vendor/faiss/faiss/gpu/GpuResources.h +39 -11
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +142 -17
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +57 -3
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +26 -21
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +7 -1
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +8 -5
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +25 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +129 -9
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +332 -40
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +299 -208
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +1 -0
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +1 -1
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +6 -0
- data/vendor/faiss/faiss/gpu/utils/RaftUtils.h +75 -0
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +4 -1
- data/vendor/faiss/faiss/gpu/utils/Timer.h +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +3 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +5 -5
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +26 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +10 -3
- data/vendor/faiss/faiss/impl/DistanceComputer.h +70 -1
- data/vendor/faiss/faiss/impl/FaissAssert.h +4 -2
- data/vendor/faiss/faiss/impl/FaissException.h +13 -34
- data/vendor/faiss/faiss/impl/HNSW.cpp +605 -186
- data/vendor/faiss/faiss/impl/HNSW.h +52 -30
- data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +11 -9
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +34 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +42 -27
- data/vendor/faiss/faiss/impl/NSG.cpp +0 -29
- data/vendor/faiss/faiss/impl/NSG.h +1 -1
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +14 -12
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -22
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +6 -2
- data/vendor/faiss/faiss/impl/Quantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +27 -1015
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +5 -63
- data/vendor/faiss/faiss/impl/ResultHandler.h +347 -172
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +1104 -147
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +3 -8
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +285 -42
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx512.h +248 -0
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +21 -14
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +22 -12
- data/vendor/faiss/faiss/impl/index_read.cpp +74 -34
- data/vendor/faiss/faiss/impl/index_read_utils.h +37 -0
- data/vendor/faiss/faiss/impl/index_write.cpp +88 -51
- data/vendor/faiss/faiss/impl/io.cpp +23 -15
- data/vendor/faiss/faiss/impl/io.h +4 -4
- data/vendor/faiss/faiss/impl/io_macros.h +6 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
- data/vendor/faiss/faiss/impl/platform_macros.h +40 -1
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +14 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +7 -6
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +52 -38
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +487 -49
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +960 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +176 -0
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +481 -225
- data/vendor/faiss/faiss/index_factory.cpp +41 -20
- data/vendor/faiss/faiss/index_io.h +12 -5
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +28 -8
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +3 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +10 -2
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +73 -17
- data/vendor/faiss/faiss/invlists/InvertedLists.h +26 -8
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +24 -9
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +2 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +4 -4
- data/vendor/faiss/faiss/utils/Heap.cpp +3 -1
- data/vendor/faiss/faiss/utils/Heap.h +105 -0
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +342 -0
- data/vendor/faiss/faiss/utils/NeuralNet.h +147 -0
- data/vendor/faiss/faiss/utils/WorkerThread.h +1 -0
- data/vendor/faiss/faiss/utils/bf16.h +36 -0
- data/vendor/faiss/faiss/utils/distances.cpp +147 -123
- data/vendor/faiss/faiss/utils/distances.h +86 -9
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +5 -5
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +1 -1
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +5 -5
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +1 -1
- data/vendor/faiss/faiss/utils/distances_simd.cpp +1589 -243
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +70 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +85 -137
- data/vendor/faiss/faiss/utils/extra_distances.h +3 -2
- data/vendor/faiss/faiss/utils/fp16-arm.h +29 -0
- data/vendor/faiss/faiss/utils/fp16.h +2 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +163 -111
- data/vendor/faiss/faiss/utils/hamming.h +58 -0
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +16 -89
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -0
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +19 -88
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +58 -0
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +14 -104
- data/vendor/faiss/faiss/utils/partitioning.cpp +3 -4
- data/vendor/faiss/faiss/utils/prefetch.h +77 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +0 -14
- data/vendor/faiss/faiss/utils/random.cpp +43 -0
- data/vendor/faiss/faiss/utils/random.h +25 -0
- data/vendor/faiss/faiss/utils/simdlib.h +10 -1
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +0 -6
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +296 -0
- data/vendor/faiss/faiss/utils/simdlib_neon.h +77 -79
- data/vendor/faiss/faiss/utils/simdlib_ppc64.h +1084 -0
- data/vendor/faiss/faiss/utils/sorting.cpp +140 -5
- data/vendor/faiss/faiss/utils/sorting.h +27 -0
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +176 -0
- data/vendor/faiss/faiss/utils/utils.cpp +120 -7
- data/vendor/faiss/faiss/utils/utils.h +60 -20
- metadata +23 -4
- data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +0 -102
|
@@ -36,7 +36,7 @@ IndexBinaryIVF::IndexBinaryIVF(IndexBinary* quantizer, size_t d, size_t nlist)
|
|
|
36
36
|
cp.niter = 10;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
IndexBinaryIVF::IndexBinaryIVF()
|
|
39
|
+
IndexBinaryIVF::IndexBinaryIVF() = default;
|
|
40
40
|
|
|
41
41
|
void IndexBinaryIVF::add(idx_t n, const uint8_t* x) {
|
|
42
42
|
add_with_ids(n, x, nullptr);
|
|
@@ -119,16 +119,16 @@ void IndexBinaryIVF::search(
|
|
|
119
119
|
FAISS_THROW_IF_NOT(k > 0);
|
|
120
120
|
FAISS_THROW_IF_NOT(nprobe > 0);
|
|
121
121
|
|
|
122
|
-
const size_t
|
|
123
|
-
std::unique_ptr<idx_t[]> idx(new idx_t[n *
|
|
124
|
-
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n *
|
|
122
|
+
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
123
|
+
std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_2]);
|
|
124
|
+
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
|
|
125
125
|
|
|
126
126
|
double t0 = getmillisecs();
|
|
127
|
-
quantizer->search(n, x,
|
|
127
|
+
quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get());
|
|
128
128
|
indexIVF_stats.quantization_time += getmillisecs() - t0;
|
|
129
129
|
|
|
130
130
|
t0 = getmillisecs();
|
|
131
|
-
invlists->prefetch_lists(idx.get(), n *
|
|
131
|
+
invlists->prefetch_lists(idx.get(), n * nprobe_2);
|
|
132
132
|
|
|
133
133
|
search_preassigned(
|
|
134
134
|
n, x, k, idx.get(), coarse_dis.get(), distances, labels, false);
|
|
@@ -169,16 +169,16 @@ void IndexBinaryIVF::search_and_reconstruct(
|
|
|
169
169
|
const SearchParameters* params) const {
|
|
170
170
|
FAISS_THROW_IF_NOT_MSG(
|
|
171
171
|
!params, "search params not supported for this index");
|
|
172
|
-
const size_t
|
|
172
|
+
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
173
173
|
FAISS_THROW_IF_NOT(k > 0);
|
|
174
|
-
FAISS_THROW_IF_NOT(
|
|
174
|
+
FAISS_THROW_IF_NOT(nprobe_2 > 0);
|
|
175
175
|
|
|
176
|
-
std::unique_ptr<idx_t[]> idx(new idx_t[n *
|
|
177
|
-
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n *
|
|
176
|
+
std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_2]);
|
|
177
|
+
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
|
|
178
178
|
|
|
179
|
-
quantizer->search(n, x,
|
|
179
|
+
quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get());
|
|
180
180
|
|
|
181
|
-
invlists->prefetch_lists(idx.get(), n *
|
|
181
|
+
invlists->prefetch_lists(idx.get(), n * nprobe_2);
|
|
182
182
|
|
|
183
183
|
// search_preassigned() with `store_pairs` enabled to obtain the list_no
|
|
184
184
|
// and offset into `codes` for reconstruction
|
|
@@ -321,8 +321,8 @@ struct IVFBinaryScannerL2 : BinaryInvertedListScanner {
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
idx_t list_no;
|
|
324
|
-
void set_list(idx_t
|
|
325
|
-
this->list_no =
|
|
324
|
+
void set_list(idx_t list_no_2, uint8_t /* coarse_dis */) override {
|
|
325
|
+
this->list_no = list_no_2;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
uint32_t distance_to_code(const uint8_t* code) const override {
|
|
@@ -357,7 +357,6 @@ struct IVFBinaryScannerL2 : BinaryInvertedListScanner {
|
|
|
357
357
|
const idx_t* __restrict ids,
|
|
358
358
|
int radius,
|
|
359
359
|
RangeQueryResult& result) const override {
|
|
360
|
-
size_t nup = 0;
|
|
361
360
|
for (size_t j = 0; j < n; j++) {
|
|
362
361
|
uint32_t dis = hc.hamming(codes);
|
|
363
362
|
if (dis < radius) {
|
|
@@ -370,7 +369,7 @@ struct IVFBinaryScannerL2 : BinaryInvertedListScanner {
|
|
|
370
369
|
};
|
|
371
370
|
|
|
372
371
|
void search_knn_hamming_heap(
|
|
373
|
-
const IndexBinaryIVF
|
|
372
|
+
const IndexBinaryIVF* ivf,
|
|
374
373
|
size_t n,
|
|
375
374
|
const uint8_t* __restrict x,
|
|
376
375
|
idx_t k,
|
|
@@ -380,10 +379,10 @@ void search_knn_hamming_heap(
|
|
|
380
379
|
idx_t* __restrict labels,
|
|
381
380
|
bool store_pairs,
|
|
382
381
|
const IVFSearchParameters* params) {
|
|
383
|
-
idx_t nprobe = params ? params->nprobe : ivf
|
|
384
|
-
nprobe = std::min((idx_t)ivf
|
|
385
|
-
idx_t max_codes = params ? params->max_codes : ivf
|
|
386
|
-
MetricType metric_type = ivf
|
|
382
|
+
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
383
|
+
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
384
|
+
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
385
|
+
MetricType metric_type = ivf->metric_type;
|
|
387
386
|
|
|
388
387
|
// almost verbatim copy from IndexIVF::search_preassigned
|
|
389
388
|
|
|
@@ -394,11 +393,11 @@ void search_knn_hamming_heap(
|
|
|
394
393
|
#pragma omp parallel if (n > 1) reduction(+ : nlistv, ndis, nheap)
|
|
395
394
|
{
|
|
396
395
|
std::unique_ptr<BinaryInvertedListScanner> scanner(
|
|
397
|
-
ivf
|
|
396
|
+
ivf->get_InvertedListScanner(store_pairs));
|
|
398
397
|
|
|
399
398
|
#pragma omp for
|
|
400
399
|
for (idx_t i = 0; i < n; i++) {
|
|
401
|
-
const uint8_t* xi = x + i * ivf
|
|
400
|
+
const uint8_t* xi = x + i * ivf->code_size;
|
|
402
401
|
scanner->set_query(xi);
|
|
403
402
|
|
|
404
403
|
const idx_t* keysi = keys + i * nprobe;
|
|
@@ -420,23 +419,24 @@ void search_knn_hamming_heap(
|
|
|
420
419
|
continue;
|
|
421
420
|
}
|
|
422
421
|
FAISS_THROW_IF_NOT_FMT(
|
|
423
|
-
key < (idx_t)ivf
|
|
422
|
+
key < (idx_t)ivf->nlist,
|
|
424
423
|
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
|
425
424
|
key,
|
|
426
425
|
ik,
|
|
427
|
-
ivf
|
|
426
|
+
ivf->nlist);
|
|
428
427
|
|
|
429
428
|
scanner->set_list(key, coarse_dis[i * nprobe + ik]);
|
|
430
429
|
|
|
431
430
|
nlistv++;
|
|
432
431
|
|
|
433
|
-
size_t list_size = ivf
|
|
434
|
-
InvertedLists::ScopedCodes scodes(ivf
|
|
432
|
+
size_t list_size = ivf->invlists->list_size(key);
|
|
433
|
+
InvertedLists::ScopedCodes scodes(ivf->invlists, key);
|
|
435
434
|
std::unique_ptr<InvertedLists::ScopedIds> sids;
|
|
436
435
|
const idx_t* ids = nullptr;
|
|
437
436
|
|
|
438
437
|
if (!store_pairs) {
|
|
439
|
-
sids
|
|
438
|
+
sids = std::make_unique<InvertedLists::ScopedIds>(
|
|
439
|
+
ivf->invlists, key);
|
|
440
440
|
ids = sids->get();
|
|
441
441
|
}
|
|
442
442
|
|
|
@@ -456,7 +456,7 @@ void search_knn_hamming_heap(
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
} // parallel for
|
|
459
|
-
}
|
|
459
|
+
} // parallel
|
|
460
460
|
|
|
461
461
|
indexIVF_stats.nq += n;
|
|
462
462
|
indexIVF_stats.nlist += nlistv;
|
|
@@ -466,7 +466,7 @@ void search_knn_hamming_heap(
|
|
|
466
466
|
|
|
467
467
|
template <class HammingComputer, bool store_pairs>
|
|
468
468
|
void search_knn_hamming_count(
|
|
469
|
-
const IndexBinaryIVF
|
|
469
|
+
const IndexBinaryIVF* ivf,
|
|
470
470
|
size_t nx,
|
|
471
471
|
const uint8_t* __restrict x,
|
|
472
472
|
const idx_t* __restrict keys,
|
|
@@ -474,21 +474,21 @@ void search_knn_hamming_count(
|
|
|
474
474
|
int32_t* __restrict distances,
|
|
475
475
|
idx_t* __restrict labels,
|
|
476
476
|
const IVFSearchParameters* params) {
|
|
477
|
-
const int nBuckets = ivf
|
|
477
|
+
const int nBuckets = ivf->d + 1;
|
|
478
478
|
std::vector<int> all_counters(nx * nBuckets, 0);
|
|
479
479
|
std::unique_ptr<idx_t[]> all_ids_per_dis(new idx_t[nx * nBuckets * k]);
|
|
480
480
|
|
|
481
|
-
idx_t nprobe = params ? params->nprobe : ivf
|
|
482
|
-
nprobe = std::min((idx_t)ivf
|
|
483
|
-
idx_t max_codes = params ? params->max_codes : ivf
|
|
481
|
+
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
482
|
+
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
483
|
+
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
484
484
|
|
|
485
485
|
std::vector<HCounterState<HammingComputer>> cs;
|
|
486
486
|
for (size_t i = 0; i < nx; ++i) {
|
|
487
487
|
cs.push_back(HCounterState<HammingComputer>(
|
|
488
488
|
all_counters.data() + i * nBuckets,
|
|
489
489
|
all_ids_per_dis.get() + i * nBuckets * k,
|
|
490
|
-
x + i * ivf
|
|
491
|
-
ivf
|
|
490
|
+
x + i * ivf->code_size,
|
|
491
|
+
ivf->d,
|
|
492
492
|
k));
|
|
493
493
|
}
|
|
494
494
|
|
|
@@ -508,27 +508,28 @@ void search_knn_hamming_count(
|
|
|
508
508
|
continue;
|
|
509
509
|
}
|
|
510
510
|
FAISS_THROW_IF_NOT_FMT(
|
|
511
|
-
key < (idx_t)ivf
|
|
511
|
+
key < (idx_t)ivf->nlist,
|
|
512
512
|
"Invalid key=%" PRId64 " at ik=%zd nlist=%zd\n",
|
|
513
513
|
key,
|
|
514
514
|
ik,
|
|
515
|
-
ivf
|
|
515
|
+
ivf->nlist);
|
|
516
516
|
|
|
517
517
|
nlistv++;
|
|
518
|
-
size_t list_size = ivf
|
|
519
|
-
InvertedLists::ScopedCodes scodes(ivf
|
|
518
|
+
size_t list_size = ivf->invlists->list_size(key);
|
|
519
|
+
InvertedLists::ScopedCodes scodes(ivf->invlists, key);
|
|
520
520
|
const uint8_t* list_vecs = scodes.get();
|
|
521
521
|
const idx_t* ids =
|
|
522
|
-
store_pairs ? nullptr : ivf
|
|
522
|
+
store_pairs ? nullptr : ivf->invlists->get_ids(key);
|
|
523
523
|
|
|
524
524
|
for (size_t j = 0; j < list_size; j++) {
|
|
525
|
-
const uint8_t* yj = list_vecs + ivf
|
|
525
|
+
const uint8_t* yj = list_vecs + ivf->code_size * j;
|
|
526
526
|
|
|
527
527
|
idx_t id = store_pairs ? (key << 32 | j) : ids[j];
|
|
528
528
|
csi.update_counter(yj, id);
|
|
529
529
|
}
|
|
530
|
-
if (ids)
|
|
531
|
-
ivf
|
|
530
|
+
if (ids) {
|
|
531
|
+
ivf->invlists->release_ids(key, ids);
|
|
532
|
+
}
|
|
532
533
|
|
|
533
534
|
nscan += list_size;
|
|
534
535
|
if (max_codes && nscan >= max_codes)
|
|
@@ -634,7 +635,7 @@ struct BlockSearchVariableK {
|
|
|
634
635
|
|
|
635
636
|
template <class HammingComputer>
|
|
636
637
|
void search_knn_hamming_per_invlist(
|
|
637
|
-
const IndexBinaryIVF
|
|
638
|
+
const IndexBinaryIVF* ivf,
|
|
638
639
|
size_t n,
|
|
639
640
|
const uint8_t* __restrict x,
|
|
640
641
|
idx_t k,
|
|
@@ -644,12 +645,11 @@ void search_knn_hamming_per_invlist(
|
|
|
644
645
|
idx_t* __restrict labels,
|
|
645
646
|
bool store_pairs,
|
|
646
647
|
const IVFSearchParameters* params) {
|
|
647
|
-
idx_t nprobe = params ? params->nprobe : ivf
|
|
648
|
-
nprobe = std::min((idx_t)ivf
|
|
649
|
-
idx_t max_codes = params ? params->max_codes : ivf
|
|
648
|
+
idx_t nprobe = params ? params->nprobe : ivf->nprobe;
|
|
649
|
+
nprobe = std::min((idx_t)ivf->nlist, nprobe);
|
|
650
|
+
idx_t max_codes = params ? params->max_codes : ivf->max_codes;
|
|
650
651
|
FAISS_THROW_IF_NOT(max_codes == 0);
|
|
651
652
|
FAISS_THROW_IF_NOT(!store_pairs);
|
|
652
|
-
MetricType metric_type = ivf.metric_type;
|
|
653
653
|
|
|
654
654
|
// reorder buckets
|
|
655
655
|
std::vector<int64_t> lims(n + 1);
|
|
@@ -658,18 +658,18 @@ void search_knn_hamming_per_invlist(
|
|
|
658
658
|
for (idx_t i = 0; i < n * nprobe; i++) {
|
|
659
659
|
keys[i] = keys_in[i];
|
|
660
660
|
}
|
|
661
|
-
matrix_bucket_sort_inplace(n, nprobe, keys, ivf
|
|
661
|
+
matrix_bucket_sort_inplace(n, nprobe, keys, ivf->nlist, lims.data(), 0);
|
|
662
662
|
|
|
663
663
|
using C = CMax<int32_t, idx_t>;
|
|
664
664
|
heap_heapify<C>(n * k, distances, labels);
|
|
665
|
-
const size_t code_size = ivf
|
|
665
|
+
const size_t code_size = ivf->code_size;
|
|
666
666
|
|
|
667
|
-
for (idx_t l = 0; l < ivf
|
|
667
|
+
for (idx_t l = 0; l < ivf->nlist; l++) {
|
|
668
668
|
idx_t l0 = lims[l], nq = lims[l + 1] - l0;
|
|
669
669
|
|
|
670
|
-
InvertedLists::ScopedCodes scodes(ivf
|
|
671
|
-
InvertedLists::ScopedIds sidx(ivf
|
|
672
|
-
idx_t nb = ivf
|
|
670
|
+
InvertedLists::ScopedCodes scodes(ivf->invlists, l);
|
|
671
|
+
InvertedLists::ScopedIds sidx(ivf->invlists, l);
|
|
672
|
+
idx_t nb = ivf->invlists->list_size(l);
|
|
673
673
|
const uint8_t* bcodes = scodes.get();
|
|
674
674
|
const idx_t* ids = sidx.get();
|
|
675
675
|
|
|
@@ -735,151 +735,70 @@ void search_knn_hamming_per_invlist(
|
|
|
735
735
|
}
|
|
736
736
|
}
|
|
737
737
|
|
|
738
|
+
struct Run_search_knn_hamming_per_invlist {
|
|
739
|
+
using T = void;
|
|
740
|
+
|
|
741
|
+
template <class HammingComputer, class... Types>
|
|
742
|
+
void f(Types... args) {
|
|
743
|
+
search_knn_hamming_per_invlist<HammingComputer>(args...);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
|
|
738
747
|
template <bool store_pairs>
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
int32_t* distances,
|
|
746
|
-
idx_t* labels,
|
|
747
|
-
const IVFSearchParameters* params) {
|
|
748
|
-
switch (ivf.code_size) {
|
|
749
|
-
#define HANDLE_CS(cs) \
|
|
750
|
-
case cs: \
|
|
751
|
-
search_knn_hamming_count<HammingComputer##cs, store_pairs>( \
|
|
752
|
-
ivf, nx, x, keys, k, distances, labels, params); \
|
|
753
|
-
break;
|
|
754
|
-
HANDLE_CS(4);
|
|
755
|
-
HANDLE_CS(8);
|
|
756
|
-
HANDLE_CS(16);
|
|
757
|
-
HANDLE_CS(20);
|
|
758
|
-
HANDLE_CS(32);
|
|
759
|
-
HANDLE_CS(64);
|
|
760
|
-
#undef HANDLE_CS
|
|
761
|
-
default:
|
|
762
|
-
search_knn_hamming_count<HammingComputerDefault, store_pairs>(
|
|
763
|
-
ivf, nx, x, keys, k, distances, labels, params);
|
|
764
|
-
break;
|
|
748
|
+
struct Run_search_knn_hamming_count {
|
|
749
|
+
using T = void;
|
|
750
|
+
|
|
751
|
+
template <class HammingComputer, class... Types>
|
|
752
|
+
void f(Types... args) {
|
|
753
|
+
search_knn_hamming_count<HammingComputer, store_pairs>(args...);
|
|
765
754
|
}
|
|
766
|
-
}
|
|
755
|
+
};
|
|
767
756
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
const int32_t* coarse_dis,
|
|
775
|
-
int32_t* distances,
|
|
776
|
-
idx_t* labels,
|
|
777
|
-
bool store_pairs,
|
|
778
|
-
const IVFSearchParameters* params) {
|
|
779
|
-
switch (ivf.code_size) {
|
|
780
|
-
#define HANDLE_CS(cs) \
|
|
781
|
-
case cs: \
|
|
782
|
-
search_knn_hamming_per_invlist<HammingComputer##cs>( \
|
|
783
|
-
ivf, \
|
|
784
|
-
n, \
|
|
785
|
-
x, \
|
|
786
|
-
k, \
|
|
787
|
-
keys, \
|
|
788
|
-
coarse_dis, \
|
|
789
|
-
distances, \
|
|
790
|
-
labels, \
|
|
791
|
-
store_pairs, \
|
|
792
|
-
params); \
|
|
793
|
-
break;
|
|
794
|
-
HANDLE_CS(4);
|
|
795
|
-
HANDLE_CS(8);
|
|
796
|
-
HANDLE_CS(16);
|
|
797
|
-
HANDLE_CS(20);
|
|
798
|
-
HANDLE_CS(32);
|
|
799
|
-
HANDLE_CS(64);
|
|
800
|
-
#undef HANDLE_CS
|
|
801
|
-
default:
|
|
802
|
-
search_knn_hamming_per_invlist<HammingComputerDefault>(
|
|
803
|
-
ivf,
|
|
804
|
-
n,
|
|
805
|
-
x,
|
|
806
|
-
k,
|
|
807
|
-
keys,
|
|
808
|
-
coarse_dis,
|
|
809
|
-
distances,
|
|
810
|
-
labels,
|
|
811
|
-
store_pairs,
|
|
812
|
-
params);
|
|
813
|
-
break;
|
|
757
|
+
struct BuildScanner {
|
|
758
|
+
using T = BinaryInvertedListScanner*;
|
|
759
|
+
|
|
760
|
+
template <class HammingComputer>
|
|
761
|
+
T f(size_t code_size, bool store_pairs) {
|
|
762
|
+
return new IVFBinaryScannerL2<HammingComputer>(code_size, store_pairs);
|
|
814
763
|
}
|
|
815
|
-
}
|
|
764
|
+
};
|
|
816
765
|
|
|
817
766
|
} // anonymous namespace
|
|
818
767
|
|
|
819
768
|
BinaryInvertedListScanner* IndexBinaryIVF::get_InvertedListScanner(
|
|
820
769
|
bool store_pairs) const {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
case 4:
|
|
824
|
-
HC(HammingComputer4);
|
|
825
|
-
case 8:
|
|
826
|
-
HC(HammingComputer8);
|
|
827
|
-
case 16:
|
|
828
|
-
HC(HammingComputer16);
|
|
829
|
-
case 20:
|
|
830
|
-
HC(HammingComputer20);
|
|
831
|
-
case 32:
|
|
832
|
-
HC(HammingComputer32);
|
|
833
|
-
case 64:
|
|
834
|
-
HC(HammingComputer64);
|
|
835
|
-
default:
|
|
836
|
-
HC(HammingComputerDefault);
|
|
837
|
-
}
|
|
838
|
-
#undef HC
|
|
770
|
+
BuildScanner bs;
|
|
771
|
+
return dispatch_HammingComputer(code_size, bs, code_size, store_pairs);
|
|
839
772
|
}
|
|
840
773
|
|
|
841
774
|
void IndexBinaryIVF::search_preassigned(
|
|
842
775
|
idx_t n,
|
|
843
776
|
const uint8_t* x,
|
|
844
777
|
idx_t k,
|
|
845
|
-
const idx_t*
|
|
846
|
-
const int32_t*
|
|
847
|
-
int32_t*
|
|
848
|
-
idx_t*
|
|
778
|
+
const idx_t* cidx,
|
|
779
|
+
const int32_t* cdis,
|
|
780
|
+
int32_t* dis,
|
|
781
|
+
idx_t* idx,
|
|
849
782
|
bool store_pairs,
|
|
850
783
|
const IVFSearchParameters* params) const {
|
|
851
784
|
if (per_invlist_search) {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
x,
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
coarse_dis,
|
|
859
|
-
distances,
|
|
860
|
-
labels,
|
|
861
|
-
store_pairs,
|
|
862
|
-
params);
|
|
785
|
+
Run_search_knn_hamming_per_invlist r;
|
|
786
|
+
// clang-format off
|
|
787
|
+
dispatch_HammingComputer(
|
|
788
|
+
code_size, r, this, n, x, k,
|
|
789
|
+
cidx, cdis, dis, idx, store_pairs, params);
|
|
790
|
+
// clang-format on
|
|
863
791
|
} else if (use_heap) {
|
|
864
792
|
search_knn_hamming_heap(
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
idx,
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
params);
|
|
875
|
-
} else {
|
|
876
|
-
if (store_pairs) {
|
|
877
|
-
search_knn_hamming_count_1<true>(
|
|
878
|
-
*this, n, x, idx, k, distances, labels, params);
|
|
879
|
-
} else {
|
|
880
|
-
search_knn_hamming_count_1<false>(
|
|
881
|
-
*this, n, x, idx, k, distances, labels, params);
|
|
882
|
-
}
|
|
793
|
+
this, n, x, k, cidx, cdis, dis, idx, store_pairs, params);
|
|
794
|
+
} else if (store_pairs) { // !use_heap && store_pairs
|
|
795
|
+
Run_search_knn_hamming_count<true> r;
|
|
796
|
+
dispatch_HammingComputer(
|
|
797
|
+
code_size, r, this, n, x, cidx, k, dis, idx, params);
|
|
798
|
+
} else { // !use_heap && !store_pairs
|
|
799
|
+
Run_search_knn_hamming_count<false> r;
|
|
800
|
+
dispatch_HammingComputer(
|
|
801
|
+
code_size, r, this, n, x, cidx, k, dis, idx, params);
|
|
883
802
|
}
|
|
884
803
|
}
|
|
885
804
|
|
|
@@ -891,16 +810,16 @@ void IndexBinaryIVF::range_search(
|
|
|
891
810
|
const SearchParameters* params) const {
|
|
892
811
|
FAISS_THROW_IF_NOT_MSG(
|
|
893
812
|
!params, "search params not supported for this index");
|
|
894
|
-
const size_t
|
|
895
|
-
std::unique_ptr<idx_t[]> idx(new idx_t[n *
|
|
896
|
-
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n *
|
|
813
|
+
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
814
|
+
std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_2]);
|
|
815
|
+
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
|
|
897
816
|
|
|
898
817
|
double t0 = getmillisecs();
|
|
899
|
-
quantizer->search(n, x,
|
|
818
|
+
quantizer->search(n, x, nprobe_2, coarse_dis.get(), idx.get());
|
|
900
819
|
indexIVF_stats.quantization_time += getmillisecs() - t0;
|
|
901
820
|
|
|
902
821
|
t0 = getmillisecs();
|
|
903
|
-
invlists->prefetch_lists(idx.get(), n *
|
|
822
|
+
invlists->prefetch_lists(idx.get(), n * nprobe_2);
|
|
904
823
|
|
|
905
824
|
range_search_preassigned(n, x, radius, idx.get(), coarse_dis.get(), res);
|
|
906
825
|
|
|
@@ -914,7 +833,7 @@ void IndexBinaryIVF::range_search_preassigned(
|
|
|
914
833
|
const idx_t* __restrict assign,
|
|
915
834
|
const int32_t* __restrict centroid_dis,
|
|
916
835
|
RangeSearchResult* __restrict res) const {
|
|
917
|
-
const size_t
|
|
836
|
+
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
918
837
|
bool store_pairs = false;
|
|
919
838
|
size_t nlistv = 0, ndis = 0;
|
|
920
839
|
|
|
@@ -930,7 +849,7 @@ void IndexBinaryIVF::range_search_preassigned(
|
|
|
930
849
|
all_pres[omp_get_thread_num()] = &pres;
|
|
931
850
|
|
|
932
851
|
auto scan_list_func = [&](size_t i, size_t ik, RangeQueryResult& qres) {
|
|
933
|
-
idx_t key = assign[i *
|
|
852
|
+
idx_t key = assign[i * nprobe_2 + ik]; /* select the list */
|
|
934
853
|
if (key < 0)
|
|
935
854
|
return;
|
|
936
855
|
FAISS_THROW_IF_NOT_FMT(
|
|
@@ -947,7 +866,7 @@ void IndexBinaryIVF::range_search_preassigned(
|
|
|
947
866
|
InvertedLists::ScopedCodes scodes(invlists, key);
|
|
948
867
|
InvertedLists::ScopedIds ids(invlists, key);
|
|
949
868
|
|
|
950
|
-
scanner->set_list(key, assign[i *
|
|
869
|
+
scanner->set_list(key, assign[i * nprobe_2 + ik]);
|
|
951
870
|
nlistv++;
|
|
952
871
|
ndis += list_size;
|
|
953
872
|
scanner->scan_codes_range(
|
|
@@ -960,7 +879,7 @@ void IndexBinaryIVF::range_search_preassigned(
|
|
|
960
879
|
|
|
961
880
|
RangeQueryResult& qres = pres.new_result(i);
|
|
962
881
|
|
|
963
|
-
for (size_t ik = 0; ik <
|
|
882
|
+
for (size_t ik = 0; ik < nprobe_2; ik++) {
|
|
964
883
|
scan_list_func(i, ik, qres);
|
|
965
884
|
}
|
|
966
885
|
}
|