faiss 0.4.3 → 0.5.1
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 +10 -0
- data/README.md +2 -0
- data/ext/faiss/index.cpp +33 -6
- data/ext/faiss/index_binary.cpp +17 -4
- data/ext/faiss/kmeans.cpp +6 -6
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +2 -3
- data/vendor/faiss/faiss/AutoTune.h +1 -1
- data/vendor/faiss/faiss/Clustering.cpp +2 -2
- data/vendor/faiss/faiss/Clustering.h +2 -2
- data/vendor/faiss/faiss/IVFlib.cpp +26 -51
- data/vendor/faiss/faiss/IVFlib.h +1 -1
- data/vendor/faiss/faiss/Index.cpp +11 -0
- data/vendor/faiss/faiss/Index.h +34 -11
- data/vendor/faiss/faiss/Index2Layer.cpp +1 -1
- data/vendor/faiss/faiss/Index2Layer.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +1 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +9 -4
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexBinary.h +7 -7
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +8 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +3 -3
- data/vendor/faiss/faiss/IndexBinaryHash.h +5 -5
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +7 -6
- data/vendor/faiss/faiss/IndexFastScan.cpp +125 -49
- data/vendor/faiss/faiss/IndexFastScan.h +102 -7
- data/vendor/faiss/faiss/IndexFlat.cpp +374 -4
- data/vendor/faiss/faiss/IndexFlat.h +81 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +93 -2
- data/vendor/faiss/faiss/IndexHNSW.h +58 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +14 -13
- data/vendor/faiss/faiss/IndexIDMap.h +6 -6
- data/vendor/faiss/faiss/IndexIVF.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVF.h +5 -5
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +9 -3
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +3 -1
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +176 -90
- data/vendor/faiss/faiss/IndexIVFFastScan.h +173 -18
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +1 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +251 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +64 -0
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +3 -1
- data/vendor/faiss/faiss/IndexIVFPQ.h +1 -1
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +134 -2
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +99 -8
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +828 -0
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +252 -0
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +1 -1
- data/vendor/faiss/faiss/IndexNeuralNetCodec.h +1 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +4 -1
- data/vendor/faiss/faiss/IndexPQ.h +1 -1
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +6 -2
- data/vendor/faiss/faiss/IndexPQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexPreTransform.cpp +14 -0
- data/vendor/faiss/faiss/IndexPreTransform.h +9 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +96 -13
- data/vendor/faiss/faiss/IndexRaBitQ.h +11 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +731 -0
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +175 -0
- data/vendor/faiss/faiss/IndexRefine.cpp +49 -0
- data/vendor/faiss/faiss/IndexRefine.h +17 -0
- data/vendor/faiss/faiss/IndexShards.cpp +1 -1
- data/vendor/faiss/faiss/MatrixStats.cpp +3 -3
- data/vendor/faiss/faiss/MetricType.h +1 -1
- data/vendor/faiss/faiss/VectorTransform.h +2 -2
- data/vendor/faiss/faiss/clone_index.cpp +5 -1
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +3 -1
- data/vendor/faiss/faiss/gpu/GpuIndex.h +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryCagra.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +11 -7
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIcmEncoder.cpp +7 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +2 -2
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -1
- data/vendor/faiss/faiss/impl/CodePacker.h +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +77 -6
- data/vendor/faiss/faiss/impl/FastScanDistancePostProcessing.h +53 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +295 -16
- data/vendor/faiss/faiss/impl/HNSW.h +35 -6
- data/vendor/faiss/faiss/impl/IDSelector.cpp +2 -2
- data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +1 -1
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
- data/vendor/faiss/faiss/impl/NNDescent.h +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -1
- data/vendor/faiss/faiss/impl/Panorama.cpp +193 -0
- data/vendor/faiss/faiss/impl/Panorama.h +204 -0
- data/vendor/faiss/faiss/impl/PanoramaStats.cpp +33 -0
- data/vendor/faiss/faiss/impl/PanoramaStats.h +38 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +5 -5
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +2 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +29 -0
- data/vendor/faiss/faiss/impl/RaBitQStats.h +56 -0
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +294 -0
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +330 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +304 -223
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +72 -4
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +362 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +112 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +4 -4
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +7 -10
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +2 -4
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +7 -4
- data/vendor/faiss/faiss/impl/index_read.cpp +238 -10
- data/vendor/faiss/faiss/impl/index_write.cpp +212 -19
- data/vendor/faiss/faiss/impl/io.cpp +2 -2
- data/vendor/faiss/faiss/impl/io.h +4 -4
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +1 -1
- data/vendor/faiss/faiss/impl/kmeans1d.h +1 -1
- data/vendor/faiss/faiss/impl/lattice_Zn.h +2 -2
- data/vendor/faiss/faiss/impl/mapped_io.cpp +2 -2
- data/vendor/faiss/faiss/impl/mapped_io.h +4 -3
- data/vendor/faiss/faiss/impl/maybe_owned_vector.h +8 -1
- data/vendor/faiss/faiss/impl/platform_macros.h +12 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +30 -4
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +14 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +5 -6
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +55 -11
- data/vendor/faiss/faiss/impl/svs_io.cpp +86 -0
- data/vendor/faiss/faiss/impl/svs_io.h +67 -0
- data/vendor/faiss/faiss/impl/zerocopy_io.h +1 -1
- data/vendor/faiss/faiss/index_factory.cpp +217 -8
- data/vendor/faiss/faiss/index_factory.h +1 -1
- data/vendor/faiss/faiss/index_io.h +1 -1
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +1 -1
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +115 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.h +46 -0
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +261 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +117 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +66 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +245 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +137 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +39 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +42 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +149 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +58 -0
- data/vendor/faiss/faiss/utils/AlignedTable.h +1 -1
- data/vendor/faiss/faiss/utils/Heap.cpp +2 -2
- data/vendor/faiss/faiss/utils/Heap.h +3 -3
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +1 -1
- data/vendor/faiss/faiss/utils/NeuralNet.h +3 -3
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +1 -1
- data/vendor/faiss/faiss/utils/distances.cpp +0 -3
- data/vendor/faiss/faiss/utils/distances.h +2 -2
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +3 -1
- data/vendor/faiss/faiss/utils/hamming-inl.h +2 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +7 -6
- data/vendor/faiss/faiss/utils/hamming.h +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -2
- data/vendor/faiss/faiss/utils/partitioning.cpp +5 -5
- data/vendor/faiss/faiss/utils/partitioning.h +2 -2
- data/vendor/faiss/faiss/utils/rabitq_simd.h +222 -336
- data/vendor/faiss/faiss/utils/random.cpp +1 -1
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +1 -1
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +1 -1
- data/vendor/faiss/faiss/utils/simdlib_neon.h +2 -2
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +1 -1
- data/vendor/faiss/faiss/utils/utils.cpp +9 -2
- data/vendor/faiss/faiss/utils/utils.h +2 -2
- metadata +29 -1
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
-
#include <memory>
|
|
11
|
-
|
|
12
10
|
#include <faiss/IndexIVF.h>
|
|
11
|
+
#include <faiss/impl/FastScanDistancePostProcessing.h>
|
|
13
12
|
#include <faiss/utils/AlignedTable.h>
|
|
14
13
|
|
|
15
14
|
namespace faiss {
|
|
@@ -63,6 +62,15 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
63
62
|
// quantizer used to pack the codes
|
|
64
63
|
Quantizer* fine_quantizer = nullptr;
|
|
65
64
|
|
|
65
|
+
/** Constructor for IndexIVFFastScan
|
|
66
|
+
*
|
|
67
|
+
* @param quantizer coarse quantizer for IVF clustering
|
|
68
|
+
* @param d dimensionality of vectors
|
|
69
|
+
* @param nlist number of inverted lists
|
|
70
|
+
* @param code_size size of each code in bytes
|
|
71
|
+
* @param metric distance metric to use
|
|
72
|
+
* @param own_invlists whether to own the inverted lists
|
|
73
|
+
*/
|
|
66
74
|
IndexIVFFastScan(
|
|
67
75
|
Index* quantizer,
|
|
68
76
|
size_t d,
|
|
@@ -73,7 +81,16 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
73
81
|
|
|
74
82
|
IndexIVFFastScan();
|
|
75
83
|
|
|
76
|
-
|
|
84
|
+
/** Initialize the fast scan functionality (called by implementations)
|
|
85
|
+
*
|
|
86
|
+
* @param fine_quantizer fine quantizer for encoding
|
|
87
|
+
* @param M number of subquantizers
|
|
88
|
+
* @param nbits number of bits per subquantizer
|
|
89
|
+
* @param nlist number of inverted lists
|
|
90
|
+
* @param metric distance metric to use
|
|
91
|
+
* @param bbs block size for SIMD processing
|
|
92
|
+
* @param own_invlists whether to own the inverted lists
|
|
93
|
+
*/
|
|
77
94
|
void init_fastscan(
|
|
78
95
|
Quantizer* fine_quantizer,
|
|
79
96
|
size_t M,
|
|
@@ -91,34 +108,72 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
91
108
|
/// orig's inverted lists (for debugging)
|
|
92
109
|
InvertedLists* orig_invlists = nullptr;
|
|
93
110
|
|
|
111
|
+
/** Add vectors with specific IDs to the index
|
|
112
|
+
*
|
|
113
|
+
* @param n number of vectors to add
|
|
114
|
+
* @param x vectors to add (n * d)
|
|
115
|
+
* @param xids IDs for the vectors (n)
|
|
116
|
+
*/
|
|
94
117
|
void add_with_ids(idx_t n, const float* x, const idx_t* xids) override;
|
|
95
|
-
|
|
96
118
|
// prepare look-up tables
|
|
97
119
|
|
|
98
120
|
virtual bool lookup_table_is_3d() const = 0;
|
|
99
121
|
|
|
100
122
|
// compact way of conveying coarse quantization results
|
|
101
123
|
struct CoarseQuantized {
|
|
102
|
-
size_t nprobe;
|
|
124
|
+
size_t nprobe = 0;
|
|
103
125
|
const float* dis = nullptr;
|
|
104
126
|
const idx_t* ids = nullptr;
|
|
105
127
|
};
|
|
106
128
|
|
|
129
|
+
/* Compute distance table for query set, given a list of coarse
|
|
130
|
+
* quantizers.
|
|
131
|
+
*
|
|
132
|
+
* @param n number of queries
|
|
133
|
+
* @param x query vectors (n, d)
|
|
134
|
+
* @param cq coarse quantization results
|
|
135
|
+
* @param dis_tables output distance tables
|
|
136
|
+
* @param biases output bias values
|
|
137
|
+
* @param context processing context containing query factors
|
|
138
|
+
processor
|
|
139
|
+
*/
|
|
107
140
|
virtual void compute_LUT(
|
|
108
141
|
size_t n,
|
|
109
142
|
const float* x,
|
|
110
143
|
const CoarseQuantized& cq,
|
|
111
144
|
AlignedTable<float>& dis_tables,
|
|
112
|
-
AlignedTable<float>& biases
|
|
145
|
+
AlignedTable<float>& biases,
|
|
146
|
+
const FastScanDistancePostProcessing& context) const = 0;
|
|
113
147
|
|
|
148
|
+
/** Compute quantized lookup tables for distance computation
|
|
149
|
+
*
|
|
150
|
+
* @param n number of query vectors
|
|
151
|
+
* @param x query vectors (n * d)
|
|
152
|
+
* @param cq coarse quantization results
|
|
153
|
+
* @param dis_tables output quantized distance tables
|
|
154
|
+
* @param biases output quantized bias values
|
|
155
|
+
* @param normalizers output normalization factors
|
|
156
|
+
* @param context processing context containing query factors
|
|
157
|
+
* processor
|
|
158
|
+
*/
|
|
114
159
|
void compute_LUT_uint8(
|
|
115
160
|
size_t n,
|
|
116
161
|
const float* x,
|
|
117
162
|
const CoarseQuantized& cq,
|
|
118
163
|
AlignedTable<uint8_t>& dis_tables,
|
|
119
164
|
AlignedTable<uint16_t>& biases,
|
|
120
|
-
float* normalizers
|
|
165
|
+
float* normalizers,
|
|
166
|
+
const FastScanDistancePostProcessing& context) const;
|
|
121
167
|
|
|
168
|
+
/** Search for k nearest neighbors
|
|
169
|
+
*
|
|
170
|
+
* @param n number of query vectors
|
|
171
|
+
* @param x query vectors (n * d)
|
|
172
|
+
* @param k number of nearest neighbors to find
|
|
173
|
+
* @param distances output distances (n * k)
|
|
174
|
+
* @param labels output labels/indices (n * k)
|
|
175
|
+
* @param params optional search parameters
|
|
176
|
+
*/
|
|
122
177
|
void search(
|
|
123
178
|
idx_t n,
|
|
124
179
|
const float* x,
|
|
@@ -127,6 +182,19 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
127
182
|
idx_t* labels,
|
|
128
183
|
const SearchParameters* params = nullptr) const override;
|
|
129
184
|
|
|
185
|
+
/** Search with pre-assigned coarse quantization
|
|
186
|
+
*
|
|
187
|
+
* @param n number of query vectors
|
|
188
|
+
* @param x query vectors (n * d)
|
|
189
|
+
* @param k number of nearest neighbors to find
|
|
190
|
+
* @param assign coarse cluster assignments (n * nprobe)
|
|
191
|
+
* @param centroid_dis distances to centroids (n * nprobe)
|
|
192
|
+
* @param distances output distances (n * k)
|
|
193
|
+
* @param labels output labels/indices (n * k)
|
|
194
|
+
* @param store_pairs whether to store cluster-relative pairs
|
|
195
|
+
* @param params optional IVF search parameters
|
|
196
|
+
* @param stats optional search statistics
|
|
197
|
+
*/
|
|
130
198
|
void search_preassigned(
|
|
131
199
|
idx_t n,
|
|
132
200
|
const float* x,
|
|
@@ -139,6 +207,14 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
139
207
|
const IVFSearchParameters* params = nullptr,
|
|
140
208
|
IndexIVFStats* stats = nullptr) const override;
|
|
141
209
|
|
|
210
|
+
/** Range search for all neighbors within radius
|
|
211
|
+
*
|
|
212
|
+
* @param n number of query vectors
|
|
213
|
+
* @param x query vectors (n * d)
|
|
214
|
+
* @param radius search radius
|
|
215
|
+
* @param result output range search results
|
|
216
|
+
* @param params optional search parameters
|
|
217
|
+
*/
|
|
142
218
|
void range_search(
|
|
143
219
|
idx_t n,
|
|
144
220
|
const float* x,
|
|
@@ -146,7 +222,45 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
146
222
|
RangeSearchResult* result,
|
|
147
223
|
const SearchParameters* params = nullptr) const override;
|
|
148
224
|
|
|
149
|
-
|
|
225
|
+
/** Create a KNN handler for this index type
|
|
226
|
+
*
|
|
227
|
+
* This method can be overridden by derived classes to provide
|
|
228
|
+
* specialized handlers (e.g., IVFRaBitQHeapHandler for RaBitQ indexes).
|
|
229
|
+
* Base implementation creates standard handlers based on k and impl.
|
|
230
|
+
*
|
|
231
|
+
* @param is_max true for max-heap (inner product), false for
|
|
232
|
+
* min-heap (L2 distance)
|
|
233
|
+
* @param impl implementation number:
|
|
234
|
+
* - even (10, 12, 14): use heap for top-k
|
|
235
|
+
* - odd (11, 13, 15): use reservoir sampling
|
|
236
|
+
* @param n number of queries
|
|
237
|
+
* @param k number of neighbors to find per query
|
|
238
|
+
* @param distances output array for distances (n * k), will be
|
|
239
|
+
* populated by handler
|
|
240
|
+
* @param labels output array for result IDs (n * k), will be
|
|
241
|
+
* populated by handler
|
|
242
|
+
* @param sel optional ID selector to filter results (nullptr =
|
|
243
|
+
* no filtering)
|
|
244
|
+
* @param context processing context containing additional data
|
|
245
|
+
* @param normalizers optional array of size 2*n for converting quantized
|
|
246
|
+
* uint16 distances to float.
|
|
247
|
+
*
|
|
248
|
+
* @return Allocated result handler (caller owns and must delete).
|
|
249
|
+
* Handler processes SIMD batches and populates distances/labels.
|
|
250
|
+
*
|
|
251
|
+
* @note The returned handler must be deleted by caller after use.
|
|
252
|
+
* Typical usage: handler->begin() → process batches → handler->end()
|
|
253
|
+
*/
|
|
254
|
+
virtual SIMDResultHandlerToFloat* make_knn_handler(
|
|
255
|
+
bool is_max,
|
|
256
|
+
int impl,
|
|
257
|
+
idx_t n,
|
|
258
|
+
idx_t k,
|
|
259
|
+
float* distances,
|
|
260
|
+
idx_t* labels,
|
|
261
|
+
const IDSelector* sel,
|
|
262
|
+
const FastScanDistancePostProcessing& context,
|
|
263
|
+
const float* normalizers = nullptr) const;
|
|
150
264
|
|
|
151
265
|
// dispatch to implementations and parallelize
|
|
152
266
|
void search_dispatch_implem(
|
|
@@ -156,7 +270,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
156
270
|
float* distances,
|
|
157
271
|
idx_t* labels,
|
|
158
272
|
const CoarseQuantized& cq,
|
|
159
|
-
const
|
|
273
|
+
const FastScanDistancePostProcessing& context,
|
|
160
274
|
const IVFSearchParameters* params = nullptr) const;
|
|
161
275
|
|
|
162
276
|
void range_search_dispatch_implem(
|
|
@@ -165,7 +279,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
165
279
|
float radius,
|
|
166
280
|
RangeSearchResult& rres,
|
|
167
281
|
const CoarseQuantized& cq_in,
|
|
168
|
-
const
|
|
282
|
+
const FastScanDistancePostProcessing& context,
|
|
169
283
|
const IVFSearchParameters* params = nullptr) const;
|
|
170
284
|
|
|
171
285
|
// impl 1 and 2 are just for verification
|
|
@@ -177,7 +291,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
177
291
|
float* distances,
|
|
178
292
|
idx_t* labels,
|
|
179
293
|
const CoarseQuantized& cq,
|
|
180
|
-
const
|
|
294
|
+
const FastScanDistancePostProcessing& context,
|
|
181
295
|
const IVFSearchParameters* params = nullptr) const;
|
|
182
296
|
|
|
183
297
|
template <class C>
|
|
@@ -188,7 +302,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
188
302
|
float* distances,
|
|
189
303
|
idx_t* labels,
|
|
190
304
|
const CoarseQuantized& cq,
|
|
191
|
-
const
|
|
305
|
+
const FastScanDistancePostProcessing& context,
|
|
192
306
|
const IVFSearchParameters* params = nullptr) const;
|
|
193
307
|
|
|
194
308
|
// implem 10 and 12 are not multithreaded internally, so
|
|
@@ -200,7 +314,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
200
314
|
const CoarseQuantized& cq,
|
|
201
315
|
size_t* ndis_out,
|
|
202
316
|
size_t* nlist_out,
|
|
203
|
-
const
|
|
317
|
+
const FastScanDistancePostProcessing& context,
|
|
204
318
|
const IVFSearchParameters* params = nullptr) const;
|
|
205
319
|
|
|
206
320
|
void search_implem_12(
|
|
@@ -210,7 +324,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
210
324
|
const CoarseQuantized& cq,
|
|
211
325
|
size_t* ndis_out,
|
|
212
326
|
size_t* nlist_out,
|
|
213
|
-
const
|
|
327
|
+
const FastScanDistancePostProcessing& context,
|
|
214
328
|
const IVFSearchParameters* params = nullptr) const;
|
|
215
329
|
|
|
216
330
|
// implem 14 is multithreaded internally across nprobes and queries
|
|
@@ -222,7 +336,7 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
222
336
|
idx_t* labels,
|
|
223
337
|
const CoarseQuantized& cq,
|
|
224
338
|
int impl,
|
|
225
|
-
const
|
|
339
|
+
const FastScanDistancePostProcessing& context,
|
|
226
340
|
const IVFSearchParameters* params = nullptr) const;
|
|
227
341
|
|
|
228
342
|
// reconstruct vectors from packed invlists
|
|
@@ -234,16 +348,57 @@ struct IndexIVFFastScan : IndexIVF {
|
|
|
234
348
|
// reconstruct orig invlists (for debugging)
|
|
235
349
|
void reconstruct_orig_invlists();
|
|
236
350
|
|
|
237
|
-
/** Decode a set of vectors
|
|
351
|
+
/** Decode a set of vectors
|
|
238
352
|
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
353
|
+
* NOTE: The codes in the IndexFastScan object are non-contiguous.
|
|
354
|
+
* But this method requires a contiguous representation.
|
|
241
355
|
*
|
|
242
356
|
* @param n number of vectors
|
|
243
357
|
* @param bytes input encoded vectors, size n * code_size
|
|
244
358
|
* @param x output vectors, size n * d
|
|
245
359
|
*/
|
|
246
360
|
void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
|
|
361
|
+
|
|
362
|
+
protected:
|
|
363
|
+
/** Preprocess metadata from encoded vectors before packing.
|
|
364
|
+
*
|
|
365
|
+
* Called during add_with_ids after encode_vectors but before codes
|
|
366
|
+
* are packed into SIMD-friendly blocks. Subclasses can override to
|
|
367
|
+
* extract and store metadata embedded in codes or perform other
|
|
368
|
+
* pre-packing operations.
|
|
369
|
+
*
|
|
370
|
+
* Default implementation: no-op
|
|
371
|
+
*
|
|
372
|
+
* Example use case:
|
|
373
|
+
* - IndexIVFRaBitQFastScan extracts factor data from codes for use
|
|
374
|
+
* during search-time distance corrections
|
|
375
|
+
*
|
|
376
|
+
* @param n number of vectors encoded
|
|
377
|
+
* @param flat_codes encoded vectors (n * code_size bytes)
|
|
378
|
+
* @param start_global_idx starting global index (ntotal before add)
|
|
379
|
+
*/
|
|
380
|
+
virtual void preprocess_code_metadata(
|
|
381
|
+
idx_t n,
|
|
382
|
+
const uint8_t* flat_codes,
|
|
383
|
+
idx_t start_global_idx);
|
|
384
|
+
|
|
385
|
+
/** Get stride for interpreting codes during SIMD packing.
|
|
386
|
+
*
|
|
387
|
+
* The stride determines how to read codes when packing them into
|
|
388
|
+
* SIMD-friendly block format. This is needed when codes contain
|
|
389
|
+
* embedded metadata that should be skipped during packing.
|
|
390
|
+
*
|
|
391
|
+
* Default implementation: returns 0 (use standard M-byte stride)
|
|
392
|
+
*
|
|
393
|
+
* Example use case:
|
|
394
|
+
* - IndexIVFRaBitQFastScan returns code_size because codes contain
|
|
395
|
+
* embedded factor data after the quantized bits
|
|
396
|
+
*
|
|
397
|
+
* @return stride in bytes:
|
|
398
|
+
* - 0: use default stride (M bytes, standard PQ/AQ codes)
|
|
399
|
+
* - >0: use custom stride (e.g., code_size for embedded metadata)
|
|
400
|
+
*/
|
|
401
|
+
virtual size_t code_packing_stride() const;
|
|
247
402
|
};
|
|
248
403
|
|
|
249
404
|
struct IVFFastScanStats {
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and 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
|
+
#include <faiss/IndexIVFFlatPanorama.h>
|
|
11
|
+
|
|
12
|
+
#include <cstdio>
|
|
13
|
+
|
|
14
|
+
#include <faiss/IndexFlat.h>
|
|
15
|
+
|
|
16
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
17
|
+
#include <faiss/impl/IDSelector.h>
|
|
18
|
+
#include <faiss/impl/PanoramaStats.h>
|
|
19
|
+
|
|
20
|
+
#include <faiss/impl/FaissAssert.h>
|
|
21
|
+
#include <faiss/utils/distances.h>
|
|
22
|
+
#include <faiss/utils/extra_distances.h>
|
|
23
|
+
#include <faiss/utils/utils.h>
|
|
24
|
+
|
|
25
|
+
namespace faiss {
|
|
26
|
+
|
|
27
|
+
IndexIVFFlatPanorama::IndexIVFFlatPanorama(
|
|
28
|
+
Index* quantizer,
|
|
29
|
+
size_t d,
|
|
30
|
+
size_t nlist,
|
|
31
|
+
int n_levels,
|
|
32
|
+
MetricType metric,
|
|
33
|
+
bool own_invlists)
|
|
34
|
+
: IndexIVFFlat(quantizer, d, nlist, metric, false), n_levels(n_levels) {
|
|
35
|
+
// For now, we only support L2 distance.
|
|
36
|
+
// Supporting dot product and cosine distance is a trivial addition
|
|
37
|
+
// left for future work.
|
|
38
|
+
FAISS_THROW_IF_NOT(metric == METRIC_L2);
|
|
39
|
+
|
|
40
|
+
// We construct the inverted lists here so that we can use the
|
|
41
|
+
// level-oriented storage. This does not cause a leak as we constructed
|
|
42
|
+
// IndexIVF first, with own_invlists set to false.
|
|
43
|
+
this->invlists = new ArrayInvertedListsPanorama(nlist, code_size, n_levels);
|
|
44
|
+
this->own_invlists = own_invlists;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
IndexIVFFlatPanorama::IndexIVFFlatPanorama() : n_levels(0) {}
|
|
48
|
+
|
|
49
|
+
namespace {
|
|
50
|
+
|
|
51
|
+
template <typename VectorDistance, bool use_sel>
|
|
52
|
+
struct IVFFlatScannerPanorama : InvertedListScanner {
|
|
53
|
+
VectorDistance vd;
|
|
54
|
+
const ArrayInvertedListsPanorama* storage;
|
|
55
|
+
using C = typename VectorDistance::C;
|
|
56
|
+
|
|
57
|
+
IVFFlatScannerPanorama(
|
|
58
|
+
const VectorDistance& vd,
|
|
59
|
+
const ArrayInvertedListsPanorama* storage,
|
|
60
|
+
bool store_pairs,
|
|
61
|
+
const IDSelector* sel)
|
|
62
|
+
: InvertedListScanner(store_pairs, sel), vd(vd), storage(storage) {
|
|
63
|
+
keep_max = vd.is_similarity;
|
|
64
|
+
code_size = vd.d * sizeof(float);
|
|
65
|
+
cum_sums.resize(storage->n_levels + 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const float* xi = nullptr;
|
|
69
|
+
std::vector<float> cum_sums;
|
|
70
|
+
float q_norm = 0.0f;
|
|
71
|
+
void set_query(const float* query) override {
|
|
72
|
+
this->xi = query;
|
|
73
|
+
this->storage->pano.compute_query_cum_sums(query, cum_sums.data());
|
|
74
|
+
q_norm = cum_sums[0] * cum_sums[0];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void set_list(idx_t list_no, float /* coarse_dis */) override {
|
|
78
|
+
this->list_no = list_no;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// This function is unreachable as `IndexIVF` only calls this within
|
|
82
|
+
/// iterators, which are not supported by `IndexIVFFlatPanorama`.
|
|
83
|
+
/// To avoid undefined behavior, we throw an error here.
|
|
84
|
+
float distance_to_code(const uint8_t* /* code */) const override {
|
|
85
|
+
FAISS_THROW_MSG(
|
|
86
|
+
"IndexIVFFlatPanorama does not support distance_to_code");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
size_t scan_codes(
|
|
90
|
+
size_t list_size,
|
|
91
|
+
const uint8_t* codes,
|
|
92
|
+
const idx_t* ids,
|
|
93
|
+
float* simi,
|
|
94
|
+
idx_t* idxi,
|
|
95
|
+
size_t k) const override {
|
|
96
|
+
size_t nup = 0;
|
|
97
|
+
|
|
98
|
+
const size_t n_batches =
|
|
99
|
+
(list_size + storage->kBatchSize - 1) / storage->kBatchSize;
|
|
100
|
+
|
|
101
|
+
const float* cum_sums_data = storage->get_cum_sums(list_no);
|
|
102
|
+
|
|
103
|
+
std::vector<float> exact_distances(storage->kBatchSize);
|
|
104
|
+
std::vector<uint32_t> active_indices(storage->kBatchSize);
|
|
105
|
+
|
|
106
|
+
PanoramaStats local_stats;
|
|
107
|
+
local_stats.reset();
|
|
108
|
+
|
|
109
|
+
for (size_t batch_no = 0; batch_no < n_batches; batch_no++) {
|
|
110
|
+
size_t batch_start = batch_no * storage->kBatchSize;
|
|
111
|
+
|
|
112
|
+
size_t num_active =
|
|
113
|
+
storage->pano
|
|
114
|
+
.progressive_filter_batch<CMax<float, int64_t>>(
|
|
115
|
+
codes,
|
|
116
|
+
cum_sums_data,
|
|
117
|
+
xi,
|
|
118
|
+
cum_sums.data(),
|
|
119
|
+
batch_no,
|
|
120
|
+
list_size,
|
|
121
|
+
sel,
|
|
122
|
+
ids,
|
|
123
|
+
use_sel,
|
|
124
|
+
active_indices,
|
|
125
|
+
exact_distances,
|
|
126
|
+
simi[0],
|
|
127
|
+
local_stats);
|
|
128
|
+
|
|
129
|
+
// Add batch survivors to heap.
|
|
130
|
+
for (size_t i = 0; i < num_active; i++) {
|
|
131
|
+
uint32_t idx = active_indices[i];
|
|
132
|
+
size_t global_idx = batch_start + idx;
|
|
133
|
+
float dis = exact_distances[idx];
|
|
134
|
+
|
|
135
|
+
if (C::cmp(simi[0], dis)) {
|
|
136
|
+
int64_t id = store_pairs ? lo_build(list_no, global_idx)
|
|
137
|
+
: ids[global_idx];
|
|
138
|
+
heap_replace_top<C>(k, simi, idxi, dis, id);
|
|
139
|
+
nup++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
indexPanorama_stats.add(local_stats);
|
|
145
|
+
return nup;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
void scan_codes_range(
|
|
149
|
+
size_t list_size,
|
|
150
|
+
const uint8_t* codes,
|
|
151
|
+
const idx_t* ids,
|
|
152
|
+
float radius,
|
|
153
|
+
RangeQueryResult& res) const override {
|
|
154
|
+
const size_t n_batches =
|
|
155
|
+
(list_size + storage->kBatchSize - 1) / storage->kBatchSize;
|
|
156
|
+
|
|
157
|
+
const float* cum_sums_data = storage->get_cum_sums(list_no);
|
|
158
|
+
|
|
159
|
+
std::vector<float> exact_distances(storage->kBatchSize);
|
|
160
|
+
std::vector<uint32_t> active_indices(storage->kBatchSize);
|
|
161
|
+
|
|
162
|
+
PanoramaStats local_stats;
|
|
163
|
+
local_stats.reset();
|
|
164
|
+
|
|
165
|
+
// Same progressive filtering as scan_codes, but with fixed radius
|
|
166
|
+
// threshold instead of dynamic heap threshold.
|
|
167
|
+
for (size_t batch_no = 0; batch_no < n_batches; batch_no++) {
|
|
168
|
+
size_t batch_start = batch_no * storage->kBatchSize;
|
|
169
|
+
|
|
170
|
+
size_t num_active =
|
|
171
|
+
storage->pano
|
|
172
|
+
.progressive_filter_batch<CMax<float, int64_t>>(
|
|
173
|
+
codes,
|
|
174
|
+
cum_sums_data,
|
|
175
|
+
xi,
|
|
176
|
+
cum_sums.data(),
|
|
177
|
+
batch_no,
|
|
178
|
+
list_size,
|
|
179
|
+
sel,
|
|
180
|
+
ids,
|
|
181
|
+
use_sel,
|
|
182
|
+
active_indices,
|
|
183
|
+
exact_distances,
|
|
184
|
+
radius,
|
|
185
|
+
local_stats);
|
|
186
|
+
|
|
187
|
+
// Add batch survivors to range result.
|
|
188
|
+
for (size_t i = 0; i < num_active; i++) {
|
|
189
|
+
uint32_t idx = active_indices[i];
|
|
190
|
+
size_t global_idx = batch_start + idx;
|
|
191
|
+
float dis = exact_distances[idx];
|
|
192
|
+
|
|
193
|
+
if (C::cmp(radius, dis)) {
|
|
194
|
+
int64_t id = store_pairs ? lo_build(list_no, global_idx)
|
|
195
|
+
: ids[global_idx];
|
|
196
|
+
res.add(dis, id);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
indexPanorama_stats.add(local_stats);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
struct Run_get_InvertedListScanner {
|
|
206
|
+
using T = InvertedListScanner*;
|
|
207
|
+
|
|
208
|
+
template <class VD>
|
|
209
|
+
InvertedListScanner* f(
|
|
210
|
+
VD& vd,
|
|
211
|
+
const IndexIVFFlatPanorama* ivf,
|
|
212
|
+
bool store_pairs,
|
|
213
|
+
const IDSelector* sel) {
|
|
214
|
+
// Safely cast to ArrayInvertedListsPanorama to access cumulative sums.
|
|
215
|
+
const ArrayInvertedListsPanorama* storage =
|
|
216
|
+
dynamic_cast<const ArrayInvertedListsPanorama*>(ivf->invlists);
|
|
217
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
218
|
+
storage,
|
|
219
|
+
"IndexIVFFlatPanorama requires ArrayInvertedListsPanorama");
|
|
220
|
+
|
|
221
|
+
if (sel) {
|
|
222
|
+
return new IVFFlatScannerPanorama<VD, true>(
|
|
223
|
+
vd, storage, store_pairs, sel);
|
|
224
|
+
} else {
|
|
225
|
+
return new IVFFlatScannerPanorama<VD, false>(
|
|
226
|
+
vd, storage, store_pairs, sel);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
} // anonymous namespace
|
|
232
|
+
|
|
233
|
+
InvertedListScanner* IndexIVFFlatPanorama::get_InvertedListScanner(
|
|
234
|
+
bool store_pairs,
|
|
235
|
+
const IDSelector* sel,
|
|
236
|
+
const IVFSearchParameters*) const {
|
|
237
|
+
Run_get_InvertedListScanner run;
|
|
238
|
+
return dispatch_VectorDistance(
|
|
239
|
+
d, metric_type, metric_arg, run, this, store_pairs, sel);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
void IndexIVFFlatPanorama::reconstruct_from_offset(
|
|
243
|
+
int64_t list_no,
|
|
244
|
+
int64_t offset,
|
|
245
|
+
float* recons) const {
|
|
246
|
+
const uint8_t* code = invlists->get_single_code(list_no, offset);
|
|
247
|
+
memcpy(recons, code, code_size);
|
|
248
|
+
invlists->release_codes(list_no, code);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
} // namespace faiss
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and 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
|
+
#ifndef FAISS_INDEX_IVF_FLAT_PANORAMA_H
|
|
11
|
+
#define FAISS_INDEX_IVF_FLAT_PANORAMA_H
|
|
12
|
+
|
|
13
|
+
#include <stdint.h>
|
|
14
|
+
#include "faiss/IndexIVFFlat.h"
|
|
15
|
+
|
|
16
|
+
namespace faiss {
|
|
17
|
+
|
|
18
|
+
/// Panorama adaptation of IndexIVFFlat following
|
|
19
|
+
/// https://www.arxiv.org/pdf/2510.00566.
|
|
20
|
+
///
|
|
21
|
+
/// IDEA:
|
|
22
|
+
/// Panorama adapts the storage layout within each cluster and uses
|
|
23
|
+
/// pruning with bounds to improve the search performance.
|
|
24
|
+
/// Combined with orthogonal transforms upstream that concentrate the energy
|
|
25
|
+
/// in the early dimensions (like PCA, Cayley, etc.), Panorama can prune up
|
|
26
|
+
/// to 95% of the vectors in the cluster.
|
|
27
|
+
///
|
|
28
|
+
/// OVERHEAD:
|
|
29
|
+
/// To be more efficient, we compute the residual energies at insertion time
|
|
30
|
+
/// and store them along the vectors, which comes with an additional storage
|
|
31
|
+
/// overhead of exactly (nlevels + 1) floats per vector. Add time is also
|
|
32
|
+
/// slightly higher due to the overhead of transposing the vectors.
|
|
33
|
+
///
|
|
34
|
+
/// NOTE:
|
|
35
|
+
/// We inherit from IndexIVFFlat instead of IndexIVF so we can keep the same
|
|
36
|
+
/// insertion logic. The code responsible for level-oriented storage is in
|
|
37
|
+
/// `ArrayInvertedListsPanorama`, which is a struct member of `IndexIVF`.
|
|
38
|
+
struct IndexIVFFlatPanorama : IndexIVFFlat {
|
|
39
|
+
size_t n_levels;
|
|
40
|
+
|
|
41
|
+
std::vector<MaybeOwnedVector<float>> cum_sums;
|
|
42
|
+
|
|
43
|
+
explicit IndexIVFFlatPanorama(
|
|
44
|
+
Index* quantizer,
|
|
45
|
+
size_t d,
|
|
46
|
+
size_t nlist_,
|
|
47
|
+
int n_levels,
|
|
48
|
+
MetricType = METRIC_L2,
|
|
49
|
+
bool own_invlists = true);
|
|
50
|
+
|
|
51
|
+
InvertedListScanner* get_InvertedListScanner(
|
|
52
|
+
bool store_pairs,
|
|
53
|
+
const IDSelector* sel,
|
|
54
|
+
const IVFSearchParameters* params) const override;
|
|
55
|
+
|
|
56
|
+
void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons)
|
|
57
|
+
const override;
|
|
58
|
+
|
|
59
|
+
IndexIVFFlatPanorama();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace faiss
|
|
63
|
+
|
|
64
|
+
#endif
|
|
@@ -1163,7 +1163,9 @@ struct IVFPQScannerT : QueryTables {
|
|
|
1163
1163
|
}
|
|
1164
1164
|
|
|
1165
1165
|
#pragma omp critical
|
|
1166
|
-
{
|
|
1166
|
+
{
|
|
1167
|
+
indexIVFPQ_stats.n_hamming_pass += n_hamming_pass;
|
|
1168
|
+
}
|
|
1167
1169
|
}
|
|
1168
1170
|
|
|
1169
1171
|
template <class SearchResultType>
|
|
@@ -113,7 +113,7 @@ struct IndexIVFPQ : IndexIVF {
|
|
|
113
113
|
*/
|
|
114
114
|
size_t find_duplicates(idx_t* ids, size_t* lims) const;
|
|
115
115
|
|
|
116
|
-
// map a vector to a binary code
|
|
116
|
+
// map a vector to a binary code knowing the index
|
|
117
117
|
void encode(idx_t key, const float* x, uint8_t* code) const;
|
|
118
118
|
|
|
119
119
|
/** Encode multiple vectors
|