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
|
@@ -41,17 +41,7 @@ struct DistanceComputer {
|
|
|
41
41
|
float& dis0,
|
|
42
42
|
float& dis1,
|
|
43
43
|
float& dis2,
|
|
44
|
-
float& dis3)
|
|
45
|
-
// compute first, assign next
|
|
46
|
-
const float d0 = this->operator()(idx0);
|
|
47
|
-
const float d1 = this->operator()(idx1);
|
|
48
|
-
const float d2 = this->operator()(idx2);
|
|
49
|
-
const float d3 = this->operator()(idx3);
|
|
50
|
-
dis0 = d0;
|
|
51
|
-
dis1 = d1;
|
|
52
|
-
dis2 = d2;
|
|
53
|
-
dis3 = d3;
|
|
54
|
-
}
|
|
44
|
+
float& dis3);
|
|
55
45
|
|
|
56
46
|
/// compute distance between two stored vectors
|
|
57
47
|
virtual float symmetric_dis(idx_t i, idx_t j) = 0;
|
|
@@ -181,9 +171,7 @@ struct FlatCodesDistanceComputer : DistanceComputer {
|
|
|
181
171
|
virtual float partial_dot_product(
|
|
182
172
|
const idx_t /* i */,
|
|
183
173
|
const uint32_t /* offset */,
|
|
184
|
-
const uint32_t /* num_components */)
|
|
185
|
-
FAISS_THROW_MSG("partial_dot_product not implemented");
|
|
186
|
-
}
|
|
174
|
+
const uint32_t /* num_components */);
|
|
187
175
|
|
|
188
176
|
/// compute distance of current query to an encoded vector
|
|
189
177
|
virtual float distance_to_code(const uint8_t* code) = 0;
|
|
@@ -214,21 +202,7 @@ struct FlatCodesDistanceComputer : DistanceComputer {
|
|
|
214
202
|
float& dp2,
|
|
215
203
|
float& dp3,
|
|
216
204
|
const uint32_t offset,
|
|
217
|
-
const uint32_t num_components)
|
|
218
|
-
// default implementation for correctness
|
|
219
|
-
const float d0 =
|
|
220
|
-
this->partial_dot_product(idx0, offset, num_components);
|
|
221
|
-
const float d1 =
|
|
222
|
-
this->partial_dot_product(idx1, offset, num_components);
|
|
223
|
-
const float d2 =
|
|
224
|
-
this->partial_dot_product(idx2, offset, num_components);
|
|
225
|
-
const float d3 =
|
|
226
|
-
this->partial_dot_product(idx3, offset, num_components);
|
|
227
|
-
dp0 = d0;
|
|
228
|
-
dp1 = d1;
|
|
229
|
-
dp2 = d2;
|
|
230
|
-
dp3 = d3;
|
|
231
|
-
}
|
|
205
|
+
const uint32_t num_components);
|
|
232
206
|
|
|
233
207
|
virtual ~FlatCodesDistanceComputer() override {}
|
|
234
208
|
};
|
|
@@ -1568,6 +1568,8 @@ void reservePriorityQueue(
|
|
|
1568
1568
|
/// Templated body of `search_from_candidate_unbounded`. The choice of
|
|
1569
1569
|
/// max-heap vs min-heap for both `top_candidates` and `candidates` is
|
|
1570
1570
|
/// derived from C via `TopCandidatesQueue` / `CandidatesQueue`.
|
|
1571
|
+
/// `sel` filters the results only. The traversal still visits the rejected
|
|
1572
|
+
/// nodes.
|
|
1571
1573
|
template <typename VTType, class C>
|
|
1572
1574
|
TopCandidatesQueue<C> search_from_candidate_unbounded_fixVT(
|
|
1573
1575
|
const HNSW& hnsw,
|
|
@@ -1575,16 +1577,48 @@ TopCandidatesQueue<C> search_from_candidate_unbounded_fixVT(
|
|
|
1575
1577
|
DistanceComputer& qdis,
|
|
1576
1578
|
int ef,
|
|
1577
1579
|
VTType& vt,
|
|
1578
|
-
HNSWStats& stats
|
|
1580
|
+
HNSWStats& stats,
|
|
1581
|
+
const IDSelector* sel) {
|
|
1582
|
+
const auto max_size = static_cast<size_t>(ef);
|
|
1583
|
+
|
|
1579
1584
|
int ndis = 0;
|
|
1585
|
+
// `top_candidates` bounds the traversal and keeps the nodes that `sel`
|
|
1586
|
+
// rejects, because a rejected node is still a valid hop towards an
|
|
1587
|
+
// accepted one.
|
|
1580
1588
|
TopCandidatesQueue<C> top_candidates;
|
|
1581
1589
|
reservePriorityQueue(top_candidates, ef);
|
|
1582
1590
|
|
|
1591
|
+
// `selected_candidates` keeps only the accepted nodes, and
|
|
1592
|
+
// the function returns it instead when `sel` is set.
|
|
1593
|
+
TopCandidatesQueue<C> selected_candidates;
|
|
1594
|
+
if (sel) {
|
|
1595
|
+
reservePriorityQueue(selected_candidates, ef);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1583
1598
|
CandidatesQueue<C> candidates;
|
|
1584
1599
|
reservePriorityQueue(candidates, ef);
|
|
1585
1600
|
|
|
1601
|
+
// Adds a node to a queue of the best `max_size` nodes. The size test
|
|
1602
|
+
// comes first because `top()` needs a queue that is not empty.
|
|
1603
|
+
auto push_bounded = [max_size](
|
|
1604
|
+
TopCandidatesQueue<C>& queue,
|
|
1605
|
+
const float dis,
|
|
1606
|
+
const size_t idx) {
|
|
1607
|
+
if (queue.size() >= max_size && !C::cmp(queue.top().first, dis)) {
|
|
1608
|
+
return false;
|
|
1609
|
+
}
|
|
1610
|
+
queue.emplace(dis, idx);
|
|
1611
|
+
if (queue.size() > max_size) {
|
|
1612
|
+
queue.pop();
|
|
1613
|
+
}
|
|
1614
|
+
return true;
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1586
1617
|
top_candidates.push(node);
|
|
1587
1618
|
candidates.push(node);
|
|
1619
|
+
if (sel && sel->is_member(node.second)) {
|
|
1620
|
+
selected_candidates.push(node);
|
|
1621
|
+
}
|
|
1588
1622
|
|
|
1589
1623
|
vt.set(node.second);
|
|
1590
1624
|
|
|
@@ -1619,14 +1653,11 @@ TopCandidatesQueue<C> search_from_candidate_unbounded_fixVT(
|
|
|
1619
1653
|
size_t saved_j[4];
|
|
1620
1654
|
|
|
1621
1655
|
auto add_to_heap = [&](const size_t idx, const float dis) {
|
|
1622
|
-
if (
|
|
1623
|
-
|
|
1656
|
+
if (sel && sel->is_member(idx)) {
|
|
1657
|
+
push_bounded(selected_candidates, dis, idx);
|
|
1658
|
+
}
|
|
1659
|
+
if (push_bounded(top_candidates, dis, idx)) {
|
|
1624
1660
|
candidates.emplace(dis, idx);
|
|
1625
|
-
top_candidates.emplace(dis, idx);
|
|
1626
|
-
|
|
1627
|
-
if (top_candidates.size() > static_cast<size_t>(ef)) {
|
|
1628
|
-
top_candidates.pop();
|
|
1629
|
-
}
|
|
1630
1661
|
}
|
|
1631
1662
|
};
|
|
1632
1663
|
|
|
@@ -1674,6 +1705,9 @@ TopCandidatesQueue<C> search_from_candidate_unbounded_fixVT(
|
|
|
1674
1705
|
}
|
|
1675
1706
|
stats.ndis += ndis;
|
|
1676
1707
|
|
|
1708
|
+
if (sel) {
|
|
1709
|
+
return selected_candidates;
|
|
1710
|
+
}
|
|
1677
1711
|
return top_candidates;
|
|
1678
1712
|
}
|
|
1679
1713
|
|
|
@@ -1693,7 +1727,7 @@ std::priority_queue<HNSW::Node> hnsw_detail::search_from_candidate_unbounded(
|
|
|
1693
1727
|
using C = HNSW::C_distance;
|
|
1694
1728
|
auto call = [&]<typename VTType>(VTType& vt_concrete) {
|
|
1695
1729
|
return search_from_candidate_unbounded_fixVT<VTType, C>(
|
|
1696
|
-
hnsw, node, qdis, ef, vt_concrete, stats);
|
|
1730
|
+
hnsw, node, qdis, ef, vt_concrete, stats, nullptr);
|
|
1697
1731
|
};
|
|
1698
1732
|
if (VisitedTableVector* vtv = dynamic_cast<VisitedTableVector*>(vt)) {
|
|
1699
1733
|
return call(*vtv);
|
|
@@ -1792,6 +1826,7 @@ HNSWStats search_impl(
|
|
|
1792
1826
|
hnsw.search_method == HNSW::SM_DEFAULT ||
|
|
1793
1827
|
hnsw.search_method == HNSW::SM_PANORAMA,
|
|
1794
1828
|
"invalid HNSW search method");
|
|
1829
|
+
const IDSelector* sel = params ? params->sel : nullptr;
|
|
1795
1830
|
auto call = [&]<typename VTType>(VTType& vt_concrete) {
|
|
1796
1831
|
return search_from_candidate_unbounded_fixVT<VTType, C>(
|
|
1797
1832
|
hnsw,
|
|
@@ -1799,7 +1834,8 @@ HNSWStats search_impl(
|
|
|
1799
1834
|
qdis,
|
|
1800
1835
|
ef,
|
|
1801
1836
|
vt_concrete,
|
|
1802
|
-
stats
|
|
1837
|
+
stats,
|
|
1838
|
+
sel);
|
|
1803
1839
|
};
|
|
1804
1840
|
TopCandidatesQueue<C> top_candidates;
|
|
1805
1841
|
if (VisitedTableVector* vtv = dynamic_cast<VisitedTableVector*>(&vt)) {
|
|
@@ -296,6 +296,76 @@ void hnsw_add_vertices_deterministic(
|
|
|
296
296
|
const std::function<void(DistanceComputer&, HNSW::storage_idx_t)>&
|
|
297
297
|
set_query);
|
|
298
298
|
|
|
299
|
+
/// Parameters of add_level_0_links_from_sample() of IndexHNSW and
|
|
300
|
+
/// IndexBinaryHNSW.
|
|
301
|
+
struct HNSWLevel0LinkParameters {
|
|
302
|
+
/// The search that the new links are for. nullptr: the search settings
|
|
303
|
+
/// of the index, which the IVF assignment with a coarse quantizer uses.
|
|
304
|
+
const SearchParametersHNSW* search_params = nullptr;
|
|
305
|
+
/// A sink receives at least this factor times the mean number of
|
|
306
|
+
/// vectors per node.
|
|
307
|
+
float min_mean_factor = 3.0f;
|
|
308
|
+
/// For at least this fraction of the vectors that the search sends to a
|
|
309
|
+
/// sink, an exact search finds a nearer node.
|
|
310
|
+
float min_closer_fraction = 0.5f;
|
|
311
|
+
/// Maximum number of level-0 links added to one sink in one round.
|
|
312
|
+
int max_links_per_sink = 32;
|
|
313
|
+
/// Maximum number of rounds that find sinks and add links.
|
|
314
|
+
int max_rounds = 3;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
struct HNSWLevel0LinkStats {
|
|
318
|
+
/// Sinks found in the first round.
|
|
319
|
+
size_t n_sinks_found = 0;
|
|
320
|
+
/// Sinks found after the last round.
|
|
321
|
+
size_t n_sinks_remaining = 0;
|
|
322
|
+
/// Level-0 links written into free slots.
|
|
323
|
+
size_t n_links_added = 0;
|
|
324
|
+
/// Level-0 links that replaced a link.
|
|
325
|
+
size_t n_links_replaced = 0;
|
|
326
|
+
/// Rounds that changed links.
|
|
327
|
+
int n_rounds = 0;
|
|
328
|
+
/// Exact searches with the storage, in all rounds.
|
|
329
|
+
size_t n_exact_searches = 0;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
/** The two searches of the sample vectors that
|
|
333
|
+
* hnsw_add_level_0_links_from_sample() compares. IndexHNSW and IndexBinaryHNSW
|
|
334
|
+
* implement them for their vector types. */
|
|
335
|
+
struct HNSWLinkSampleSearch {
|
|
336
|
+
/// number of sample vectors
|
|
337
|
+
idx_t n = 0;
|
|
338
|
+
|
|
339
|
+
virtual ~HNSWLinkSampleSearch() = default;
|
|
340
|
+
|
|
341
|
+
/// HNSW search (k = 1) of the m sample vectors `ids` (null: the first m).
|
|
342
|
+
virtual void search(
|
|
343
|
+
const SearchParametersHNSW* params,
|
|
344
|
+
size_t m,
|
|
345
|
+
const idx_t* ids,
|
|
346
|
+
idx_t* labels) const = 0;
|
|
347
|
+
|
|
348
|
+
/** Exact search (k = 1) of the m sample vectors `ids`. nearer[j] is 1 when
|
|
349
|
+
* exact[j] is nearer than found[j] by more than rounding differences. */
|
|
350
|
+
virtual void search_exact(
|
|
351
|
+
size_t m,
|
|
352
|
+
const idx_t* ids,
|
|
353
|
+
const idx_t* found,
|
|
354
|
+
idx_t* exact,
|
|
355
|
+
uint8_t* nearer) const = 0;
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
/** add_level_0_links_from_sample() of IndexHNSW and IndexBinaryHNSW.
|
|
359
|
+
* `dis` computes distances between nodes. `similarity` is true when a larger
|
|
360
|
+
* distance is nearer. */
|
|
361
|
+
HNSWLevel0LinkStats hnsw_add_level_0_links_from_sample(
|
|
362
|
+
HNSW& hnsw,
|
|
363
|
+
size_t ntotal,
|
|
364
|
+
DistanceComputer& dis,
|
|
365
|
+
bool similarity,
|
|
366
|
+
const HNSWLinkSampleSearch& sample,
|
|
367
|
+
const HNSWLevel0LinkParameters& params);
|
|
368
|
+
|
|
299
369
|
struct HNSWStats {
|
|
300
370
|
size_t n1 = 0; /// number of vectors searched
|
|
301
371
|
size_t n2 =
|
|
@@ -315,6 +385,8 @@ struct HNSWStats {
|
|
|
315
385
|
ndis += other.ndis;
|
|
316
386
|
nhops += other.nhops;
|
|
317
387
|
}
|
|
388
|
+
|
|
389
|
+
void combine_atomic(const HNSWStats& other);
|
|
318
390
|
};
|
|
319
391
|
|
|
320
392
|
// global var that collects them all
|
|
@@ -23,12 +23,9 @@
|
|
|
23
23
|
#include <faiss/utils/utils.h>
|
|
24
24
|
|
|
25
25
|
#include <faiss/impl/approx_topk/approx_topk.h>
|
|
26
|
+
#include <faiss/impl/platform_macros.h>
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#ifdef COMPILE_SIMD_AVX2
|
|
30
|
-
#include <xmmintrin.h>
|
|
31
|
-
#endif
|
|
28
|
+
#include <faiss/utils/prefetch.h>
|
|
32
29
|
|
|
33
30
|
extern "C" {
|
|
34
31
|
// LU decomposition of a general matrix
|
|
@@ -602,7 +599,7 @@ void LocalSearchQuantizer::icm_encode_step(
|
|
|
602
599
|
|
|
603
600
|
// Resolve SIMD level once, not per iteration of the n × n_iters × M loop.
|
|
604
601
|
with_simd_level_256bit([&]<SIMDLevel SL>() {
|
|
605
|
-
#pragma omp parallel for schedule(
|
|
602
|
+
#pragma omp parallel for schedule(FAISS_OMP_DYNAMIC)
|
|
606
603
|
for (int64_t i = 0; i < static_cast<int64_t>(n); i++) {
|
|
607
604
|
std::vector<float> objs(K);
|
|
608
605
|
|
|
@@ -622,23 +619,13 @@ void LocalSearchQuantizer::icm_encode_step(
|
|
|
622
619
|
continue;
|
|
623
620
|
}
|
|
624
621
|
|
|
625
|
-
#ifdef COMPILE_SIMD_AVX2
|
|
626
|
-
// TODO: add platform-independent compiler-independent
|
|
627
|
-
// prefetch utilities.
|
|
628
622
|
if (other_m + 1 < M) {
|
|
629
623
|
// do a single prefetch
|
|
630
624
|
int32_t code2 = codes[i * M + other_m + 1];
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
size_t binary_idx = (other_m + 1) * M * K * K +
|
|
635
|
-
m * K * K + code2 * K + code;
|
|
636
|
-
_mm_prefetch(
|
|
637
|
-
(const char*)(binaries + binary_idx),
|
|
638
|
-
_MM_HINT_T0);
|
|
639
|
-
}
|
|
625
|
+
size_t binary_idx = (other_m + 1) * M * K * K +
|
|
626
|
+
m * K * K + code2 * K;
|
|
627
|
+
prefetch_L1(binaries + binary_idx);
|
|
640
628
|
}
|
|
641
|
-
#endif
|
|
642
629
|
|
|
643
630
|
for (size_t code = 0; code < K; code++) {
|
|
644
631
|
int32_t code2 = codes[i * M + other_m];
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
15
15
|
#include <faiss/impl/DistanceComputer.h>
|
|
16
16
|
#include <faiss/impl/VisitedTable.h>
|
|
17
|
+
#include <faiss/impl/platform_macros.h>
|
|
17
18
|
|
|
18
19
|
namespace faiss {
|
|
19
20
|
|
|
@@ -200,7 +201,7 @@ void NNDescent::join(DistanceComputer& qdis) {
|
|
|
200
201
|
idx_t check_period = InterruptCallback::get_period_hint(d * search_L);
|
|
201
202
|
for (idx_t i0 = 0; i0 < (idx_t)ntotal; i0 += check_period) {
|
|
202
203
|
idx_t i1 = std::min(i0 + check_period, (idx_t)ntotal);
|
|
203
|
-
#pragma omp parallel for default(shared) schedule(
|
|
204
|
+
#pragma omp parallel for default(shared) schedule(FAISS_OMP_DYNAMIC, 100)
|
|
204
205
|
for (idx_t n = i0; n < i1; n++) {
|
|
205
206
|
graph[n].join([&](int i, int j) {
|
|
206
207
|
if (i != j) {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
#include <faiss/impl/DistanceComputer.h>
|
|
17
17
|
#include <faiss/impl/VisitedTable.h>
|
|
18
|
+
#include <faiss/impl/platform_macros.h>
|
|
18
19
|
|
|
19
20
|
namespace faiss {
|
|
20
21
|
|
|
@@ -352,7 +353,7 @@ void NSG::link(
|
|
|
352
353
|
std::unique_ptr<DistanceComputer> dis(
|
|
353
354
|
storage_distance_computer(storage));
|
|
354
355
|
|
|
355
|
-
#pragma omp for schedule(
|
|
356
|
+
#pragma omp for schedule(FAISS_OMP_DYNAMIC, 100)
|
|
356
357
|
for (int i = 0; i < ntotal; i++) {
|
|
357
358
|
storage->reconstruct(i, vec.get());
|
|
358
359
|
dis->set_query(vec.get());
|
|
@@ -375,7 +376,7 @@ void NSG::link(
|
|
|
375
376
|
std::unique_ptr<DistanceComputer> dis(
|
|
376
377
|
storage_distance_computer(storage));
|
|
377
378
|
|
|
378
|
-
#pragma omp for schedule(
|
|
379
|
+
#pragma omp for schedule(FAISS_OMP_DYNAMIC, 100)
|
|
379
380
|
for (int i = 0; i < ntotal; ++i) {
|
|
380
381
|
add_reverse_links(i, locks, *dis, graph);
|
|
381
382
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <faiss/impl/IDSelector.h>
|
|
15
15
|
#include <faiss/impl/PanoramaStats.h>
|
|
16
16
|
#include <faiss/utils/distances.h>
|
|
17
|
+
#include <faiss/utils/simd_levels.h>
|
|
17
18
|
|
|
18
19
|
#include <algorithm>
|
|
19
20
|
#include <cstddef>
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
#include <cstring>
|
|
22
23
|
#include <vector>
|
|
23
24
|
|
|
24
|
-
#if
|
|
25
|
+
#if FAISS_SIMD_TU(AVX2) && defined(__BMI2__)
|
|
25
26
|
#include <immintrin.h>
|
|
26
27
|
#endif
|
|
27
28
|
|
|
@@ -154,7 +155,7 @@ inline size_t compact_active_kernel(
|
|
|
154
155
|
size_t next_active = 0;
|
|
155
156
|
size_t i = 0;
|
|
156
157
|
|
|
157
|
-
#if
|
|
158
|
+
#if FAISS_SIMD_TU(AVX2) && defined(__BMI2__)
|
|
158
159
|
for (; i + 8 <= num_active; i += 8) {
|
|
159
160
|
uint64_t bytes;
|
|
160
161
|
memcpy(&bytes, &active_byteset[i], 8);
|