faiss 0.2.3 → 0.2.5
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 +23 -21
- data/ext/faiss/extconf.rb +11 -0
- data/ext/faiss/index.cpp +4 -4
- data/ext/faiss/index_binary.cpp +6 -6
- data/ext/faiss/product_quantizer.cpp +4 -4
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +13 -0
- data/vendor/faiss/faiss/Clustering.cpp +32 -0
- data/vendor/faiss/faiss/Clustering.h +14 -0
- data/vendor/faiss/faiss/IVFlib.cpp +101 -2
- data/vendor/faiss/faiss/IVFlib.h +26 -2
- data/vendor/faiss/faiss/Index.cpp +36 -3
- data/vendor/faiss/faiss/Index.h +43 -6
- data/vendor/faiss/faiss/Index2Layer.cpp +24 -93
- data/vendor/faiss/faiss/Index2Layer.h +8 -17
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +610 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +253 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
- data/vendor/faiss/faiss/IndexBinary.h +18 -3
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
- data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
- data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
- data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
- data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
- data/vendor/faiss/faiss/IndexFastScan.h +145 -0
- data/vendor/faiss/faiss/IndexFlat.cpp +52 -69
- data/vendor/faiss/faiss/IndexFlat.h +16 -19
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +101 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +59 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
- data/vendor/faiss/faiss/IndexHNSW.h +4 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
- data/vendor/faiss/faiss/IndexIDMap.h +107 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +200 -40
- data/vendor/faiss/faiss/IndexIVF.h +59 -22
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +393 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +183 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +43 -26
- data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +238 -53
- data/vendor/faiss/faiss/IndexIVFPQ.h +6 -2
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +63 -40
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +23 -7
- data/vendor/faiss/faiss/IndexLSH.cpp +8 -32
- data/vendor/faiss/faiss/IndexLSH.h +4 -16
- data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
- data/vendor/faiss/faiss/IndexLattice.h +3 -1
- data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -5
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +37 -5
- data/vendor/faiss/faiss/IndexNSG.h +25 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +108 -120
- data/vendor/faiss/faiss/IndexPQ.h +21 -22
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
- data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
- data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
- data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
- data/vendor/faiss/faiss/IndexRefine.cpp +36 -4
- data/vendor/faiss/faiss/IndexRefine.h +14 -2
- data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
- data/vendor/faiss/faiss/IndexReplicas.h +2 -1
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +28 -43
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +8 -23
- data/vendor/faiss/faiss/IndexShards.cpp +4 -1
- data/vendor/faiss/faiss/IndexShards.h +2 -1
- data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
- data/vendor/faiss/faiss/MetaIndexes.h +3 -81
- data/vendor/faiss/faiss/VectorTransform.cpp +45 -1
- data/vendor/faiss/faiss/VectorTransform.h +25 -4
- data/vendor/faiss/faiss/clone_index.cpp +26 -3
- data/vendor/faiss/faiss/clone_index.h +3 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
- data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +2 -6
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
- data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +331 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +110 -19
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
- data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +133 -32
- data/vendor/faiss/faiss/impl/HNSW.h +19 -16
- data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
- data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +378 -217
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +106 -29
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -4
- data/vendor/faiss/faiss/impl/NSG.h +1 -1
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
- data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +521 -55
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +94 -16
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +108 -191
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
- data/vendor/faiss/faiss/impl/index_read.cpp +338 -24
- data/vendor/faiss/faiss/impl/index_write.cpp +300 -18
- data/vendor/faiss/faiss/impl/io.cpp +1 -1
- data/vendor/faiss/faiss/impl/io_macros.h +20 -0
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +303 -0
- data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
- data/vendor/faiss/faiss/index_factory.cpp +772 -412
- data/vendor/faiss/faiss/index_factory.h +3 -0
- data/vendor/faiss/faiss/index_io.h +5 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
- data/vendor/faiss/faiss/utils/Heap.h +31 -15
- data/vendor/faiss/faiss/utils/distances.cpp +384 -58
- data/vendor/faiss/faiss/utils/distances.h +149 -18
- data/vendor/faiss/faiss/utils/distances_simd.cpp +776 -6
- data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
- data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
- data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
- data/vendor/faiss/faiss/utils/fp16.h +11 -0
- data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
- data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
- data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
- data/vendor/faiss/faiss/utils/random.cpp +53 -0
- data/vendor/faiss/faiss/utils/random.h +5 -0
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
- data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
- data/vendor/faiss/faiss/utils/utils.h +1 -1
- metadata +46 -5
- data/vendor/faiss/faiss/IndexResidual.cpp +0 -291
- data/vendor/faiss/faiss/IndexResidual.h +0 -152
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <faiss/Index.h>
|
|
11
|
+
#include <faiss/utils/AlignedTable.h>
|
|
12
|
+
|
|
13
|
+
namespace faiss {
|
|
14
|
+
|
|
15
|
+
/** Fast scan version of IndexPQ and IndexAQ. Works for 4-bit PQ and AQ for now.
|
|
16
|
+
*
|
|
17
|
+
* The codes are not stored sequentially but grouped in blocks of size bbs.
|
|
18
|
+
* This makes it possible to compute distances quickly with SIMD instructions.
|
|
19
|
+
* The trailing codes (padding codes that are added to complete the last code)
|
|
20
|
+
* are garbage.
|
|
21
|
+
*
|
|
22
|
+
* Implementations:
|
|
23
|
+
* 12: blocked loop with internal loop on Q with qbs
|
|
24
|
+
* 13: same with reservoir accumulator to store results
|
|
25
|
+
* 14: no qbs with heap accumulator
|
|
26
|
+
* 15: no qbs with reservoir accumulator
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
struct IndexFastScan : Index {
|
|
30
|
+
// implementation to select
|
|
31
|
+
int implem = 0;
|
|
32
|
+
// skip some parts of the computation (for timing)
|
|
33
|
+
int skip = 0;
|
|
34
|
+
|
|
35
|
+
// size of the kernel
|
|
36
|
+
int bbs; // set at build time
|
|
37
|
+
int qbs = 0; // query block size 0 = use default
|
|
38
|
+
|
|
39
|
+
// vector quantizer
|
|
40
|
+
size_t M;
|
|
41
|
+
size_t nbits;
|
|
42
|
+
size_t ksub;
|
|
43
|
+
size_t code_size;
|
|
44
|
+
|
|
45
|
+
// packed version of the codes
|
|
46
|
+
size_t ntotal2;
|
|
47
|
+
size_t M2;
|
|
48
|
+
|
|
49
|
+
AlignedTable<uint8_t> codes;
|
|
50
|
+
|
|
51
|
+
// this is for testing purposes only
|
|
52
|
+
// (set when initialized by IndexPQ or IndexAQ)
|
|
53
|
+
const uint8_t* orig_codes = nullptr;
|
|
54
|
+
|
|
55
|
+
void init_fastscan(
|
|
56
|
+
int d,
|
|
57
|
+
size_t M,
|
|
58
|
+
size_t nbits,
|
|
59
|
+
MetricType metric,
|
|
60
|
+
int bbs);
|
|
61
|
+
|
|
62
|
+
IndexFastScan();
|
|
63
|
+
|
|
64
|
+
void reset() override;
|
|
65
|
+
|
|
66
|
+
void search(
|
|
67
|
+
idx_t n,
|
|
68
|
+
const float* x,
|
|
69
|
+
idx_t k,
|
|
70
|
+
float* distances,
|
|
71
|
+
idx_t* labels,
|
|
72
|
+
const SearchParameters* params = nullptr) const override;
|
|
73
|
+
|
|
74
|
+
void add(idx_t n, const float* x) override;
|
|
75
|
+
|
|
76
|
+
virtual void compute_codes(uint8_t* codes, idx_t n, const float* x)
|
|
77
|
+
const = 0;
|
|
78
|
+
|
|
79
|
+
virtual void compute_float_LUT(float* lut, idx_t n, const float* x)
|
|
80
|
+
const = 0;
|
|
81
|
+
|
|
82
|
+
// called by search function
|
|
83
|
+
void compute_quantized_LUT(
|
|
84
|
+
idx_t n,
|
|
85
|
+
const float* x,
|
|
86
|
+
uint8_t* lut,
|
|
87
|
+
float* normalizers) const;
|
|
88
|
+
|
|
89
|
+
template <bool is_max, class Scaler>
|
|
90
|
+
void search_dispatch_implem(
|
|
91
|
+
idx_t n,
|
|
92
|
+
const float* x,
|
|
93
|
+
idx_t k,
|
|
94
|
+
float* distances,
|
|
95
|
+
idx_t* labels,
|
|
96
|
+
const Scaler& scaler) const;
|
|
97
|
+
|
|
98
|
+
template <class Cfloat, class Scaler>
|
|
99
|
+
void search_implem_234(
|
|
100
|
+
idx_t n,
|
|
101
|
+
const float* x,
|
|
102
|
+
idx_t k,
|
|
103
|
+
float* distances,
|
|
104
|
+
idx_t* labels,
|
|
105
|
+
const Scaler& scaler) const;
|
|
106
|
+
|
|
107
|
+
template <class C, class Scaler>
|
|
108
|
+
void search_implem_12(
|
|
109
|
+
idx_t n,
|
|
110
|
+
const float* x,
|
|
111
|
+
idx_t k,
|
|
112
|
+
float* distances,
|
|
113
|
+
idx_t* labels,
|
|
114
|
+
int impl,
|
|
115
|
+
const Scaler& scaler) const;
|
|
116
|
+
|
|
117
|
+
template <class C, class Scaler>
|
|
118
|
+
void search_implem_14(
|
|
119
|
+
idx_t n,
|
|
120
|
+
const float* x,
|
|
121
|
+
idx_t k,
|
|
122
|
+
float* distances,
|
|
123
|
+
idx_t* labels,
|
|
124
|
+
int impl,
|
|
125
|
+
const Scaler& scaler) const;
|
|
126
|
+
|
|
127
|
+
void reconstruct(idx_t key, float* recons) const override;
|
|
128
|
+
size_t remove_ids(const IDSelector& sel) override;
|
|
129
|
+
void merge_from(Index& otherIndex, idx_t add_id = 0) override;
|
|
130
|
+
void check_compatible_for_merge(const Index& otherIndex) const override;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
struct FastScanStats {
|
|
134
|
+
uint64_t t0, t1, t2, t3;
|
|
135
|
+
FastScanStats() {
|
|
136
|
+
reset();
|
|
137
|
+
}
|
|
138
|
+
void reset() {
|
|
139
|
+
memset(this, 0, sizeof(*this));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
FAISS_API extern FastScanStats FastScan_stats;
|
|
144
|
+
|
|
145
|
+
} // namespace faiss
|
|
@@ -19,38 +19,31 @@
|
|
|
19
19
|
|
|
20
20
|
namespace faiss {
|
|
21
21
|
|
|
22
|
-
IndexFlat::IndexFlat(idx_t d, MetricType metric)
|
|
23
|
-
|
|
24
|
-
void IndexFlat::add(idx_t n, const float* x) {
|
|
25
|
-
xb.insert(xb.end(), x, x + n * d);
|
|
26
|
-
ntotal += n;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
void IndexFlat::reset() {
|
|
30
|
-
xb.clear();
|
|
31
|
-
ntotal = 0;
|
|
32
|
-
}
|
|
22
|
+
IndexFlat::IndexFlat(idx_t d, MetricType metric)
|
|
23
|
+
: IndexFlatCodes(sizeof(float) * d, d, metric) {}
|
|
33
24
|
|
|
34
25
|
void IndexFlat::search(
|
|
35
26
|
idx_t n,
|
|
36
27
|
const float* x,
|
|
37
28
|
idx_t k,
|
|
38
29
|
float* distances,
|
|
39
|
-
idx_t* labels
|
|
30
|
+
idx_t* labels,
|
|
31
|
+
const SearchParameters* params) const {
|
|
32
|
+
IDSelector* sel = params ? params->sel : nullptr;
|
|
40
33
|
FAISS_THROW_IF_NOT(k > 0);
|
|
41
34
|
|
|
42
35
|
// we see the distances and labels as heaps
|
|
43
|
-
|
|
44
36
|
if (metric_type == METRIC_INNER_PRODUCT) {
|
|
45
37
|
float_minheap_array_t res = {size_t(n), size_t(k), labels, distances};
|
|
46
|
-
knn_inner_product(x,
|
|
38
|
+
knn_inner_product(x, get_xb(), d, n, ntotal, &res, sel);
|
|
47
39
|
} else if (metric_type == METRIC_L2) {
|
|
48
40
|
float_maxheap_array_t res = {size_t(n), size_t(k), labels, distances};
|
|
49
|
-
knn_L2sqr(x,
|
|
41
|
+
knn_L2sqr(x, get_xb(), d, n, ntotal, &res, nullptr, sel);
|
|
50
42
|
} else {
|
|
43
|
+
FAISS_THROW_IF_NOT(!sel);
|
|
51
44
|
float_maxheap_array_t res = {size_t(n), size_t(k), labels, distances};
|
|
52
45
|
knn_extra_metrics(
|
|
53
|
-
x,
|
|
46
|
+
x, get_xb(), d, n, ntotal, metric_type, metric_arg, &res);
|
|
54
47
|
}
|
|
55
48
|
}
|
|
56
49
|
|
|
@@ -58,14 +51,17 @@ void IndexFlat::range_search(
|
|
|
58
51
|
idx_t n,
|
|
59
52
|
const float* x,
|
|
60
53
|
float radius,
|
|
61
|
-
RangeSearchResult* result
|
|
54
|
+
RangeSearchResult* result,
|
|
55
|
+
const SearchParameters* params) const {
|
|
56
|
+
IDSelector* sel = params ? params->sel : nullptr;
|
|
57
|
+
|
|
62
58
|
switch (metric_type) {
|
|
63
59
|
case METRIC_INNER_PRODUCT:
|
|
64
60
|
range_search_inner_product(
|
|
65
|
-
x,
|
|
61
|
+
x, get_xb(), d, n, ntotal, radius, result, sel);
|
|
66
62
|
break;
|
|
67
63
|
case METRIC_L2:
|
|
68
|
-
range_search_L2sqr(x,
|
|
64
|
+
range_search_L2sqr(x, get_xb(), d, n, ntotal, radius, result, sel);
|
|
69
65
|
break;
|
|
70
66
|
default:
|
|
71
67
|
FAISS_THROW_MSG("metric type not supported");
|
|
@@ -80,49 +76,28 @@ void IndexFlat::compute_distance_subset(
|
|
|
80
76
|
const idx_t* labels) const {
|
|
81
77
|
switch (metric_type) {
|
|
82
78
|
case METRIC_INNER_PRODUCT:
|
|
83
|
-
fvec_inner_products_by_idx(
|
|
84
|
-
distances, x, xb.data(), labels, d, n, k);
|
|
79
|
+
fvec_inner_products_by_idx(distances, x, get_xb(), labels, d, n, k);
|
|
85
80
|
break;
|
|
86
81
|
case METRIC_L2:
|
|
87
|
-
fvec_L2sqr_by_idx(distances, x,
|
|
82
|
+
fvec_L2sqr_by_idx(distances, x, get_xb(), labels, d, n, k);
|
|
88
83
|
break;
|
|
89
84
|
default:
|
|
90
85
|
FAISS_THROW_MSG("metric type not supported");
|
|
91
86
|
}
|
|
92
87
|
}
|
|
93
88
|
|
|
94
|
-
size_t IndexFlat::remove_ids(const IDSelector& sel) {
|
|
95
|
-
idx_t j = 0;
|
|
96
|
-
for (idx_t i = 0; i < ntotal; i++) {
|
|
97
|
-
if (sel.is_member(i)) {
|
|
98
|
-
// should be removed
|
|
99
|
-
} else {
|
|
100
|
-
if (i > j) {
|
|
101
|
-
memmove(&xb[d * j], &xb[d * i], sizeof(xb[0]) * d);
|
|
102
|
-
}
|
|
103
|
-
j++;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
size_t nremove = ntotal - j;
|
|
107
|
-
if (nremove > 0) {
|
|
108
|
-
ntotal = j;
|
|
109
|
-
xb.resize(ntotal * d);
|
|
110
|
-
}
|
|
111
|
-
return nremove;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
89
|
namespace {
|
|
115
90
|
|
|
116
|
-
struct FlatL2Dis :
|
|
91
|
+
struct FlatL2Dis : FlatCodesDistanceComputer {
|
|
117
92
|
size_t d;
|
|
118
93
|
Index::idx_t nb;
|
|
119
94
|
const float* q;
|
|
120
95
|
const float* b;
|
|
121
96
|
size_t ndis;
|
|
122
97
|
|
|
123
|
-
float
|
|
98
|
+
float distance_to_code(const uint8_t* code) final {
|
|
124
99
|
ndis++;
|
|
125
|
-
return fvec_L2sqr(q,
|
|
100
|
+
return fvec_L2sqr(q, (float*)code, d);
|
|
126
101
|
}
|
|
127
102
|
|
|
128
103
|
float symmetric_dis(idx_t i, idx_t j) override {
|
|
@@ -130,10 +105,13 @@ struct FlatL2Dis : DistanceComputer {
|
|
|
130
105
|
}
|
|
131
106
|
|
|
132
107
|
explicit FlatL2Dis(const IndexFlat& storage, const float* q = nullptr)
|
|
133
|
-
:
|
|
108
|
+
: FlatCodesDistanceComputer(
|
|
109
|
+
storage.codes.data(),
|
|
110
|
+
storage.code_size),
|
|
111
|
+
d(storage.d),
|
|
134
112
|
nb(storage.ntotal),
|
|
135
113
|
q(q),
|
|
136
|
-
b(storage.
|
|
114
|
+
b(storage.get_xb()),
|
|
137
115
|
ndis(0) {}
|
|
138
116
|
|
|
139
117
|
void set_query(const float* x) override {
|
|
@@ -141,27 +119,30 @@ struct FlatL2Dis : DistanceComputer {
|
|
|
141
119
|
}
|
|
142
120
|
};
|
|
143
121
|
|
|
144
|
-
struct FlatIPDis :
|
|
122
|
+
struct FlatIPDis : FlatCodesDistanceComputer {
|
|
145
123
|
size_t d;
|
|
146
124
|
Index::idx_t nb;
|
|
147
125
|
const float* q;
|
|
148
126
|
const float* b;
|
|
149
127
|
size_t ndis;
|
|
150
128
|
|
|
151
|
-
float operator()(idx_t i) override {
|
|
152
|
-
ndis++;
|
|
153
|
-
return fvec_inner_product(q, b + i * d, d);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
129
|
float symmetric_dis(idx_t i, idx_t j) override {
|
|
157
130
|
return fvec_inner_product(b + j * d, b + i * d, d);
|
|
158
131
|
}
|
|
159
132
|
|
|
133
|
+
float distance_to_code(const uint8_t* code) final {
|
|
134
|
+
ndis++;
|
|
135
|
+
return fvec_inner_product(q, (float*)code, d);
|
|
136
|
+
}
|
|
137
|
+
|
|
160
138
|
explicit FlatIPDis(const IndexFlat& storage, const float* q = nullptr)
|
|
161
|
-
:
|
|
139
|
+
: FlatCodesDistanceComputer(
|
|
140
|
+
storage.codes.data(),
|
|
141
|
+
storage.code_size),
|
|
142
|
+
d(storage.d),
|
|
162
143
|
nb(storage.ntotal),
|
|
163
144
|
q(q),
|
|
164
|
-
b(storage.
|
|
145
|
+
b(storage.get_xb()),
|
|
165
146
|
ndis(0) {}
|
|
166
147
|
|
|
167
148
|
void set_query(const float* x) override {
|
|
@@ -171,32 +152,31 @@ struct FlatIPDis : DistanceComputer {
|
|
|
171
152
|
|
|
172
153
|
} // namespace
|
|
173
154
|
|
|
174
|
-
|
|
155
|
+
FlatCodesDistanceComputer* IndexFlat::get_FlatCodesDistanceComputer() const {
|
|
175
156
|
if (metric_type == METRIC_L2) {
|
|
176
157
|
return new FlatL2Dis(*this);
|
|
177
158
|
} else if (metric_type == METRIC_INNER_PRODUCT) {
|
|
178
159
|
return new FlatIPDis(*this);
|
|
179
160
|
} else {
|
|
180
161
|
return get_extra_distance_computer(
|
|
181
|
-
d, metric_type, metric_arg, ntotal,
|
|
162
|
+
d, metric_type, metric_arg, ntotal, get_xb());
|
|
182
163
|
}
|
|
183
164
|
}
|
|
184
165
|
|
|
185
166
|
void IndexFlat::reconstruct(idx_t key, float* recons) const {
|
|
186
|
-
memcpy(recons, &(
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/* The standalone codec interface */
|
|
190
|
-
size_t IndexFlat::sa_code_size() const {
|
|
191
|
-
return sizeof(float) * d;
|
|
167
|
+
memcpy(recons, &(codes[key * code_size]), code_size);
|
|
192
168
|
}
|
|
193
169
|
|
|
194
170
|
void IndexFlat::sa_encode(idx_t n, const float* x, uint8_t* bytes) const {
|
|
195
|
-
|
|
171
|
+
if (n > 0) {
|
|
172
|
+
memcpy(bytes, x, sizeof(float) * d * n);
|
|
173
|
+
}
|
|
196
174
|
}
|
|
197
175
|
|
|
198
176
|
void IndexFlat::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
|
|
199
|
-
|
|
177
|
+
if (n > 0) {
|
|
178
|
+
memcpy(x, bytes, sizeof(float) * d * n);
|
|
179
|
+
}
|
|
200
180
|
}
|
|
201
181
|
|
|
202
182
|
/***************************************************
|
|
@@ -211,9 +191,9 @@ IndexFlat1D::IndexFlat1D(bool continuous_update)
|
|
|
211
191
|
void IndexFlat1D::update_permutation() {
|
|
212
192
|
perm.resize(ntotal);
|
|
213
193
|
if (ntotal < 1000000) {
|
|
214
|
-
fvec_argsort(ntotal,
|
|
194
|
+
fvec_argsort(ntotal, get_xb(), (size_t*)perm.data());
|
|
215
195
|
} else {
|
|
216
|
-
fvec_argsort_parallel(ntotal,
|
|
196
|
+
fvec_argsort_parallel(ntotal, get_xb(), (size_t*)perm.data());
|
|
217
197
|
}
|
|
218
198
|
}
|
|
219
199
|
|
|
@@ -233,11 +213,14 @@ void IndexFlat1D::search(
|
|
|
233
213
|
const float* x,
|
|
234
214
|
idx_t k,
|
|
235
215
|
float* distances,
|
|
236
|
-
idx_t* labels
|
|
216
|
+
idx_t* labels,
|
|
217
|
+
const SearchParameters* params) const {
|
|
218
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
219
|
+
!params, "search params not supported for this index");
|
|
237
220
|
FAISS_THROW_IF_NOT(k > 0);
|
|
238
|
-
|
|
239
221
|
FAISS_THROW_IF_NOT_MSG(
|
|
240
222
|
perm.size() == ntotal, "Call update_permutation before search");
|
|
223
|
+
const float* xb = get_xb();
|
|
241
224
|
|
|
242
225
|
#pragma omp parallel for
|
|
243
226
|
for (idx_t i = 0; i < n; i++) {
|
|
@@ -12,33 +12,28 @@
|
|
|
12
12
|
|
|
13
13
|
#include <vector>
|
|
14
14
|
|
|
15
|
-
#include <faiss/
|
|
15
|
+
#include <faiss/IndexFlatCodes.h>
|
|
16
16
|
|
|
17
17
|
namespace faiss {
|
|
18
18
|
|
|
19
19
|
/** Index that stores the full vectors and performs exhaustive search */
|
|
20
|
-
struct IndexFlat :
|
|
21
|
-
/// database vectors, size ntotal * d
|
|
22
|
-
std::vector<float> xb;
|
|
23
|
-
|
|
20
|
+
struct IndexFlat : IndexFlatCodes {
|
|
24
21
|
explicit IndexFlat(idx_t d, MetricType metric = METRIC_L2);
|
|
25
22
|
|
|
26
|
-
void add(idx_t n, const float* x) override;
|
|
27
|
-
|
|
28
|
-
void reset() override;
|
|
29
|
-
|
|
30
23
|
void search(
|
|
31
24
|
idx_t n,
|
|
32
25
|
const float* x,
|
|
33
26
|
idx_t k,
|
|
34
27
|
float* distances,
|
|
35
|
-
idx_t* labels
|
|
28
|
+
idx_t* labels,
|
|
29
|
+
const SearchParameters* params = nullptr) const override;
|
|
36
30
|
|
|
37
31
|
void range_search(
|
|
38
32
|
idx_t n,
|
|
39
33
|
const float* x,
|
|
40
34
|
float radius,
|
|
41
|
-
RangeSearchResult* result
|
|
35
|
+
RangeSearchResult* result,
|
|
36
|
+
const SearchParameters* params = nullptr) const override;
|
|
42
37
|
|
|
43
38
|
void reconstruct(idx_t key, float* recons) const override;
|
|
44
39
|
|
|
@@ -57,18 +52,19 @@ struct IndexFlat : Index {
|
|
|
57
52
|
float* distances,
|
|
58
53
|
const idx_t* labels) const;
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
// get pointer to the floating point data
|
|
56
|
+
float* get_xb() {
|
|
57
|
+
return (float*)codes.data();
|
|
58
|
+
}
|
|
59
|
+
const float* get_xb() const {
|
|
60
|
+
return (const float*)codes.data();
|
|
61
|
+
}
|
|
64
62
|
|
|
65
63
|
IndexFlat() {}
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
FlatCodesDistanceComputer* get_FlatCodesDistanceComputer() const override;
|
|
68
66
|
|
|
69
67
|
/* The stanadlone codec interface (just memcopies in this case) */
|
|
70
|
-
size_t sa_code_size() const override;
|
|
71
|
-
|
|
72
68
|
void sa_encode(idx_t n, const float* x, uint8_t* bytes) const override;
|
|
73
69
|
|
|
74
70
|
void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
|
|
@@ -106,7 +102,8 @@ struct IndexFlat1D : IndexFlatL2 {
|
|
|
106
102
|
const float* x,
|
|
107
103
|
idx_t k,
|
|
108
104
|
float* distances,
|
|
109
|
-
idx_t* labels
|
|
105
|
+
idx_t* labels,
|
|
106
|
+
const SearchParameters* params = nullptr) const override;
|
|
110
107
|
};
|
|
111
108
|
|
|
112
109
|
} // namespace faiss
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include <faiss/IndexFlatCodes.h>
|
|
9
|
+
|
|
10
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
11
|
+
#include <faiss/impl/DistanceComputer.h>
|
|
12
|
+
#include <faiss/impl/FaissAssert.h>
|
|
13
|
+
#include <faiss/impl/IDSelector.h>
|
|
14
|
+
|
|
15
|
+
namespace faiss {
|
|
16
|
+
|
|
17
|
+
IndexFlatCodes::IndexFlatCodes(size_t code_size, idx_t d, MetricType metric)
|
|
18
|
+
: Index(d, metric), code_size(code_size) {}
|
|
19
|
+
|
|
20
|
+
IndexFlatCodes::IndexFlatCodes() : code_size(0) {}
|
|
21
|
+
|
|
22
|
+
void IndexFlatCodes::add(idx_t n, const float* x) {
|
|
23
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
24
|
+
if (n == 0) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
codes.resize((ntotal + n) * code_size);
|
|
28
|
+
sa_encode(n, x, codes.data() + (ntotal * code_size));
|
|
29
|
+
ntotal += n;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void IndexFlatCodes::reset() {
|
|
33
|
+
codes.clear();
|
|
34
|
+
ntotal = 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
size_t IndexFlatCodes::sa_code_size() const {
|
|
38
|
+
return code_size;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
size_t IndexFlatCodes::remove_ids(const IDSelector& sel) {
|
|
42
|
+
idx_t j = 0;
|
|
43
|
+
for (idx_t i = 0; i < ntotal; i++) {
|
|
44
|
+
if (sel.is_member(i)) {
|
|
45
|
+
// should be removed
|
|
46
|
+
} else {
|
|
47
|
+
if (i > j) {
|
|
48
|
+
memmove(&codes[code_size * j],
|
|
49
|
+
&codes[code_size * i],
|
|
50
|
+
code_size);
|
|
51
|
+
}
|
|
52
|
+
j++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
size_t nremove = ntotal - j;
|
|
56
|
+
if (nremove > 0) {
|
|
57
|
+
ntotal = j;
|
|
58
|
+
codes.resize(ntotal * code_size);
|
|
59
|
+
}
|
|
60
|
+
return nremove;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void IndexFlatCodes::reconstruct_n(idx_t i0, idx_t ni, float* recons) const {
|
|
64
|
+
FAISS_THROW_IF_NOT(ni == 0 || (i0 >= 0 && i0 + ni <= ntotal));
|
|
65
|
+
sa_decode(ni, codes.data() + i0 * code_size, recons);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void IndexFlatCodes::reconstruct(idx_t key, float* recons) const {
|
|
69
|
+
reconstruct_n(key, 1, recons);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
FlatCodesDistanceComputer* IndexFlatCodes::get_FlatCodesDistanceComputer()
|
|
73
|
+
const {
|
|
74
|
+
FAISS_THROW_MSG("not implemented");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void IndexFlatCodes::check_compatible_for_merge(const Index& otherIndex) const {
|
|
78
|
+
// minimal sanity checks
|
|
79
|
+
const IndexFlatCodes* other =
|
|
80
|
+
dynamic_cast<const IndexFlatCodes*>(&otherIndex);
|
|
81
|
+
FAISS_THROW_IF_NOT(other);
|
|
82
|
+
FAISS_THROW_IF_NOT(other->d == d);
|
|
83
|
+
FAISS_THROW_IF_NOT(other->code_size == code_size);
|
|
84
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
85
|
+
typeid(*this) == typeid(*other),
|
|
86
|
+
"can only merge indexes of the same type");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void IndexFlatCodes::merge_from(Index& otherIndex, idx_t add_id) {
|
|
90
|
+
FAISS_THROW_IF_NOT_MSG(add_id == 0, "cannot set ids in FlatCodes index");
|
|
91
|
+
check_compatible_for_merge(otherIndex);
|
|
92
|
+
IndexFlatCodes* other = static_cast<IndexFlatCodes*>(&otherIndex);
|
|
93
|
+
codes.resize((ntotal + other->ntotal) * code_size);
|
|
94
|
+
memcpy(codes.data() + (ntotal * code_size),
|
|
95
|
+
other->codes.data(),
|
|
96
|
+
other->ntotal * code_size);
|
|
97
|
+
ntotal += other->ntotal;
|
|
98
|
+
other->reset();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
} // namespace faiss
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// -*- c++ -*-
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include <faiss/Index.h>
|
|
13
|
+
#include <faiss/impl/DistanceComputer.h>
|
|
14
|
+
#include <vector>
|
|
15
|
+
|
|
16
|
+
namespace faiss {
|
|
17
|
+
|
|
18
|
+
/** Index that encodes all vectors as fixed-size codes (size code_size). Storage
|
|
19
|
+
* is in the codes vector */
|
|
20
|
+
struct IndexFlatCodes : Index {
|
|
21
|
+
size_t code_size;
|
|
22
|
+
|
|
23
|
+
/// encoded dataset, size ntotal * code_size
|
|
24
|
+
std::vector<uint8_t> codes;
|
|
25
|
+
|
|
26
|
+
IndexFlatCodes();
|
|
27
|
+
|
|
28
|
+
IndexFlatCodes(size_t code_size, idx_t d, MetricType metric = METRIC_L2);
|
|
29
|
+
|
|
30
|
+
/// default add uses sa_encode
|
|
31
|
+
void add(idx_t n, const float* x) override;
|
|
32
|
+
|
|
33
|
+
void reset() override;
|
|
34
|
+
|
|
35
|
+
/// reconstruction using the codec interface
|
|
36
|
+
void reconstruct_n(idx_t i0, idx_t ni, float* recons) const override;
|
|
37
|
+
|
|
38
|
+
void reconstruct(idx_t key, float* recons) const override;
|
|
39
|
+
|
|
40
|
+
size_t sa_code_size() const override;
|
|
41
|
+
|
|
42
|
+
/** remove some ids. NB that Because of the structure of the
|
|
43
|
+
* indexing structure, the semantics of this operation are
|
|
44
|
+
* different from the usual ones: the new ids are shifted */
|
|
45
|
+
size_t remove_ids(const IDSelector& sel) override;
|
|
46
|
+
|
|
47
|
+
/** a FlatCodesDistanceComputer offers a distance_to_code method */
|
|
48
|
+
virtual FlatCodesDistanceComputer* get_FlatCodesDistanceComputer() const;
|
|
49
|
+
|
|
50
|
+
DistanceComputer* get_distance_computer() const override {
|
|
51
|
+
return get_FlatCodesDistanceComputer();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void check_compatible_for_merge(const Index& otherIndex) const override;
|
|
55
|
+
|
|
56
|
+
virtual void merge_from(Index& otherIndex, idx_t add_id = 0) override;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
} // namespace faiss
|