faiss 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +3 -1
- data/vendor/faiss/faiss/Clustering.cpp +9 -1
- data/vendor/faiss/faiss/IVFlib.cpp +14 -3
- data/vendor/faiss/faiss/Index.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +1 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +10 -12
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +5 -7
- data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
- data/vendor/faiss/faiss/IndexEDEN.h +57 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +13 -50
- data/vendor/faiss/faiss/IndexHNSW.cpp +177 -148
- data/vendor/faiss/faiss/IndexIDMap.cpp +16 -3
- data/vendor/faiss/faiss/IndexIDMap.h +2 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +19 -8
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
- data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +6 -5
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +42 -25
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -3
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +23 -62
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +10 -3
- data/vendor/faiss/faiss/IndexNSG.cpp +8 -4
- data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
- data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +68 -6
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
- data/vendor/faiss/faiss/IndexShards.cpp +2 -2
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
- data/vendor/faiss/faiss/SuperKMeans.cpp +256 -240
- data/vendor/faiss/faiss/SuperKMeans.h +30 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +33 -2
- data/vendor/faiss/faiss/clone_index.cpp +5 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
- data/vendor/faiss/faiss/factory_tools.cpp +51 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndex.h +34 -11
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +47 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +11 -12
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +3 -3
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
- data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +7 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +177 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +48 -3
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
- data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +658 -344
- data/vendor/faiss/faiss/impl/HNSW.h +51 -13
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +18 -12
- data/vendor/faiss/faiss/impl/Panorama.h +20 -7
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +59 -24
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +45 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +175 -68
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +19 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +2 -11
- data/vendor/faiss/faiss/impl/ResultHandler.h +26 -31
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +522 -58
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +70 -0
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +33 -13
- data/vendor/faiss/faiss/impl/VisitedTable.h +88 -33
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +1 -1
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +38 -3
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +35 -43
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -15
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +86 -40
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +81 -50
- data/vendor/faiss/faiss/impl/index_read.cpp +476 -75
- data/vendor/faiss/faiss/impl/index_write.cpp +56 -4
- data/vendor/faiss/faiss/impl/io_macros.h +25 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
- data/vendor/faiss/faiss/impl/platform_macros.h +15 -9
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
- data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +6 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +20 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +36 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +2 -0
- data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +882 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +6 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +336 -26
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +331 -32
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +558 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +284 -45
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +502 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +157 -32
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +26 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +86 -8
- data/vendor/faiss/faiss/index_factory.cpp +37 -7
- data/vendor/faiss/faiss/index_io.h +16 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +5 -2
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +15 -15
- data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -2
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +19 -4
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +150 -23
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +30 -7
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +65 -25
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +3 -2
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
- data/vendor/faiss/faiss/utils/bf16.h +34 -0
- data/vendor/faiss/faiss/utils/distances.cpp +14 -2
- data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -4
- data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
- data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +9 -9
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +2 -1
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +6 -30
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +0 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
- data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +160 -18
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +14 -68
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +273 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +435 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
- data/vendor/faiss/faiss/utils/simd_levels.cpp +56 -2
- data/vendor/faiss/faiss/utils/simd_levels.h +14 -0
- data/vendor/faiss/faiss/utils/utils.cpp +9 -27
- metadata +27 -2
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/impl/simdlib/simdlib_neon.h>
|
|
11
11
|
|
|
12
|
+
#include <algorithm>
|
|
12
13
|
#include <cstring>
|
|
13
14
|
|
|
14
15
|
#include <faiss/impl/scalar_quantizer/codecs.h>
|
|
@@ -180,6 +181,12 @@ struct QuantizerTemplate<
|
|
|
180
181
|
xi.data.val[1],
|
|
181
182
|
this->vdiff)});
|
|
182
183
|
}
|
|
184
|
+
|
|
185
|
+
/// Raw codec decode without denormalization (for pre-decode opt)
|
|
186
|
+
FAISS_ALWAYS_INLINE simd8float32
|
|
187
|
+
decode_8_raw(const uint8_t* code, int i) const {
|
|
188
|
+
return Codec::decode_8_components(code, i);
|
|
189
|
+
}
|
|
183
190
|
};
|
|
184
191
|
|
|
185
192
|
template <class Codec>
|
|
@@ -216,41 +223,52 @@ struct QuantizerTemplate<
|
|
|
216
223
|
};
|
|
217
224
|
|
|
218
225
|
/**********************************************************
|
|
219
|
-
*
|
|
226
|
+
* Lloyd-Max scalar quantizer
|
|
220
227
|
**********************************************************/
|
|
221
228
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
229
|
+
// NEON Lloyd-Max: decode via gather, encode stays scalar.
|
|
230
|
+
// NEON doesn't have movemask so 1-bit encode is also scalar.
|
|
231
|
+
#define DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(NBITS, UNPACK_FN) \
|
|
232
|
+
template <> \
|
|
233
|
+
struct QuantizerLloydMax<NBITS, SIMDLevel::ARM_NEON> \
|
|
234
|
+
: QuantizerLloydMax<NBITS, SIMDLevel::NONE> { \
|
|
235
|
+
using Base = QuantizerLloydMax<NBITS, SIMDLevel::NONE>; \
|
|
236
|
+
\
|
|
237
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained) \
|
|
238
|
+
: Base(d, trained) { \
|
|
239
|
+
assert(d % 8 == 0); \
|
|
240
|
+
} \
|
|
241
|
+
\
|
|
242
|
+
FAISS_ALWAYS_INLINE simd8float32 \
|
|
243
|
+
reconstruct_8_components(const uint8_t* code, int i) const { \
|
|
244
|
+
uint8_t indices[8]; \
|
|
245
|
+
UNPACK_FN(code, i, indices); \
|
|
246
|
+
return gather_8_components(this->centroids, indices); \
|
|
247
|
+
} \
|
|
248
|
+
\
|
|
249
|
+
void decode_vector(const uint8_t* code, float* x) const final { \
|
|
250
|
+
for (size_t i = 0; i < this->d; i += 8) { \
|
|
251
|
+
simd8float32 xi = \
|
|
252
|
+
reconstruct_8_components(code, static_cast<int>(i)); \
|
|
253
|
+
vst1q_f32(x + i, xi.data.val[0]); \
|
|
254
|
+
vst1q_f32(x + i + 4, xi.data.val[1]); \
|
|
255
|
+
} \
|
|
256
|
+
} \
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(1, unpack_8x1bit_to_u8);
|
|
260
|
+
DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(2, unpack_8x2bit_to_u8);
|
|
261
|
+
DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(3, unpack_8x3bit_to_u8);
|
|
262
|
+
DEFINE_LLOYD_MAX_NEON_SPECIALIZATION(4, unpack_8x4bit_to_u8);
|
|
263
|
+
|
|
264
|
+
#undef DEFINE_LLOYD_MAX_NEON_SPECIALIZATION
|
|
247
265
|
|
|
248
266
|
template <>
|
|
249
|
-
struct
|
|
250
|
-
:
|
|
251
|
-
using Base =
|
|
267
|
+
struct QuantizerLloydMax<8, SIMDLevel::ARM_NEON>
|
|
268
|
+
: QuantizerLloydMax<8, SIMDLevel::NONE> {
|
|
269
|
+
using Base = QuantizerLloydMax<8, SIMDLevel::NONE>;
|
|
252
270
|
|
|
253
|
-
|
|
271
|
+
QuantizerLloydMax(size_t d, const std::vector<float>& trained)
|
|
254
272
|
: Base(d, trained) {
|
|
255
273
|
assert(d % 8 == 0);
|
|
256
274
|
}
|
|
@@ -261,6 +279,15 @@ struct QuantizerTurboQuantMSE<8, SIMDLevel::ARM_NEON>
|
|
|
261
279
|
std::memcpy(indices, code + static_cast<size_t>(i), sizeof(indices));
|
|
262
280
|
return gather_8_components(this->centroids, indices);
|
|
263
281
|
}
|
|
282
|
+
|
|
283
|
+
void decode_vector(const uint8_t* code, float* x) const final {
|
|
284
|
+
for (size_t i = 0; i < this->d; i += 8) {
|
|
285
|
+
simd8float32 xi =
|
|
286
|
+
reconstruct_8_components(code, static_cast<int>(i));
|
|
287
|
+
vst1q_f32(x + i, xi.data.val[0]);
|
|
288
|
+
vst1q_f32(x + i + 4, xi.data.val[1]);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
264
291
|
};
|
|
265
292
|
|
|
266
293
|
/**********************************************************
|
|
@@ -397,6 +424,22 @@ struct SimilarityL2<SIMDLevel::ARM_NEON> {
|
|
|
397
424
|
FAISS_ALWAYS_INLINE float result_8() {
|
|
398
425
|
return horizontal_add(accu8);
|
|
399
426
|
}
|
|
427
|
+
|
|
428
|
+
static void adjust_query_for_raw_decode(
|
|
429
|
+
const float* x,
|
|
430
|
+
float* q_adj,
|
|
431
|
+
size_t d,
|
|
432
|
+
float vmin,
|
|
433
|
+
float vdiff,
|
|
434
|
+
float& scale_factor,
|
|
435
|
+
float& bias) {
|
|
436
|
+
float inv_vdiff = (vdiff != 0) ? 1.0f / vdiff : 0.0f;
|
|
437
|
+
for (size_t i = 0; i < d; i++) {
|
|
438
|
+
q_adj[i] = (x[i] - vmin) * inv_vdiff;
|
|
439
|
+
}
|
|
440
|
+
scale_factor = vdiff * vdiff;
|
|
441
|
+
bias = 0;
|
|
442
|
+
}
|
|
400
443
|
};
|
|
401
444
|
|
|
402
445
|
template <>
|
|
@@ -431,6 +474,23 @@ struct SimilarityIP<SIMDLevel::ARM_NEON> {
|
|
|
431
474
|
FAISS_ALWAYS_INLINE float result_8() {
|
|
432
475
|
return horizontal_add(accu8);
|
|
433
476
|
}
|
|
477
|
+
|
|
478
|
+
static void adjust_query_for_raw_decode(
|
|
479
|
+
const float* x,
|
|
480
|
+
float* q_adj,
|
|
481
|
+
size_t d,
|
|
482
|
+
float vmin,
|
|
483
|
+
float vdiff,
|
|
484
|
+
float& scale_factor,
|
|
485
|
+
float& bias) {
|
|
486
|
+
float sum_q = 0;
|
|
487
|
+
for (size_t i = 0; i < d; i++) {
|
|
488
|
+
q_adj[i] = x[i];
|
|
489
|
+
sum_q += x[i];
|
|
490
|
+
}
|
|
491
|
+
scale_factor = vdiff;
|
|
492
|
+
bias = vmin * sum_q;
|
|
493
|
+
}
|
|
434
494
|
};
|
|
435
495
|
|
|
436
496
|
/**********************************************************
|
|
@@ -444,8 +504,23 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
|
|
|
444
504
|
|
|
445
505
|
Quantizer quant;
|
|
446
506
|
|
|
507
|
+
// Pre-adjusted query buffer for uniform quantizers
|
|
508
|
+
std::vector<float> q_adj;
|
|
509
|
+
float scale_factor = 0;
|
|
510
|
+
float bias = 0;
|
|
511
|
+
|
|
512
|
+
static constexpr bool has_decode_raw() {
|
|
513
|
+
return requires(const Quantizer& q, const uint8_t* c, int i) {
|
|
514
|
+
{ q.decode_8_raw(c, i) };
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
|
|
447
518
|
DCTemplate(size_t d, const std::vector<float>& trained)
|
|
448
|
-
: quant(d, trained) {
|
|
519
|
+
: quant(d, trained) {
|
|
520
|
+
if constexpr (has_decode_raw()) {
|
|
521
|
+
q_adj.resize(d);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
449
524
|
|
|
450
525
|
float compute_distance(const float* x, const uint8_t* code) const {
|
|
451
526
|
Similarity sim(x);
|
|
@@ -471,6 +546,26 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
|
|
|
471
546
|
|
|
472
547
|
void set_query(const float* x) final {
|
|
473
548
|
q = x;
|
|
549
|
+
if constexpr (has_decode_raw()) {
|
|
550
|
+
Sim::adjust_query_for_raw_decode(
|
|
551
|
+
x,
|
|
552
|
+
q_adj.data(),
|
|
553
|
+
quant.d,
|
|
554
|
+
quant.vmin,
|
|
555
|
+
quant.vdiff,
|
|
556
|
+
scale_factor,
|
|
557
|
+
bias);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
float query_to_code_predecoded(const uint8_t* code) const {
|
|
562
|
+
Similarity sim(q_adj.data());
|
|
563
|
+
sim.begin_8();
|
|
564
|
+
for (size_t i = 0; i < quant.d; i += 8) {
|
|
565
|
+
simd8float32 xi = quant.decode_8_raw(code, i);
|
|
566
|
+
sim.add_8_components(xi);
|
|
567
|
+
}
|
|
568
|
+
return bias + scale_factor * sim.result_8();
|
|
474
569
|
}
|
|
475
570
|
|
|
476
571
|
float symmetric_dis(idx_t i, idx_t j) override {
|
|
@@ -479,7 +574,11 @@ struct DCTemplate<Quantizer, Similarity, SIMDLevel::ARM_NEON>
|
|
|
479
574
|
}
|
|
480
575
|
|
|
481
576
|
float query_to_code(const uint8_t* code) const final {
|
|
482
|
-
|
|
577
|
+
if constexpr (has_decode_raw()) {
|
|
578
|
+
return query_to_code_predecoded(code);
|
|
579
|
+
} else {
|
|
580
|
+
return compute_distance(q, code);
|
|
581
|
+
}
|
|
483
582
|
}
|
|
484
583
|
|
|
485
584
|
void query_to_codes_batch_4(
|
|
@@ -564,6 +663,32 @@ struct DistanceComputerByte<Similarity, SIMDLevel::ARM_NEON>
|
|
|
564
663
|
}
|
|
565
664
|
};
|
|
566
665
|
|
|
666
|
+
/**********************************************************
|
|
667
|
+
* TurboQuant masked_sum NEON specialization (scalar fallback)
|
|
668
|
+
**********************************************************/
|
|
669
|
+
|
|
670
|
+
template <SIMDLevel SL0>
|
|
671
|
+
float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
|
|
672
|
+
|
|
673
|
+
template <>
|
|
674
|
+
float turboq_masked_sum<SIMDLevel::ARM_NEON>(
|
|
675
|
+
const float* arr,
|
|
676
|
+
const uint8_t* bits,
|
|
677
|
+
size_t d) {
|
|
678
|
+
float result = 0;
|
|
679
|
+
for (size_t byte_idx = 0; byte_idx < (d + 7) / 8; byte_idx++) {
|
|
680
|
+
uint8_t b = bits[byte_idx];
|
|
681
|
+
size_t base = byte_idx * 8;
|
|
682
|
+
size_t end = std::min(base + 8, d);
|
|
683
|
+
for (size_t j = base; j < end; j++) {
|
|
684
|
+
if (b & (1 << (j - base))) {
|
|
685
|
+
result += arr[j];
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
|
|
567
692
|
} // namespace scalar_quantizer
|
|
568
693
|
} // namespace faiss
|
|
569
694
|
|
|
@@ -302,6 +302,32 @@ struct DCTemplate<
|
|
|
302
302
|
}
|
|
303
303
|
};
|
|
304
304
|
|
|
305
|
+
/**********************************************************
|
|
306
|
+
* TurboQuant masked_sum RVV specialization (scalar fallback)
|
|
307
|
+
**********************************************************/
|
|
308
|
+
|
|
309
|
+
template <SIMDLevel SL0>
|
|
310
|
+
float turboq_masked_sum(const float* arr, const uint8_t* bits, size_t d);
|
|
311
|
+
|
|
312
|
+
template <>
|
|
313
|
+
float turboq_masked_sum<SIMDLevel::RISCV_RVV>(
|
|
314
|
+
const float* arr,
|
|
315
|
+
const uint8_t* bits,
|
|
316
|
+
size_t d) {
|
|
317
|
+
float result = 0;
|
|
318
|
+
for (size_t byte_idx = 0; byte_idx < (d + 7) / 8; byte_idx++) {
|
|
319
|
+
uint8_t b = bits[byte_idx];
|
|
320
|
+
size_t base = byte_idx * 8;
|
|
321
|
+
size_t end = std::min(base + 8, d);
|
|
322
|
+
for (size_t j = base; j < end; j++) {
|
|
323
|
+
if (b & (1 << (j - base))) {
|
|
324
|
+
result += arr[j];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
|
|
305
331
|
} // namespace scalar_quantizer
|
|
306
332
|
} // namespace faiss
|
|
307
333
|
|
|
@@ -36,6 +36,12 @@ constexpr int AVAILABLE_SIMD_LEVELS_AVX2_NEON = AVAILABLE_SIMD_LEVELS_NONE |
|
|
|
36
36
|
constexpr int AVAILABLE_SIMD_LEVELS_A0 = AVAILABLE_SIMD_LEVELS_AVX2_NEON |
|
|
37
37
|
(1 << int(SIMDLevel::AVX512)) | (1 << int(SIMDLevel::RISCV_RVV));
|
|
38
38
|
|
|
39
|
+
// A0_SPR: same as A0 + AVX512_SPR (for functions with a dedicated SPR
|
|
40
|
+
// specialization on top of an AVX512 fallback). Currently used by the
|
|
41
|
+
// RaBitQ popcount kernels, which use VPOPCNTDQ on SPR+.
|
|
42
|
+
constexpr int AVAILABLE_SIMD_LEVELS_A0_SPR =
|
|
43
|
+
AVAILABLE_SIMD_LEVELS_A0 | (1 << int(SIMDLevel::AVX512_SPR));
|
|
44
|
+
|
|
39
45
|
// A1: same + ARM_SVE (for functions with dedicated SVE implementations)
|
|
40
46
|
constexpr int AVAILABLE_SIMD_LEVELS_A1 =
|
|
41
47
|
AVAILABLE_SIMD_LEVELS_A0 | (1 << int(SIMDLevel::ARM_SVE));
|
|
@@ -47,6 +53,55 @@ constexpr int AVAILABLE_SIMD_LEVELS_A2 = AVAILABLE_SIMD_LEVELS_NONE |
|
|
|
47
53
|
|
|
48
54
|
constexpr int AVAILABLE_SIMD_LEVELS_ALL = -1;
|
|
49
55
|
|
|
56
|
+
constexpr SIMDLevel get_simd_fallback(SIMDLevel level) {
|
|
57
|
+
switch (level) {
|
|
58
|
+
case SIMDLevel::AVX512_SPR:
|
|
59
|
+
return SIMDLevel::AVX512;
|
|
60
|
+
case SIMDLevel::AVX512:
|
|
61
|
+
return SIMDLevel::AVX2;
|
|
62
|
+
case SIMDLevel::ARM_SVE:
|
|
63
|
+
return SIMDLevel::ARM_NEON;
|
|
64
|
+
case SIMDLevel::AVX2:
|
|
65
|
+
case SIMDLevel::ARM_NEON:
|
|
66
|
+
case SIMDLevel::RISCV_RVV:
|
|
67
|
+
return SIMDLevel::NONE;
|
|
68
|
+
default:
|
|
69
|
+
return SIMDLevel::NONE;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
template <int available_levels, SIMDLevel current_level, typename LambdaType>
|
|
74
|
+
inline auto dispatch_with_fallback(LambdaType&& action) {
|
|
75
|
+
if constexpr (available_levels & (1 << int(current_level))) {
|
|
76
|
+
return action.template operator()<current_level>();
|
|
77
|
+
} else if constexpr (current_level != SIMDLevel::NONE) {
|
|
78
|
+
return dispatch_with_fallback<
|
|
79
|
+
available_levels,
|
|
80
|
+
get_simd_fallback(current_level)>(
|
|
81
|
+
std::forward<LambdaType>(action));
|
|
82
|
+
} else {
|
|
83
|
+
return action.template operator()<SIMDLevel::NONE>();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Run action at current_level; on a null result, retry the next-lower level,
|
|
88
|
+
* down to NONE (terminal). action is called per level tried, so never moved. */
|
|
89
|
+
template <int available_levels, SIMDLevel current_level, typename LambdaType>
|
|
90
|
+
inline auto dispatch_simd_level_or_lower(LambdaType& action) {
|
|
91
|
+
if constexpr (current_level == SIMDLevel::NONE) {
|
|
92
|
+
return action.template operator()<SIMDLevel::NONE>();
|
|
93
|
+
} else {
|
|
94
|
+
if constexpr (available_levels & (1 << int(current_level))) {
|
|
95
|
+
if (auto result = action.template operator()<current_level>()) {
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return dispatch_simd_level_or_lower<
|
|
100
|
+
available_levels,
|
|
101
|
+
get_simd_fallback(current_level)>(action);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
50
105
|
/** The complete dispatching function. It takes into account:
|
|
51
106
|
* - the currently selected SIMD level
|
|
52
107
|
* - the compiled in SIMD levels (given by COMPILE_SIMD_XXX)
|
|
@@ -114,17 +169,30 @@ inline auto with_selected_simd_levels(LambdaType&& action) {
|
|
|
114
169
|
}
|
|
115
170
|
#else // static dispatch
|
|
116
171
|
// In static mode, SINGLE_SIMD_LEVEL is a constexpr resolved at compile
|
|
117
|
-
// time.
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
172
|
+
// time. We mirror the DD fallthrough behavior at compile time via
|
|
173
|
+
// dispatch_with_fallback, which recursively walks get_simd_fallback:
|
|
174
|
+
// x86: AVX512_SPR -> AVX512 -> AVX2 -> NONE
|
|
175
|
+
// ARM: ARM_SVE -> ARM_NEON -> NONE
|
|
176
|
+
// RISCV: RISCV_RVV -> NONE
|
|
177
|
+
// The first level in the chain that appears in available_levels is
|
|
178
|
+
// selected; if none match, NONE is used unconditionally.
|
|
179
|
+
return dispatch_with_fallback<available_levels, SINGLE_SIMD_LEVEL>(
|
|
180
|
+
std::forward<LambdaType>(action));
|
|
125
181
|
#endif
|
|
126
182
|
}
|
|
127
183
|
|
|
184
|
+
/** Like with_selected_simd_levels, but for factory actions that return null to
|
|
185
|
+
* decline a level (e.g. AVX-512 needing d % 16 == 0). Falls back to the next
|
|
186
|
+
* lower level, down to NONE. */
|
|
187
|
+
template <int available_levels, typename LambdaType>
|
|
188
|
+
inline auto with_simd_level_fallback(const LambdaType& action) {
|
|
189
|
+
return with_selected_simd_levels<available_levels>(
|
|
190
|
+
[&action]<SIMDLevel SL>() {
|
|
191
|
+
return dispatch_simd_level_or_lower<available_levels, SL>(
|
|
192
|
+
action);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
128
196
|
/**
|
|
129
197
|
* Dispatch to a lambda with SIMDLevel as a compile-time constant.
|
|
130
198
|
*
|
|
@@ -170,4 +238,14 @@ inline auto with_simd_level_256bit(LambdaType&& action) {
|
|
|
170
238
|
std::forward<LambdaType>(action));
|
|
171
239
|
}
|
|
172
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Use for functions that have A0-level implementations plus an AVX512_SPR
|
|
243
|
+
* specialization (e.g. using VPOPCNTDQ).
|
|
244
|
+
*/
|
|
245
|
+
template <typename LambdaType>
|
|
246
|
+
inline auto with_simd_level_a0_spr(LambdaType&& action) {
|
|
247
|
+
return with_selected_simd_levels<AVAILABLE_SIMD_LEVELS_A0_SPR>(
|
|
248
|
+
std::forward<LambdaType>(action));
|
|
249
|
+
}
|
|
250
|
+
|
|
173
251
|
} // namespace faiss
|
|
@@ -21,11 +21,13 @@
|
|
|
21
21
|
#include <faiss/Index2Layer.h>
|
|
22
22
|
#include <faiss/IndexAdditiveQuantizer.h>
|
|
23
23
|
#include <faiss/IndexAdditiveQuantizerFastScan.h>
|
|
24
|
+
#include <faiss/IndexEDEN.h>
|
|
24
25
|
#include <faiss/IndexFlat.h>
|
|
25
26
|
#include <faiss/IndexHNSW.h>
|
|
26
27
|
#include <faiss/IndexIVF.h>
|
|
27
28
|
#include <faiss/IndexIVFAdditiveQuantizer.h>
|
|
28
29
|
#include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
|
|
30
|
+
#include <faiss/IndexIVFEDEN.h>
|
|
29
31
|
#include <faiss/IndexIVFFlat.h>
|
|
30
32
|
#include <faiss/IndexIVFFlatPanorama.h>
|
|
31
33
|
#include <faiss/IndexIVFPQ.h>
|
|
@@ -168,9 +170,13 @@ std::map<std::string, ScalarQuantizer::QuantizerType> sq_types = {
|
|
|
168
170
|
{"SQtqmse3", ScalarQuantizer::QT_3bit_tqmse},
|
|
169
171
|
{"SQtqmse4", ScalarQuantizer::QT_4bit_tqmse},
|
|
170
172
|
{"SQtqmse8", ScalarQuantizer::QT_8bit_tqmse},
|
|
173
|
+
{"SQtq2", ScalarQuantizer::QT_2bit_tq},
|
|
174
|
+
{"SQtq3", ScalarQuantizer::QT_3bit_tq},
|
|
175
|
+
{"SQtq4", ScalarQuantizer::QT_4bit_tq},
|
|
176
|
+
{"SQtq5", ScalarQuantizer::QT_5bit_tq},
|
|
171
177
|
};
|
|
172
178
|
const std::string sq_pattern =
|
|
173
|
-
"(SQ0|SQ4|SQ8|SQ6|SQfp16|SQbf16|SQ8_direct_signed|SQ8_direct|SQtqmse1|SQtqmse2|SQtqmse3|SQtqmse4|SQtqmse8)";
|
|
179
|
+
"(SQ0|SQ4|SQ8|SQ6|SQfp16|SQbf16|SQ8_direct_signed|SQ8_direct|SQtqmse1|SQtqmse2|SQtqmse3|SQtqmse4|SQtqmse8|SQtq2|SQtq3|SQtq4|SQtq5)";
|
|
174
180
|
|
|
175
181
|
std::map<std::string, AdditiveQuantizer::Search_type_t> aq_search_type = {
|
|
176
182
|
{"_Nfloat", AdditiveQuantizer::ST_norm_float},
|
|
@@ -311,8 +317,8 @@ Index* parse_coarse_quantizer(
|
|
|
311
317
|
SVSStorageKind storage = SVSStorageKind::SVS_FP32;
|
|
312
318
|
if (sm[3].matched) {
|
|
313
319
|
std::string s = sm[3].str().substr(1);
|
|
314
|
-
if (s == "
|
|
315
|
-
storage = SVSStorageKind::
|
|
320
|
+
if (s == "SQ8") {
|
|
321
|
+
storage = SVSStorageKind::SVS_SQ8;
|
|
316
322
|
} else if (s == "FP16") {
|
|
317
323
|
storage = SVSStorageKind::SVS_FP16;
|
|
318
324
|
} else if (s == "FP32") {
|
|
@@ -510,6 +516,18 @@ IndexIVF* parse_IndexIVF(
|
|
|
510
516
|
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
511
517
|
return new IndexIVFRaBitQ(get_q(), d, nlist, mt, own_il, nb_bits);
|
|
512
518
|
}
|
|
519
|
+
// IndexIVFEDEN with optional nb_bits (1-8) and scale type.
|
|
520
|
+
// Accepts: "EDEN" (default 1-bit), "EDEN{nb_bits}" (e.g., "EDEN4"),
|
|
521
|
+
// or "EDEN{nb_bits}BIASED" for the MSE-minimizing scale.
|
|
522
|
+
if (match("EDEN([1-8])?(BIASED|BIAS)?")) {
|
|
523
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
524
|
+
EDENScaleType scale_type =
|
|
525
|
+
sm[2].str() == "BIASED" || sm[2].str() == "BIAS"
|
|
526
|
+
? EDENScaleType_BIASED
|
|
527
|
+
: EDENScaleType_UNBIASED;
|
|
528
|
+
return new IndexIVFEDEN(
|
|
529
|
+
get_q(), d, nlist, mt, own_il, nb_bits, scale_type);
|
|
530
|
+
}
|
|
513
531
|
// Accepts: "RaBitQfs" (default 1-bit, batch size 32)
|
|
514
532
|
// "RaBitQfs{nb_bits}" (e.g., "RaBitQfs4")
|
|
515
533
|
// "RaBitQfs_64" (1-bit, batch size 64)
|
|
@@ -677,16 +695,16 @@ Index* parse_svs_datatype(
|
|
|
677
695
|
}
|
|
678
696
|
FAISS_ASSERT(false && "Unsupported SVS index type for Float16");
|
|
679
697
|
}
|
|
680
|
-
if (re_match(datatype_string, "
|
|
698
|
+
if (re_match(datatype_string, "SQ8", sm)) {
|
|
681
699
|
if (index_type == "Vamana") {
|
|
682
700
|
return new IndexSVSVamana(
|
|
683
|
-
d, std::stoul(arg_string), mt, SVSStorageKind::
|
|
701
|
+
d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQ8);
|
|
684
702
|
}
|
|
685
703
|
if (index_type == "IVF") {
|
|
686
704
|
return new IndexSVSIVF(
|
|
687
|
-
d, std::stoul(arg_string), mt, SVSStorageKind::
|
|
705
|
+
d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQ8);
|
|
688
706
|
}
|
|
689
|
-
FAISS_ASSERT(false && "Unsupported SVS index type for
|
|
707
|
+
FAISS_ASSERT(false && "Unsupported SVS index type for SQ8");
|
|
690
708
|
}
|
|
691
709
|
if (re_match(datatype_string, "(LVQ[0-9]+x[0-9]+)", sm)) {
|
|
692
710
|
if (index_type == "Vamana") {
|
|
@@ -913,6 +931,18 @@ Index* parse_other_indexes(
|
|
|
913
931
|
return new IndexRaBitQ(d, metric, nb_bits);
|
|
914
932
|
}
|
|
915
933
|
|
|
934
|
+
// IndexEDEN with optional nb_bits (1-8) and scale type.
|
|
935
|
+
// Accepts: "EDEN" (default 1-bit), "EDEN{nb_bits}" (e.g., "EDEN4"),
|
|
936
|
+
// or "EDEN{nb_bits}BIASED" for the MSE-minimizing scale.
|
|
937
|
+
if (match("EDEN([1-8])?(BIASED|BIAS)?")) {
|
|
938
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
939
|
+
EDENScaleType scale_type =
|
|
940
|
+
sm[2].str() == "BIASED" || sm[2].str() == "BIAS"
|
|
941
|
+
? EDENScaleType_BIASED
|
|
942
|
+
: EDENScaleType_UNBIASED;
|
|
943
|
+
return new IndexEDEN(d, metric, nb_bits, scale_type);
|
|
944
|
+
}
|
|
945
|
+
|
|
916
946
|
if (match("RaBitQfs([1-9])?(_[0-9]+)?")) {
|
|
917
947
|
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
918
948
|
int bbs = mres_to_int(sm[2], 32, 1);
|
|
@@ -137,6 +137,22 @@ size_t get_deserialization_vector_byte_limit();
|
|
|
137
137
|
// and do not modify while deserialization is in progress on other threads.
|
|
138
138
|
void set_deserialization_vector_byte_limit(size_t value);
|
|
139
139
|
|
|
140
|
+
// Returns the current IndexLattice r2 limit for deserialization.
|
|
141
|
+
// When nonzero, deserialization rejects IndexLattice payloads whose
|
|
142
|
+
// r2 (squared lattice radius) exceeds this value. The
|
|
143
|
+
// ZnSphereCodecRec constructor that runs at IndexLattice deserialize
|
|
144
|
+
// time builds a decode cache whose population cost scales
|
|
145
|
+
// polynomially in r2 and dim, and can exceed real-world workload time
|
|
146
|
+
// budgets even for r2 values that do not trip the existing
|
|
147
|
+
// decode-cache memory cap.
|
|
148
|
+
// Default: 0 (no limit).
|
|
149
|
+
size_t get_deserialization_lattice_r2_limit();
|
|
150
|
+
|
|
151
|
+
// Sets the IndexLattice r2 deserialization limit.
|
|
152
|
+
// NOT thread-safe: set before any concurrent deserialization calls
|
|
153
|
+
// and do not modify while deserialization is in progress on other threads.
|
|
154
|
+
void set_deserialization_lattice_r2_limit(size_t value);
|
|
155
|
+
|
|
140
156
|
} // namespace faiss
|
|
141
157
|
|
|
142
158
|
#endif
|
|
@@ -80,7 +80,7 @@ idx_t DirectMap::get(idx_t key) const {
|
|
|
80
80
|
return lo;
|
|
81
81
|
} else if (type == Hashtable) {
|
|
82
82
|
auto res = hashtable.find(key);
|
|
83
|
-
|
|
83
|
+
FAISS_THROW_IF_MSG(res == hashtable.end(), "key not found");
|
|
84
84
|
return res->second;
|
|
85
85
|
} else {
|
|
86
86
|
FAISS_THROW_MSG("direct map not initialized");
|
|
@@ -254,7 +254,10 @@ void DirectMap::update_codes(
|
|
|
254
254
|
int64_t id2 = invlists->get_single_id(il, l - 1);
|
|
255
255
|
array[id2] = lo_build(il, ofs);
|
|
256
256
|
invlists->update_entry(
|
|
257
|
-
il,
|
|
257
|
+
il,
|
|
258
|
+
ofs,
|
|
259
|
+
id2,
|
|
260
|
+
InvertedLists::ScopedCodes(invlists, il, l - 1).get());
|
|
258
261
|
}
|
|
259
262
|
invlists->resize(il, l - 1);
|
|
260
263
|
}
|
|
@@ -371,8 +371,8 @@ ArrayInvertedListsPanorama::ArrayInvertedListsPanorama(
|
|
|
371
371
|
pano(code_size_in, n_levels_in, batch_size) {
|
|
372
372
|
FAISS_THROW_IF_NOT(n_levels_in > 0);
|
|
373
373
|
FAISS_THROW_IF_NOT(code_size_in % sizeof(float) == 0);
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
FAISS_THROW_IF_MSG(
|
|
375
|
+
use_iterator,
|
|
376
376
|
"IndexIVFFlatPanorama does not support iterators, use vanilla IndexIVFFlat instead");
|
|
377
377
|
FAISS_ASSERT(level_width % sizeof(float) == 0);
|
|
378
378
|
|
|
@@ -498,12 +498,12 @@ void ReadOnlyInvertedLists::resize(size_t, size_t) {
|
|
|
498
498
|
* HStackInvertedLists implementation
|
|
499
499
|
******************************************/
|
|
500
500
|
|
|
501
|
-
HStackInvertedLists::HStackInvertedLists(int
|
|
501
|
+
HStackInvertedLists::HStackInvertedLists(int n_il, const InvertedLists** ils_in)
|
|
502
502
|
: ReadOnlyInvertedLists(
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
FAISS_THROW_IF_NOT(
|
|
506
|
-
for (int i = 0; i <
|
|
503
|
+
n_il > 0 ? ils_in[0]->nlist : 0,
|
|
504
|
+
n_il > 0 ? ils_in[0]->code_size : 0) {
|
|
505
|
+
FAISS_THROW_IF_NOT(n_il > 0);
|
|
506
|
+
for (int i = 0; i < n_il; i++) {
|
|
507
507
|
ils.push_back(ils_in[i]);
|
|
508
508
|
FAISS_THROW_IF_NOT(
|
|
509
509
|
ils_in[i]->code_size == code_size && ils_in[i]->nlist == nlist);
|
|
@@ -683,9 +683,9 @@ int translate_list_no(const VStackInvertedLists* vil, idx_t list_no) {
|
|
|
683
683
|
return i0;
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
-
idx_t sum_il_sizes(int
|
|
686
|
+
idx_t sum_il_sizes(int n_il, const InvertedLists** ils_in) {
|
|
687
687
|
idx_t tot = 0;
|
|
688
|
-
for (int i = 0; i <
|
|
688
|
+
for (int i = 0; i < n_il; i++) {
|
|
689
689
|
tot += ils_in[i]->nlist;
|
|
690
690
|
}
|
|
691
691
|
return tot;
|
|
@@ -693,13 +693,13 @@ idx_t sum_il_sizes(int nil, const InvertedLists** ils_in) {
|
|
|
693
693
|
|
|
694
694
|
} // namespace
|
|
695
695
|
|
|
696
|
-
VStackInvertedLists::VStackInvertedLists(int
|
|
696
|
+
VStackInvertedLists::VStackInvertedLists(int n_il, const InvertedLists** ils_in)
|
|
697
697
|
: ReadOnlyInvertedLists(
|
|
698
|
-
sum_il_sizes(
|
|
699
|
-
|
|
700
|
-
FAISS_THROW_IF_NOT(
|
|
701
|
-
cumsz.resize(
|
|
702
|
-
for (int i = 0; i <
|
|
698
|
+
sum_il_sizes(n_il, ils_in),
|
|
699
|
+
n_il > 0 ? ils_in[0]->code_size : 0) {
|
|
700
|
+
FAISS_THROW_IF_NOT(n_il > 0);
|
|
701
|
+
cumsz.resize(n_il + 1);
|
|
702
|
+
for (int i = 0; i < n_il; i++) {
|
|
703
703
|
ils.push_back(ils_in[i]);
|
|
704
704
|
FAISS_THROW_IF_NOT(ils_in[i]->code_size == code_size);
|
|
705
705
|
cumsz[i + 1] = cumsz[i] + ils_in[i]->nlist;
|
|
@@ -376,7 +376,7 @@ struct HStackInvertedLists : ReadOnlyInvertedLists {
|
|
|
376
376
|
std::vector<const InvertedLists*> ils;
|
|
377
377
|
|
|
378
378
|
/// build InvertedLists by concatenating nil of them
|
|
379
|
-
HStackInvertedLists(int
|
|
379
|
+
HStackInvertedLists(int n_il, const InvertedLists** ils);
|
|
380
380
|
|
|
381
381
|
size_t list_size(size_t list_no) const override;
|
|
382
382
|
const uint8_t* get_codes(size_t list_no) const override;
|
|
@@ -422,7 +422,7 @@ struct VStackInvertedLists : ReadOnlyInvertedLists {
|
|
|
422
422
|
std::vector<idx_t> cumsz;
|
|
423
423
|
|
|
424
424
|
/// build InvertedLists by concatenating nil of them
|
|
425
|
-
VStackInvertedLists(int
|
|
425
|
+
VStackInvertedLists(int n_il, const InvertedLists** ils);
|
|
426
426
|
|
|
427
427
|
size_t list_size(size_t list_no) const override;
|
|
428
428
|
const uint8_t* get_codes(size_t list_no) const override;
|