faiss 0.6.4 → 0.6.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 +4 -0
- data/ext/faiss/extconf.rb +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +175 -0
- data/vendor/faiss/faiss/Clustering.cpp +150 -60
- data/vendor/faiss/faiss/Clustering.h +29 -0
- data/vendor/faiss/faiss/IVFlib.cpp +99 -0
- data/vendor/faiss/faiss/IVFlib.h +15 -0
- data/vendor/faiss/faiss/Index.cpp +44 -0
- data/vendor/faiss/faiss/Index.h +19 -14
- data/vendor/faiss/faiss/IndexBinary.cpp +8 -0
- data/vendor/faiss/faiss/IndexBinary.h +8 -0
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +82 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +19 -0
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +34 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +33 -17
- data/vendor/faiss/faiss/IndexFastScan.h +6 -3
- data/vendor/faiss/faiss/IndexFlat.cpp +56 -0
- data/vendor/faiss/faiss/IndexFlat.h +31 -0
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +6 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +456 -10
- data/vendor/faiss/faiss/IndexHNSW.h +38 -0
- data/vendor/faiss/faiss/IndexIDMap.cpp +32 -0
- data/vendor/faiss/faiss/IndexIDMap.h +7 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +281 -31
- data/vendor/faiss/faiss/IndexIVF.h +53 -1
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +46 -14
- data/vendor/faiss/faiss/IndexIVFFastScan.h +4 -2
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +33 -0
- data/vendor/faiss/faiss/IndexIVFFlat.h +16 -0
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +1 -0
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +3 -20
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +50 -14
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -2
- data/vendor/faiss/faiss/IndexIVFSQFastScan.cpp +855 -0
- data/vendor/faiss/faiss/IndexIVFSQFastScan.h +145 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +0 -3
- data/vendor/faiss/faiss/IndexPiPNN.cpp +201 -0
- data/vendor/faiss/faiss/IndexPiPNN.h +83 -0
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +6 -3
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +10 -4
- data/vendor/faiss/faiss/IndexReplicas.cpp +20 -0
- data/vendor/faiss/faiss/IndexReplicas.h +9 -0
- data/vendor/faiss/faiss/IndexSQFastScan.cpp +648 -0
- data/vendor/faiss/faiss/IndexSQFastScan.h +129 -0
- data/vendor/faiss/faiss/IndexShards.cpp +10 -0
- data/vendor/faiss/faiss/IndexShards.h +5 -0
- data/vendor/faiss/faiss/SuperKMeans.cpp +57 -15
- data/vendor/faiss/faiss/SuperKMeans.h +9 -4
- data/vendor/faiss/faiss/VectorTransform.cpp +3 -2
- data/vendor/faiss/faiss/clone_index.cpp +24 -0
- data/vendor/faiss/faiss/gpu/Dataset.h +112 -0
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +16 -13
- data/vendor/faiss/faiss/gpu/GpuCloner.h +4 -0
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +3 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +4 -13
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryCagra.h +26 -13
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +45 -22
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +11 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +6 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuDatasetHeader.cpp +18 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +215 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +98 -0
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +11 -0
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +1 -1
- data/vendor/faiss/faiss/gpu_metal/MetalCloner.h +11 -0
- data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +92 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +4 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexBinaryFlat.h +69 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +38 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +106 -0
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +10 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +2 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -6
- data/vendor/faiss/faiss/impl/ClusteringHelpers.cpp +134 -45
- data/vendor/faiss/faiss/impl/ClusteringHelpers.h +36 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +286 -136
- data/vendor/faiss/faiss/impl/DistanceComputer.cpp +63 -0
- data/vendor/faiss/faiss/impl/DistanceComputer.h +3 -29
- data/vendor/faiss/faiss/impl/HNSW.cpp +46 -10
- data/vendor/faiss/faiss/impl/HNSW.h +72 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +6 -19
- data/vendor/faiss/faiss/impl/NNDescent.cpp +2 -1
- data/vendor/faiss/faiss/impl/NSG.cpp +3 -2
- data/vendor/faiss/faiss/impl/Panorama.h +3 -2
- data/vendor/faiss/faiss/impl/PiPNN.cpp +822 -0
- data/vendor/faiss/faiss/impl/PiPNN.h +122 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +54 -11
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +1 -1
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +81 -57
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +15 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +29 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +1 -6
- data/vendor/faiss/faiss/impl/approx_topk/avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/approx_topk/neon.cpp +0 -4
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryHash_impl.h +5 -2
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/binary_hamming/avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/binary_hamming/neon.cpp +0 -4
- data/vendor/faiss/faiss/impl/binary_hamming/rvv.cpp +0 -4
- data/vendor/faiss/faiss/impl/expanded_scanners.h +88 -0
- data/vendor/faiss/faiss/impl/fast_scan/FastScanDistancePostProcessing.h +4 -0
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops.h +61 -64
- data/vendor/faiss/faiss/impl/fast_scan/accumulate_loops_512.h +13 -14
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +17 -129
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +25 -19
- data/vendor/faiss/faiss/impl/fast_scan/fast_scan.cpp +5 -0
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/fast_scan/impl-avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/fast_scan/impl-neon.cpp +0 -88
- data/vendor/faiss/faiss/impl/fast_scan/impl-riscv.cpp +0 -4
- data/vendor/faiss/faiss/impl/fast_scan/kernels_neon.h +155 -0
- data/vendor/faiss/faiss/impl/fast_scan/kernels_simd256.h +22 -1
- data/vendor/faiss/faiss/impl/fast_scan/kernels_simd512.h +3 -2
- data/vendor/faiss/faiss/impl/fast_scan/simd_result_handlers.h +41 -23
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/index_read.cpp +172 -0
- data/vendor/faiss/faiss/impl/index_write.cpp +95 -0
- data/vendor/faiss/faiss/impl/pipnn/HashPrune.cpp +159 -0
- data/vendor/faiss/faiss/impl/pipnn/HashPrune.h +69 -0
- data/vendor/faiss/faiss/impl/pipnn/Partition.cpp +587 -0
- data/vendor/faiss/faiss/impl/pipnn/Partition.h +93 -0
- data/vendor/faiss/faiss/impl/pipnn/kernels.cpp +326 -0
- data/vendor/faiss/faiss/impl/pipnn/kernels.h +92 -0
- data/vendor/faiss/faiss/impl/platform_macros.h +45 -0
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +79 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +6 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +0 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-avx2.h +4 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-avx512.h +4 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +19 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.h +6 -6
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +131 -6
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +0 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_rvv_kernel.h +89 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +21 -10
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +45 -18
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +2 -1
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +0 -4
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +0 -4
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +5 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +28 -52
- data/vendor/faiss/faiss/impl/scalar_quantizer/scanners.h +59 -11
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +226 -77
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +482 -103
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +2 -149
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +3 -698
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +66 -57
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +101 -96
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +3185 -144
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq8_coefficients.h +48 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq8_rvv_kernel.h +546 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/training.cpp +2 -2
- data/vendor/faiss/faiss/impl/simd_dispatch.h +7 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib_avx2.h +14 -0
- data/vendor/faiss/faiss/impl/simdlib/simdlib_dispatch.h +7 -8
- data/vendor/faiss/faiss/impl/sq_fastscan_utils.h +232 -0
- data/vendor/faiss/faiss/index_factory.cpp +76 -0
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +3 -2
- data/vendor/faiss/faiss/utils/AlignedTable.h +6 -1
- data/vendor/faiss/faiss/utils/Heap.cpp +4 -3
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +16 -5
- data/vendor/faiss/faiss/utils/bf16.h +36 -0
- data/vendor/faiss/faiss/utils/distances.cpp +226 -15
- data/vendor/faiss/faiss/utils/distances.h +34 -0
- data/vendor/faiss/faiss/utils/distances_dispatch.h +6 -4
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +2 -5
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +0 -14
- data/vendor/faiss/faiss/utils/distances_fused/rvv.cpp +25 -0
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +0 -4
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based_neon.cpp +0 -4
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_kernel-inl.h +2 -1
- data/vendor/faiss/faiss/utils/distances_simd.cpp +9 -0
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +4 -0
- data/vendor/faiss/faiss/utils/fp16-inl.h +26 -52
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +0 -4
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512.cpp +0 -4
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_vpopcnt.cpp +0 -4
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +33 -5
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_vpopcnt.h +15 -30
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-neon.h +0 -4
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +2 -1
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_neon.cpp +0 -4
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_rvv.cpp +0 -4
- data/vendor/faiss/faiss/utils/pq_code_distance.h +8 -4
- data/vendor/faiss/faiss/utils/prefetch.h +1 -26
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +26 -27
- data/vendor/faiss/faiss/utils/quantize_lut.h +11 -0
- data/vendor/faiss/faiss/utils/rabitq_simd.h +51 -16
- data/vendor/faiss/faiss/utils/simd_impl/distances_aarch64.cpp +9 -4
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +37 -5
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +64 -5
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +64 -5
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +353 -71
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv_kernel.h +68 -0
- data/vendor/faiss/faiss/utils/simd_impl/exhaustive_L2sqr_blas_cmax.h +93 -0
- data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels.h +76 -0
- data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_avx2.cpp +52 -0
- data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_avx512.cpp +52 -0
- data/vendor/faiss/faiss/utils/simd_impl/fp16_kernels_neon.cpp +48 -0
- data/vendor/faiss/faiss/utils/simd_impl/masked_sum-avx2.h +44 -0
- data/vendor/faiss/faiss/utils/simd_impl/masked_sum-avx512.h +43 -0
- data/vendor/faiss/faiss/utils/simd_impl/masked_sum.h +38 -0
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_avx2.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_neon.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +54 -15
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +38 -21
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_vpopcnt.cpp +51 -14
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +297 -10
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx2.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_avx512.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_sve.cpp +0 -4
- data/vendor/faiss/faiss/utils/simd_levels.cpp +19 -3
- data/vendor/faiss/faiss/utils/simd_levels.h +74 -1
- data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +0 -4
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +0 -4
- data/vendor/faiss/faiss/utils/utils.cpp +80 -0
- data/vendor/faiss/faiss/utils/utils.h +24 -0
- metadata +33 -1
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <cstddef>
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <vector>
|
|
13
|
+
|
|
14
|
+
#include <faiss/MetricType.h>
|
|
15
|
+
#include <faiss/impl/maybe_owned_vector.h>
|
|
16
|
+
|
|
17
|
+
namespace faiss {
|
|
18
|
+
|
|
19
|
+
struct DistanceComputer;
|
|
20
|
+
struct IDSelector;
|
|
21
|
+
struct Index;
|
|
22
|
+
struct PiPNN;
|
|
23
|
+
struct VisitedTable;
|
|
24
|
+
|
|
25
|
+
namespace pipnn {
|
|
26
|
+
|
|
27
|
+
// Internal build pieces, exposed for tests; hidden from SWIG.
|
|
28
|
+
#ifndef SWIG
|
|
29
|
+
|
|
30
|
+
/// Points per medoid block. It fixes the summation order of the mean, so
|
|
31
|
+
/// changing it changes the entry point.
|
|
32
|
+
constexpr size_t kMedoidBlock = size_t(1) << 16;
|
|
33
|
+
|
|
34
|
+
/// Throws unless every vector is finite with squared norm <= FLT_MAX / 8, and
|
|
35
|
+
/// returns the L2 medoid: the point closest to the mean, lowest id on ties.
|
|
36
|
+
int32_t medoid_and_validate(const Index& storage, float* norm_cv = nullptr);
|
|
37
|
+
|
|
38
|
+
/// RobustPrune of x (row 0 of the m x m D) over cand[t] (row 1 + t) in
|
|
39
|
+
/// (D, id) order; writes <= R ids to out, -1 padded. order: m - 1 ints.
|
|
40
|
+
void robust_prune(
|
|
41
|
+
const float* D,
|
|
42
|
+
size_t m,
|
|
43
|
+
const int32_t* cand,
|
|
44
|
+
MetricType metric,
|
|
45
|
+
float alpha,
|
|
46
|
+
int R,
|
|
47
|
+
int* order,
|
|
48
|
+
int32_t* out);
|
|
49
|
+
|
|
50
|
+
namespace detail {
|
|
51
|
+
|
|
52
|
+
/// PiPNN::build with a given reservoir chunk size, for tests.
|
|
53
|
+
void build_with_chunk(
|
|
54
|
+
PiPNN& p,
|
|
55
|
+
const Index& storage,
|
|
56
|
+
size_t reservoir_chunk,
|
|
57
|
+
bool verbose);
|
|
58
|
+
|
|
59
|
+
} // namespace detail
|
|
60
|
+
|
|
61
|
+
#endif // SWIG
|
|
62
|
+
|
|
63
|
+
} // namespace pipnn
|
|
64
|
+
|
|
65
|
+
/// PiPNN graph (Rubel et al., KDD '26, arXiv:2602.21247).
|
|
66
|
+
struct PiPNN {
|
|
67
|
+
// build parameters
|
|
68
|
+
int R = 64; ///< max out-degree
|
|
69
|
+
int leaf_k = 2; ///< neighbours each point offers per leaf
|
|
70
|
+
int hash_bits = 12; ///< HashPrune keeps one candidate per hash bucket
|
|
71
|
+
int reservoir_size = 64; ///< candidates kept per point
|
|
72
|
+
int c_max = 1024; ///< largest leaf
|
|
73
|
+
int c_min = 128; ///< smaller partition children are merged
|
|
74
|
+
int leader_cap = 1000; ///< most leaders per split
|
|
75
|
+
float leader_fraction = 0.005f; ///< leaders per split, fraction of its size
|
|
76
|
+
float alpha = 0; ///< 0 = 1.2
|
|
77
|
+
std::vector<int> fanout = {10, 3}; ///< leaders joined per depth, then 1
|
|
78
|
+
int64_t seed = 1234;
|
|
79
|
+
/// IP: rank partition leaders by angle, not inner product
|
|
80
|
+
bool ip_partition_by_angle = false;
|
|
81
|
+
/// point instances per partition wave, which bounds memory
|
|
82
|
+
size_t partition_wave_budget = size_t(1) << 30;
|
|
83
|
+
|
|
84
|
+
int search_L = 64; ///< default beam width of search
|
|
85
|
+
|
|
86
|
+
// result
|
|
87
|
+
MaybeOwnedVector<int32_t> graph; ///< ntotal x R, -1 padded
|
|
88
|
+
/// next higher row with the same code, or -1; empty if all codes differ.
|
|
89
|
+
/// Such copies have empty graph rows; search returns them with the first.
|
|
90
|
+
MaybeOwnedVector<int32_t> next_copy;
|
|
91
|
+
int32_t entry_point = -1; ///< L2 medoid
|
|
92
|
+
idx_t ntotal = 0;
|
|
93
|
+
|
|
94
|
+
PiPNN() = default;
|
|
95
|
+
explicit PiPNN(int R) : R(R) {}
|
|
96
|
+
|
|
97
|
+
float effective_alpha(MetricType metric) const;
|
|
98
|
+
|
|
99
|
+
void check_params() const;
|
|
100
|
+
|
|
101
|
+
#ifndef SWIG
|
|
102
|
+
/// Builds over the vectors and metric of storage. Strong guarantee: the
|
|
103
|
+
/// results are unchanged if it throws.
|
|
104
|
+
void build(const Index& storage, bool verbose = false);
|
|
105
|
+
|
|
106
|
+
/// Beam max(L, k); qdis smaller-is-better; vt: ntotal slots, clean in/out.
|
|
107
|
+
/// Writes the k nearest in sel by (dis, id), padded; sel does not prune.
|
|
108
|
+
void search(
|
|
109
|
+
DistanceComputer& qdis,
|
|
110
|
+
int L,
|
|
111
|
+
idx_t k,
|
|
112
|
+
idx_t* I,
|
|
113
|
+
float* D,
|
|
114
|
+
VisitedTable& vt,
|
|
115
|
+
const IDSelector* sel) const;
|
|
116
|
+
#endif
|
|
117
|
+
|
|
118
|
+
/// Empties the graph; entry_point = -1, ntotal = 0.
|
|
119
|
+
void reset();
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
} // namespace faiss
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/impl/ProductQuantizer.h>
|
|
11
11
|
|
|
12
|
+
#include <omp.h>
|
|
13
|
+
#include <atomic>
|
|
12
14
|
#include <cstddef>
|
|
13
15
|
#include <cstdio>
|
|
14
16
|
#include <cstring>
|
|
@@ -16,10 +18,12 @@
|
|
|
16
18
|
#include <type_traits>
|
|
17
19
|
|
|
18
20
|
#include <algorithm>
|
|
21
|
+
#include <atomic>
|
|
19
22
|
|
|
20
23
|
#include <faiss/IndexFlat.h>
|
|
21
24
|
#include <faiss/VectorTransform.h>
|
|
22
25
|
#include <faiss/impl/FaissAssert.h>
|
|
26
|
+
#include <faiss/impl/FaissException.h>
|
|
23
27
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
28
|
#include <faiss/impl/pq_code_distance/pq_code_distance-inl.h>
|
|
25
29
|
#include <faiss/impl/simd_dispatch.h>
|
|
@@ -141,8 +145,8 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
141
145
|
}
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
const auto train_slice = [&](size_t m) {
|
|
149
|
+
std::unique_ptr<float[]> xslice(new float[n * dsub]);
|
|
146
150
|
for (size_t j = 0; j < n; j++)
|
|
147
151
|
memcpy(xslice.get() + j * dsub,
|
|
148
152
|
x + j * d + m * dsub,
|
|
@@ -150,7 +154,6 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
150
154
|
|
|
151
155
|
Clustering clus(dsub, ksub, cp);
|
|
152
156
|
|
|
153
|
-
// we have some initialization for the centroids
|
|
154
157
|
if (final_train_type != Train_default) {
|
|
155
158
|
clus.centroids.resize(dsub * ksub);
|
|
156
159
|
}
|
|
@@ -187,6 +190,28 @@ void ProductQuantizer::train(size_t n, const float* x) {
|
|
|
187
190
|
IndexFlatL2 index(dsub);
|
|
188
191
|
clus.train(n, xslice.get(), assign_index ? *assign_index : index);
|
|
189
192
|
set_params(clus.centroids.data(), m);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
if (!assign_index && x != centroids.data() && M > 1 &&
|
|
196
|
+
M * 8 >= static_cast<size_t>(omp_get_max_threads())) {
|
|
197
|
+
std::exception_ptr ex;
|
|
198
|
+
std::atomic<bool> failed{false};
|
|
199
|
+
#pragma omp parallel for
|
|
200
|
+
for (int64_t m = 0; m < static_cast<int64_t>(M); m++) {
|
|
201
|
+
if (failed) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
train_slice(m);
|
|
206
|
+
} catch (...) {
|
|
207
|
+
omp_capture_exception(ex, [&] { failed = true; });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
omp_rethrow_if_exception(ex);
|
|
211
|
+
} else {
|
|
212
|
+
for (size_t m = 0; m < M; m++) {
|
|
213
|
+
train_slice(m);
|
|
214
|
+
}
|
|
190
215
|
}
|
|
191
216
|
|
|
192
217
|
} else {
|
|
@@ -422,10 +447,21 @@ void ProductQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
|
422
447
|
|
|
423
448
|
int64_t n_signed = n;
|
|
424
449
|
if (dsub < 16) { // simple direct computation
|
|
450
|
+
std::exception_ptr ex;
|
|
451
|
+
std::atomic<bool> interrupt{false};
|
|
425
452
|
|
|
426
453
|
#pragma omp parallel for
|
|
427
|
-
for (int64_t i = 0; i < n_signed; i++)
|
|
428
|
-
|
|
454
|
+
for (int64_t i = 0; i < n_signed; i++) {
|
|
455
|
+
if (interrupt.load(std::memory_order_relaxed)) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
compute_code(x + i * d, codes + i * code_size);
|
|
460
|
+
} catch (...) {
|
|
461
|
+
omp_capture_exception(ex, [&] { interrupt = true; });
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
omp_rethrow_if_exception(ex);
|
|
429
465
|
|
|
430
466
|
} else { // worthwhile to use BLAS
|
|
431
467
|
std::unique_ptr<float[]> dis_tables(new float[n * ksub * M]);
|
|
@@ -489,8 +525,12 @@ void ProductQuantizer::compute_distance_tables(
|
|
|
489
525
|
const float* x,
|
|
490
526
|
float* dis_tables) const {
|
|
491
527
|
int64_t nx_signed = nx;
|
|
492
|
-
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON)
|
|
493
|
-
|
|
528
|
+
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON) || \
|
|
529
|
+
defined(COMPILE_SIMD_RISCV_RVV)
|
|
530
|
+
// The dsub2 kernels help for a narrow range of settings. They require
|
|
531
|
+
// ksub = 1 << nbits to be a multiple of 8. Therefore nbits must be 3 or
|
|
532
|
+
// more.
|
|
533
|
+
if (dsub == 2 && nbits >= 3 && nbits < 8) {
|
|
494
534
|
compute_PQ_dis_tables_dsub2(
|
|
495
535
|
d, ksub, centroids.data(), nx, x, false, dis_tables);
|
|
496
536
|
} else
|
|
@@ -524,8 +564,9 @@ void ProductQuantizer::compute_inner_prod_tables(
|
|
|
524
564
|
const float* x,
|
|
525
565
|
float* dis_tables) const {
|
|
526
566
|
int64_t nx_signed = nx;
|
|
527
|
-
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON)
|
|
528
|
-
|
|
567
|
+
#if defined(COMPILE_SIMD_AVX2) || defined(COMPILE_SIMD_ARM_NEON) || \
|
|
568
|
+
defined(COMPILE_SIMD_RISCV_RVV)
|
|
569
|
+
if (dsub == 2 && nbits >= 3 && nbits < 8) {
|
|
529
570
|
compute_PQ_dis_tables_dsub2(
|
|
530
571
|
d, ksub, centroids.data(), nx, x, true, dis_tables);
|
|
531
572
|
} else
|
|
@@ -872,8 +913,9 @@ void ProductQuantizer::search_sdc(
|
|
|
872
913
|
float* heap_dis = res->val + i * k;
|
|
873
914
|
const uint8_t* qcode = qcodes + i * code_size;
|
|
874
915
|
|
|
875
|
-
if (init_finalize_heap)
|
|
916
|
+
if (init_finalize_heap) {
|
|
876
917
|
maxheap_heapify(k, heap_dis, heap_ids);
|
|
918
|
+
}
|
|
877
919
|
|
|
878
920
|
// Precompute per-subquantizer row pointers: q_row[m] points to
|
|
879
921
|
// sdc_table[m*ksub^2 + qcode[m]*ksub], eliminating M
|
|
@@ -897,8 +939,9 @@ void ProductQuantizer::search_sdc(
|
|
|
897
939
|
bcode += code_size;
|
|
898
940
|
}
|
|
899
941
|
|
|
900
|
-
if (init_finalize_heap)
|
|
942
|
+
if (init_finalize_heap) {
|
|
901
943
|
maxheap_reorder(k, heap_dis, heap_ids);
|
|
944
|
+
}
|
|
902
945
|
}
|
|
903
946
|
}
|
|
904
947
|
}
|
|
@@ -353,7 +353,7 @@ inline int extract_code_inline(
|
|
|
353
353
|
* The multi-bit distance combines the sign bit (1-bit) with additional
|
|
354
354
|
* magnitude bits (ex_bits) to compute a more accurate distance estimate.
|
|
355
355
|
* Uses SIMD-optimized bit-plane decomposition (AVX2+BMI2) for ex_bits 1-7,
|
|
356
|
-
* with scalar fallback for non-x86
|
|
356
|
+
* with scalar fallback for non-x86 platforms.
|
|
357
357
|
*
|
|
358
358
|
* @param sign_bits unpacked sign bits (1-bit codes in standard format)
|
|
359
359
|
* @param ex_code packed ex-bit codes
|
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#include <faiss/impl/RaBitQuantizer.h>
|
|
9
|
+
#include <faiss/utils/prefetch.h>
|
|
9
10
|
|
|
10
11
|
#include <faiss/impl/FaissAssert.h>
|
|
11
12
|
#include <faiss/impl/IDSelector.h>
|
|
12
13
|
#include <faiss/impl/RaBitQUtils.h>
|
|
13
14
|
#include <faiss/impl/RaBitQuantizerMultiBit.h>
|
|
14
15
|
#include <faiss/impl/ResultHandler.h>
|
|
16
|
+
#include <faiss/impl/platform_macros.h>
|
|
15
17
|
#include <faiss/impl/simd_dispatch.h>
|
|
16
18
|
#include <faiss/invlists/DirectMap.h>
|
|
17
19
|
#include <faiss/utils/distances.h>
|
|
@@ -27,6 +29,11 @@ namespace faiss {
|
|
|
27
29
|
|
|
28
30
|
RaBitQStats rabitq_stats;
|
|
29
31
|
|
|
32
|
+
void RaBitQStats::add_atomic(const RaBitQStats& other) {
|
|
33
|
+
detail::atomic_fetch_add_relaxed(n_1bit, other.n_1bit);
|
|
34
|
+
detail::atomic_fetch_add_relaxed(n_refine, other.n_refine);
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
// Import shared utilities from RaBitQUtils
|
|
31
38
|
using rabitq_utils::ExtraBitsFactors;
|
|
32
39
|
using rabitq_utils::QueryFactorsData;
|
|
@@ -296,27 +303,10 @@ struct RaBitQDistanceComputerNotQ final : RaBitQDistanceComputer {
|
|
|
296
303
|
float distance_to_code_1bit_impl(
|
|
297
304
|
const uint8_t* binary_data,
|
|
298
305
|
const SignBitFactors* base_fac) const {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
// compute <q,o> using floats
|
|
302
|
-
float dot_qo = 0;
|
|
303
|
-
// It was a willful decision (after the discussion) to not to pre-cache
|
|
304
|
-
// the sum of all bits, just in order to reduce the overhead per
|
|
305
|
-
// vector.
|
|
306
|
-
uint64_t sum_q = 0;
|
|
307
|
-
|
|
308
|
-
for (size_t i = 0; i < d; i++) {
|
|
309
|
-
// Extract i-th bit
|
|
310
|
-
bool bit = rabitq_utils::extract_bit_standard(binary_data, i);
|
|
311
|
-
// accumulate dp
|
|
312
|
-
dot_qo += bit ? rotated_q[i] : 0;
|
|
313
|
-
// accumulate sum-of-bits
|
|
314
|
-
sum_q += bit ? 1 : 0;
|
|
315
|
-
}
|
|
306
|
+
const float dot_qo = fvec_masked_sum<simd512_level_selector<SL>::value>(
|
|
307
|
+
rotated_q.data(), binary_data, d);
|
|
316
308
|
|
|
317
|
-
|
|
318
|
-
float final_dot =
|
|
319
|
-
query_fac.c1 * dot_qo + query_fac.c2 * sum_q - query_fac.c34;
|
|
309
|
+
float final_dot = query_fac.c1 * dot_qo - query_fac.c34;
|
|
320
310
|
|
|
321
311
|
// pre_dist = ||or - c||^2 + ||qr - c||^2 -
|
|
322
312
|
// 2 * ||or - c|| * ||qr - c|| * <q,o> - (IP ? ||or||^2 : 0)
|
|
@@ -418,7 +408,6 @@ struct RaBitQDistanceComputerNotQ final : RaBitQDistanceComputer {
|
|
|
418
408
|
}
|
|
419
409
|
|
|
420
410
|
query_fac.c1 = 2 * inv_d;
|
|
421
|
-
query_fac.c2 = 0;
|
|
422
411
|
query_fac.c34 = sum_q * inv_d;
|
|
423
412
|
|
|
424
413
|
if (metric_type == MetricType::METRIC_INNER_PRODUCT) {
|
|
@@ -475,7 +464,9 @@ struct RaBitQDistanceComputerNotQ final : RaBitQDistanceComputer {
|
|
|
475
464
|
const float dis = distance_to_code_full(codes);
|
|
476
465
|
idx_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
477
466
|
|
|
478
|
-
if (
|
|
467
|
+
if ((keep_max ? dis > handler.threshold
|
|
468
|
+
: dis < handler.threshold) &&
|
|
469
|
+
handler.add_result(dis, id)) {
|
|
479
470
|
handler.stats.nheap_updates++;
|
|
480
471
|
nup++;
|
|
481
472
|
}
|
|
@@ -520,8 +511,6 @@ struct RaBitQDistanceComputerQ final : RaBitQDistanceComputer {
|
|
|
520
511
|
float final_dot = 0;
|
|
521
512
|
if (centered) {
|
|
522
513
|
int64_t int_dot = ((1 << qb) - 1) * d;
|
|
523
|
-
// See RaBitDistanceComputerNotQ::distance_to_code() for
|
|
524
|
-
// baseline code.
|
|
525
514
|
int_dot -= 2 *
|
|
526
515
|
rabitq::bitwise_xor_dot_product<SL>(
|
|
527
516
|
rearranged_rotated_qq.data(),
|
|
@@ -572,6 +561,42 @@ struct RaBitQDistanceComputerQ final : RaBitQDistanceComputer {
|
|
|
572
561
|
return distance_to_code_1bit_impl(code, base_fac, size);
|
|
573
562
|
}
|
|
574
563
|
|
|
564
|
+
void distance_to_code_1bit_batch_4(
|
|
565
|
+
const uint8_t* const* codes_in,
|
|
566
|
+
float* distances) final {
|
|
567
|
+
if (qb != 4 || centered) {
|
|
568
|
+
RaBitQDistanceComputer::distance_to_code_1bit_batch_4(
|
|
569
|
+
codes_in, distances);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
const size_t size = (d + 7) / 8;
|
|
573
|
+
const size_t prefix = size +
|
|
574
|
+
(nb_bits == 1 ? sizeof(SignBitFactors)
|
|
575
|
+
: sizeof(SignBitFactorsWithError));
|
|
576
|
+
for (int i = 0; i < 4; ++i) {
|
|
577
|
+
for (size_t offset = 0; offset < prefix; offset += 64) {
|
|
578
|
+
prefetch_L1(codes_in[i] + offset);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
rabitq::BitwiseAndDotProductResult results[4];
|
|
582
|
+
rabitq::bitwise_q4_batch_4<SL>(
|
|
583
|
+
rearranged_rotated_qq.data(), codes_in, size, results);
|
|
584
|
+
for (int i = 0; i < 4; ++i) {
|
|
585
|
+
const auto* factors =
|
|
586
|
+
reinterpret_cast<const SignBitFactors*>(codes_in[i] + size);
|
|
587
|
+
float final_dot = 0;
|
|
588
|
+
final_dot += query_fac.c1 * results[i].dot_product;
|
|
589
|
+
final_dot += query_fac.c2 * results[i].popcount;
|
|
590
|
+
final_dot -= query_fac.c34;
|
|
591
|
+
const float pre_dist = factors->or_minus_c_l2sqr +
|
|
592
|
+
query_fac.qr_to_c_L2sqr -
|
|
593
|
+
2 * factors->dp_multiplier * final_dot;
|
|
594
|
+
distances[i] = metric_type == METRIC_L2
|
|
595
|
+
? std::max(0.0f, pre_dist)
|
|
596
|
+
: -0.5f * (pre_dist - query_fac.qr_norm_L2sqr);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
575
600
|
// Compute full distance using 1-bit + ex-bits (accurate)
|
|
576
601
|
float distance_to_code_full(const uint8_t* code) final {
|
|
577
602
|
FAISS_ASSERT(code != nullptr);
|
|
@@ -660,51 +685,50 @@ struct RaBitQDistanceComputerQ final : RaBitQDistanceComputer {
|
|
|
660
685
|
bool keep_max,
|
|
661
686
|
ResultHandler& handler) final {
|
|
662
687
|
const size_t code_size_base = (d + 7) / 8;
|
|
663
|
-
const size_t ex_bits = nb_bits - 1;
|
|
664
|
-
FAISS_ASSERT(ex_bits > 0);
|
|
665
688
|
|
|
666
|
-
// Honor IDSelectorWithContext on the multibit path too, so a RaBitQ
|
|
667
|
-
// index does not silently lose the context hook once nb_bits >= 2 (the
|
|
668
|
-
// 1-bit path already routes through run_scan_codes1).
|
|
669
689
|
const IDSelectorContextDispatch sel_dispatch(sel, store_pairs);
|
|
670
690
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
691
|
+
auto scan = [&](auto multibit) {
|
|
692
|
+
size_t nup = 0;
|
|
693
|
+
for (size_t j = 0; j < list_size; j++, codes += code_size) {
|
|
694
|
+
if (sel != nullptr) {
|
|
695
|
+
idx_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
696
|
+
if (!sel_dispatch.is_member(
|
|
697
|
+
id, IDScanContext{ids, list_size, j})) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
679
700
|
}
|
|
680
|
-
}
|
|
681
701
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
702
|
+
const auto* base_fac =
|
|
703
|
+
reinterpret_cast<const SignBitFactorsWithError*>(
|
|
704
|
+
codes + code_size_base);
|
|
705
|
+
float dis = distance_to_code_1bit_impl(
|
|
706
|
+
codes, base_fac, code_size_base);
|
|
707
|
+
|
|
708
|
+
if constexpr (decltype(multibit)::value) {
|
|
709
|
+
if (!rabitq_utils::should_refine_candidate(
|
|
710
|
+
dis,
|
|
711
|
+
base_fac->f_error,
|
|
712
|
+
g_error,
|
|
713
|
+
handler.threshold,
|
|
714
|
+
keep_max)) {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
dis = distance_to_code_full(codes);
|
|
718
|
+
}
|
|
695
719
|
handler.stats.scan_cnt++;
|
|
696
|
-
const float dis = distance_to_code_full(codes);
|
|
697
720
|
idx_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
698
721
|
|
|
699
|
-
if (
|
|
722
|
+
if ((keep_max ? dis > handler.threshold
|
|
723
|
+
: dis < handler.threshold) &&
|
|
724
|
+
handler.add_result(dis, id)) {
|
|
700
725
|
handler.stats.nheap_updates++;
|
|
701
726
|
nup++;
|
|
702
727
|
}
|
|
703
728
|
}
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
return nup;
|
|
729
|
+
return nup;
|
|
730
|
+
};
|
|
731
|
+
return nb_bits == 1 ? scan(std::false_type{}) : scan(std::true_type{});
|
|
708
732
|
}
|
|
709
733
|
};
|
|
710
734
|
|
|
@@ -40,6 +40,8 @@ struct RaBitQStats {
|
|
|
40
40
|
n_refine += other.n_refine;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
void add_atomic(const RaBitQStats& other);
|
|
44
|
+
|
|
43
45
|
double refine_ratio() const {
|
|
44
46
|
return n_1bit ? double(n_refine) / double(n_1bit) : 0.0;
|
|
45
47
|
}
|
|
@@ -157,6 +159,19 @@ struct RaBitQDistanceComputer : FlatCodesDistanceComputer {
|
|
|
157
159
|
// Compute 1-bit distance estimate (fast)
|
|
158
160
|
virtual float distance_to_code_1bit(const uint8_t* code) = 0;
|
|
159
161
|
|
|
162
|
+
/// Compute four one-bit estimates in input order. Caller must call
|
|
163
|
+
/// set_query() first. Each pointer addresses one complete encoded row; rows
|
|
164
|
+
/// need not be contiguous or distinct. The output holds four floats.
|
|
165
|
+
/// Does not refine candidates, update thresholds, or increment stats. The
|
|
166
|
+
/// default calls the single estimate four times.
|
|
167
|
+
virtual void distance_to_code_1bit_batch_4(
|
|
168
|
+
const uint8_t* const* codes_in,
|
|
169
|
+
float* distances) {
|
|
170
|
+
for (size_t i = 0; i < 4; ++i) {
|
|
171
|
+
distances[i] = distance_to_code_1bit(codes_in[i]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
160
175
|
// Compute full multi-bit distance (accurate)
|
|
161
176
|
virtual float distance_to_code_full(const uint8_t* code) = 0;
|
|
162
177
|
|
|
@@ -453,6 +453,35 @@ float unit_norm_component_scale(size_t d) {
|
|
|
453
453
|
|
|
454
454
|
} // namespace
|
|
455
455
|
|
|
456
|
+
void ScalarQuantizer::SQDistanceComputer::query_to_codes_batch_4(
|
|
457
|
+
const uint8_t* code_0,
|
|
458
|
+
const uint8_t* code_1,
|
|
459
|
+
const uint8_t* code_2,
|
|
460
|
+
const uint8_t* code_3,
|
|
461
|
+
float& dis0,
|
|
462
|
+
float& dis1,
|
|
463
|
+
float& dis2,
|
|
464
|
+
float& dis3) const {
|
|
465
|
+
dis0 = query_to_code(code_0);
|
|
466
|
+
dis1 = query_to_code(code_1);
|
|
467
|
+
dis2 = query_to_code(code_2);
|
|
468
|
+
dis3 = query_to_code(code_3);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
namespace scalar_quantizer {
|
|
472
|
+
|
|
473
|
+
void IVFCoarseDistanceScanner::set_list(idx_t list_no_in, float coarse_dis_in) {
|
|
474
|
+
this->list_no = list_no_in;
|
|
475
|
+
this->coarse_dis = coarse_dis_in;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
float IVFCoarseDistanceScanner::distance_to_code(
|
|
479
|
+
const uint8_t* /*code*/) const {
|
|
480
|
+
return coarse_dis;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
} // namespace scalar_quantizer
|
|
484
|
+
|
|
456
485
|
/*******************************************************************
|
|
457
486
|
* ScalarQuantizer implementation
|
|
458
487
|
********************************************************************/
|
|
@@ -133,12 +133,7 @@ struct ScalarQuantizer : Quantizer {
|
|
|
133
133
|
float& dis0,
|
|
134
134
|
float& dis1,
|
|
135
135
|
float& dis2,
|
|
136
|
-
float& dis3) const
|
|
137
|
-
dis0 = query_to_code(code_0);
|
|
138
|
-
dis1 = query_to_code(code_1);
|
|
139
|
-
dis2 = query_to_code(code_2);
|
|
140
|
-
dis3 = query_to_code(code_3);
|
|
141
|
-
}
|
|
136
|
+
float& dis3) const;
|
|
142
137
|
|
|
143
138
|
float distance_to_code(const uint8_t* code) final {
|
|
144
139
|
return query_to_code(code);
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
// Explicit template instantiations of HeapWithBucketsCMaxFloat and
|
|
9
9
|
// accum_and_*_tab for SIMDLevel::AVX2.
|
|
10
10
|
|
|
11
|
-
#ifdef COMPILE_SIMD_AVX2
|
|
12
|
-
|
|
13
11
|
#include <faiss/impl/approx_topk/rq_beam_search_tab-inl.h>
|
|
14
12
|
#include <faiss/impl/approx_topk/simdlib256-inl.h>
|
|
15
13
|
#include <faiss/impl/simdlib/simdlib_avx2.h>
|
|
@@ -64,5 +62,3 @@ INSTANTIATE_ACCUM_TAB(8)
|
|
|
64
62
|
#undef INSTANTIATE_ACCUM_TAB
|
|
65
63
|
|
|
66
64
|
} // namespace faiss
|
|
67
|
-
|
|
68
|
-
#endif // COMPILE_SIMD_AVX2
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
// Explicit template instantiations of HeapWithBucketsCMaxFloat and
|
|
9
9
|
// accum_and_*_tab for SIMDLevel::ARM_NEON.
|
|
10
10
|
|
|
11
|
-
#ifdef COMPILE_SIMD_ARM_NEON
|
|
12
|
-
|
|
13
11
|
#include <faiss/impl/approx_topk/rq_beam_search_tab-inl.h>
|
|
14
12
|
#include <faiss/impl/approx_topk/simdlib256-inl.h>
|
|
15
13
|
#include <faiss/impl/simdlib/simdlib_neon.h>
|
|
@@ -64,5 +62,3 @@ INSTANTIATE_ACCUM_TAB(8)
|
|
|
64
62
|
#undef INSTANTIATE_ACCUM_TAB
|
|
65
63
|
|
|
66
64
|
} // namespace faiss
|
|
67
|
-
|
|
68
|
-
#endif // COMPILE_SIMD_ARM_NEON
|
|
@@ -139,11 +139,14 @@ void search_single_query_template(
|
|
|
139
139
|
} while (fe.next());
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
// A hash type with internal linkage makes the functions of the set local.
|
|
143
|
+
struct ShortlistHash : std::hash<idx_t> {};
|
|
144
|
+
|
|
142
145
|
template <class HammingComputer, class SearchResults>
|
|
143
146
|
static void verify_shortlist(
|
|
144
147
|
const IndexBinaryFlat* index,
|
|
145
148
|
const uint8_t* q,
|
|
146
|
-
const std::unordered_set<idx_t>& shortlist,
|
|
149
|
+
const std::unordered_set<idx_t, ShortlistHash>& shortlist,
|
|
147
150
|
SearchResults& res) {
|
|
148
151
|
size_t code_size = index->code_size;
|
|
149
152
|
|
|
@@ -164,7 +167,7 @@ void search_1_query_multihash(
|
|
|
164
167
|
size_t& n0,
|
|
165
168
|
size_t& nlist,
|
|
166
169
|
size_t& ndis) {
|
|
167
|
-
std::unordered_set<idx_t> shortlist;
|
|
170
|
+
std::unordered_set<idx_t, ShortlistHash> shortlist;
|
|
168
171
|
int b = index.b;
|
|
169
172
|
|
|
170
173
|
BitstringReader br(xi, index.code_size);
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#ifdef COMPILE_SIMD_AVX2
|
|
9
|
-
|
|
10
8
|
#define THE_SIMD_LEVEL SIMDLevel::AVX2
|
|
11
9
|
|
|
12
10
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader,facebook-unused-include-check)
|
|
@@ -22,5 +20,3 @@
|
|
|
22
20
|
#include <faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h> // IWYU pragma: keep
|
|
23
21
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
22
|
#include <faiss/impl/binary_hamming/IndexPQ_impl.h>
|
|
25
|
-
|
|
26
|
-
#endif // COMPILE_SIMD_AVX2
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#ifdef COMPILE_SIMD_AVX512
|
|
9
|
-
|
|
10
8
|
#define THE_SIMD_LEVEL SIMDLevel::AVX512
|
|
11
9
|
|
|
12
10
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
@@ -22,5 +20,3 @@
|
|
|
22
20
|
#include <faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h>
|
|
23
21
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
22
|
#include <faiss/impl/binary_hamming/IndexPQ_impl.h>
|
|
25
|
-
|
|
26
|
-
#endif // COMPILE_SIMD_AVX512
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#ifdef COMPILE_SIMD_ARM_NEON
|
|
9
|
-
|
|
10
8
|
#define THE_SIMD_LEVEL SIMDLevel::ARM_NEON
|
|
11
9
|
|
|
12
10
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
@@ -22,5 +20,3 @@
|
|
|
22
20
|
#include <faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h>
|
|
23
21
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
22
|
#include <faiss/impl/binary_hamming/IndexPQ_impl.h>
|
|
25
|
-
|
|
26
|
-
#endif // COMPILE_SIMD_ARM_NEON
|