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
|
@@ -13,11 +13,15 @@
|
|
|
13
13
|
#include <limits>
|
|
14
14
|
#include <random>
|
|
15
15
|
#include <unordered_set>
|
|
16
|
+
#include <utility>
|
|
16
17
|
#include <vector>
|
|
17
18
|
|
|
19
|
+
#include <faiss/impl/ClusteringHelpers.h>
|
|
18
20
|
#include <faiss/impl/FaissAssert.h>
|
|
21
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
19
22
|
#include <faiss/utils/distances_dispatch.h>
|
|
20
23
|
#include <faiss/utils/random.h>
|
|
24
|
+
#include <faiss/utils/simd_impl/fp16_kernels.h>
|
|
21
25
|
|
|
22
26
|
namespace faiss {
|
|
23
27
|
|
|
@@ -32,37 +36,90 @@ uint64_t get_seed(int64_t seed) {
|
|
|
32
36
|
.count());
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
struct FloatRows {
|
|
40
|
+
static constexpr bool needs_scratch = false;
|
|
41
|
+
static constexpr bool has_fixed_simd_level = false;
|
|
42
|
+
|
|
43
|
+
size_t d;
|
|
44
|
+
const float* x;
|
|
45
|
+
|
|
46
|
+
const float* row(size_t idx, float*) const {
|
|
47
|
+
return x + idx * d;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void copy_row(size_t idx, float* out) const {
|
|
51
|
+
std::memcpy(out, x + idx * d, d * sizeof(float));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
template <SIMDLevel SL>
|
|
56
|
+
struct Fp16Rows {
|
|
57
|
+
static constexpr bool needs_scratch = true;
|
|
58
|
+
static constexpr bool has_fixed_simd_level = true;
|
|
59
|
+
static constexpr SIMDLevel simd_level = SL;
|
|
60
|
+
|
|
61
|
+
size_t d;
|
|
62
|
+
const uint16_t* x;
|
|
63
|
+
|
|
64
|
+
const float* row(size_t idx, float* scratch) const {
|
|
65
|
+
detail::fp16_to_fp32_kernel<SL>(d, x + idx * d, scratch);
|
|
66
|
+
return scratch;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void copy_row(size_t idx, float* out) const {
|
|
70
|
+
detail::fp16_to_fp32_kernel<SL>(d, x + idx * d, out);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void copy_rows(size_t idx, size_t count, float* out) const {
|
|
74
|
+
detail::fp16_to_fp32_kernel<SL>(count * d, x + idx * d, out);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
template <typename Rows, typename Action>
|
|
79
|
+
auto with_rows_simd_level(Action&& action) {
|
|
80
|
+
if constexpr (Rows::has_fixed_simd_level) {
|
|
81
|
+
return action.template operator()<Rows::simd_level>();
|
|
82
|
+
} else {
|
|
83
|
+
return with_simd_level(std::forward<Action>(action));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
template <typename Rows>
|
|
88
|
+
std::vector<float> row_scratch(size_t d) {
|
|
89
|
+
return std::vector<float>(Rows::needs_scratch ? d : 0);
|
|
90
|
+
}
|
|
91
|
+
|
|
35
92
|
/// Compute distance from point idx to its nearest centroid.
|
|
36
93
|
/// Optionally checks both primary and secondary centroid sets.
|
|
94
|
+
template <typename Rows>
|
|
37
95
|
float distance_to_nearest_centroid(
|
|
38
|
-
|
|
96
|
+
const Rows& rows,
|
|
39
97
|
size_t n_centroids,
|
|
40
|
-
const float* x,
|
|
41
98
|
size_t idx,
|
|
42
99
|
const float* centroids,
|
|
43
|
-
size_t n_existing_centroids
|
|
44
|
-
const float* existing_centroids
|
|
100
|
+
size_t n_existing_centroids,
|
|
101
|
+
const float* existing_centroids,
|
|
102
|
+
float* scratch) {
|
|
45
103
|
if (n_centroids == 0 && n_existing_centroids == 0) {
|
|
46
104
|
return std::numeric_limits<float>::infinity();
|
|
47
105
|
}
|
|
48
106
|
|
|
49
|
-
const float* point =
|
|
107
|
+
const float* point = rows.row(idx, scratch);
|
|
50
108
|
float min_dist = std::numeric_limits<float>::max();
|
|
51
109
|
|
|
52
110
|
auto check_centroids = [&]<SIMDLevel SL>() {
|
|
53
|
-
// Check primary centroids
|
|
54
111
|
for (size_t c = 0; c < n_centroids; c++) {
|
|
55
|
-
float dist = fvec_L2sqr<SL>(point, centroids + c * d, d);
|
|
112
|
+
float dist = fvec_L2sqr<SL>(point, centroids + c * rows.d, rows.d);
|
|
56
113
|
min_dist = std::min(min_dist, dist);
|
|
57
114
|
}
|
|
58
115
|
|
|
59
|
-
// Check existing centroids if provided
|
|
60
116
|
for (size_t c = 0; c < n_existing_centroids; c++) {
|
|
61
|
-
float dist = fvec_L2sqr<SL>(
|
|
117
|
+
float dist = fvec_L2sqr<SL>(
|
|
118
|
+
point, existing_centroids + c * rows.d, rows.d);
|
|
62
119
|
min_dist = std::min(min_dist, dist);
|
|
63
120
|
}
|
|
64
121
|
};
|
|
65
|
-
|
|
122
|
+
with_rows_simd_level<Rows>(check_centroids);
|
|
66
123
|
return min_dist;
|
|
67
124
|
}
|
|
68
125
|
|
|
@@ -78,10 +135,10 @@ struct InitDistancesResult {
|
|
|
78
135
|
/// Otherwise, selects first centroid randomly and computes distances to it.
|
|
79
136
|
/// Returns first_new_centroid_idx (0 if existing, 1 if random first),
|
|
80
137
|
/// sum of squared distances, and the first selected index (if applicable).
|
|
138
|
+
template <typename Rows>
|
|
81
139
|
InitDistancesResult init_distances_for_d2_sampling(
|
|
82
|
-
size_t d,
|
|
83
140
|
size_t n,
|
|
84
|
-
const
|
|
141
|
+
const Rows& rows,
|
|
85
142
|
float* centroids,
|
|
86
143
|
size_t n_existing_centroids,
|
|
87
144
|
const float* existing_centroids,
|
|
@@ -89,25 +146,30 @@ InitDistancesResult init_distances_for_d2_sampling(
|
|
|
89
146
|
std::mt19937_64& rng) {
|
|
90
147
|
double sum_d2 = 0.0;
|
|
91
148
|
size_t first_selected_idx = 0;
|
|
149
|
+
auto scratch = row_scratch<Rows>(rows.d);
|
|
92
150
|
|
|
93
151
|
if (n_existing_centroids > 0 && existing_centroids != nullptr) {
|
|
94
|
-
// Compute distances to nearest existing centroid
|
|
95
152
|
for (size_t i = 0; i < n; i++) {
|
|
96
153
|
distances[i] = distance_to_nearest_centroid(
|
|
97
|
-
|
|
154
|
+
rows,
|
|
155
|
+
n_existing_centroids,
|
|
156
|
+
i,
|
|
157
|
+
existing_centroids,
|
|
158
|
+
0,
|
|
159
|
+
nullptr,
|
|
160
|
+
scratch.data());
|
|
98
161
|
sum_d2 += distances[i];
|
|
99
162
|
}
|
|
100
163
|
return {0, sum_d2, 0};
|
|
101
164
|
} else {
|
|
102
|
-
// Select first centroid randomly
|
|
103
165
|
std::uniform_int_distribution<size_t> uniform_dist(0, n - 1);
|
|
104
166
|
first_selected_idx = uniform_dist(rng);
|
|
105
|
-
|
|
167
|
+
rows.copy_row(first_selected_idx, centroids);
|
|
106
168
|
|
|
107
|
-
|
|
108
|
-
with_simd_level([&]<SIMDLevel SL>() {
|
|
169
|
+
with_rows_simd_level<Rows>([&]<SIMDLevel SL>() {
|
|
109
170
|
for (size_t i = 0; i < n; i++) {
|
|
110
|
-
|
|
171
|
+
const float* point = rows.row(i, scratch.data());
|
|
172
|
+
distances[i] = fvec_L2sqr<SL>(point, centroids, rows.d);
|
|
111
173
|
sum_d2 += distances[i];
|
|
112
174
|
}
|
|
113
175
|
});
|
|
@@ -140,138 +202,97 @@ size_t sample_from_cumsum(
|
|
|
140
202
|
return std::min(idx, n - 1);
|
|
141
203
|
}
|
|
142
204
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
ClusteringInitialization
|
|
146
|
-
: d(d_in), k(k_in) {}
|
|
147
|
-
|
|
148
|
-
void ClusteringInitialization::init_centroids(
|
|
149
|
-
size_t n,
|
|
150
|
-
const float* x,
|
|
151
|
-
float* centroids,
|
|
152
|
-
size_t n_existing_centroids,
|
|
153
|
-
const float* existing_centroids) const {
|
|
154
|
-
FAISS_THROW_IF_NOT_FMT(
|
|
155
|
-
n >= k,
|
|
156
|
-
"Number of points (%zu) must be >= number of centroids (%zu)",
|
|
157
|
-
n,
|
|
158
|
-
k);
|
|
159
|
-
FAISS_THROW_IF_NOT(d > 0);
|
|
160
|
-
FAISS_THROW_IF_NOT(x);
|
|
161
|
-
FAISS_THROW_IF_NOT(centroids);
|
|
162
|
-
FAISS_THROW_IF_NOT(
|
|
163
|
-
n_existing_centroids == 0 || existing_centroids != nullptr);
|
|
164
|
-
|
|
165
|
-
switch (method) {
|
|
166
|
-
case ClusteringInitMethod::RANDOM:
|
|
167
|
-
init_random(n, x, centroids);
|
|
168
|
-
break;
|
|
169
|
-
case ClusteringInitMethod::KMEANS_PLUS_PLUS:
|
|
170
|
-
init_kmeans_plus_plus(
|
|
171
|
-
n, x, centroids, n_existing_centroids, existing_centroids);
|
|
172
|
-
break;
|
|
173
|
-
case ClusteringInitMethod::AFK_MC2:
|
|
174
|
-
init_afkmc2(
|
|
175
|
-
n, x, centroids, n_existing_centroids, existing_centroids);
|
|
176
|
-
break;
|
|
177
|
-
default:
|
|
178
|
-
FAISS_THROW_MSG("Unknown initialization method");
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
void ClusteringInitialization::init_random(
|
|
205
|
+
template <typename Rows>
|
|
206
|
+
void init_kmeans_plus_plus_impl(
|
|
207
|
+
const ClusteringInitialization& initializer,
|
|
183
208
|
size_t n,
|
|
184
|
-
const
|
|
185
|
-
float* centroids) const {
|
|
186
|
-
// Use rand_perm for backward compatibility with Clustering.cpp
|
|
187
|
-
// This ensures the same random sequence as the original implementation
|
|
188
|
-
std::vector<int> perm(n);
|
|
189
|
-
rand_perm(perm.data(), n, seed);
|
|
190
|
-
|
|
191
|
-
// Copy selected points to centroids
|
|
192
|
-
for (size_t i = 0; i < k; i++) {
|
|
193
|
-
std::memcpy(centroids + i * d, x + perm[i] * d, d * sizeof(float));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
void ClusteringInitialization::init_kmeans_plus_plus(
|
|
198
|
-
size_t n,
|
|
199
|
-
const float* x,
|
|
209
|
+
const Rows& rows,
|
|
200
210
|
float* centroids,
|
|
201
211
|
size_t n_existing_centroids,
|
|
202
|
-
const float* existing_centroids)
|
|
203
|
-
std::mt19937_64 rng(get_seed(seed));
|
|
212
|
+
const float* existing_centroids) {
|
|
213
|
+
std::mt19937_64 rng(get_seed(initializer.seed));
|
|
204
214
|
|
|
205
215
|
std::vector<double> min_distances(n);
|
|
206
216
|
auto result = init_distances_for_d2_sampling(
|
|
207
|
-
d,
|
|
208
217
|
n,
|
|
209
|
-
|
|
218
|
+
rows,
|
|
210
219
|
centroids,
|
|
211
220
|
n_existing_centroids,
|
|
212
221
|
existing_centroids,
|
|
213
222
|
min_distances,
|
|
214
223
|
rng);
|
|
215
224
|
|
|
216
|
-
if (result.first_new_centroid_idx == 1 && k == 1) {
|
|
225
|
+
if (result.first_new_centroid_idx == 1 && initializer.k == 1) {
|
|
217
226
|
return;
|
|
218
227
|
}
|
|
219
228
|
|
|
220
|
-
// Reusable buffer for cumulative sum
|
|
221
229
|
std::vector<double> cumsum(n);
|
|
222
230
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
for (size_t c = result.first_new_centroid_idx; c < k; c++) {
|
|
226
|
-
// Compute cumulative sum
|
|
231
|
+
with_rows_simd_level<Rows>([&]<SIMDLevel SL>() {
|
|
232
|
+
for (size_t c = result.first_new_centroid_idx; c < initializer.k; c++) {
|
|
227
233
|
cumsum[0] = min_distances[0];
|
|
228
234
|
for (size_t i = 1; i < n; i++) {
|
|
229
235
|
cumsum[i] = cumsum[i - 1] + min_distances[i];
|
|
230
236
|
}
|
|
231
237
|
|
|
232
|
-
// Sample using precomputed cumsum
|
|
233
238
|
size_t next_idx = sample_from_cumsum(cumsum, rng);
|
|
234
239
|
|
|
235
|
-
float* new_centroid = centroids + c * d;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
float* new_centroid = centroids + c * rows.d;
|
|
241
|
+
rows.copy_row(next_idx, new_centroid);
|
|
242
|
+
|
|
243
|
+
if constexpr (Rows::needs_scratch) {
|
|
244
|
+
constexpr size_t kRowsPerBlock = 64;
|
|
245
|
+
const int64_t nblocks = static_cast<int64_t>(
|
|
246
|
+
(n + kRowsPerBlock - 1) / kRowsPerBlock);
|
|
247
|
+
#pragma omp parallel
|
|
248
|
+
{
|
|
249
|
+
std::vector<float> block(kRowsPerBlock * rows.d);
|
|
250
|
+
#pragma omp for
|
|
251
|
+
for (int64_t b = 0; b < nblocks; b++) {
|
|
252
|
+
const size_t first =
|
|
253
|
+
static_cast<size_t>(b) * kRowsPerBlock;
|
|
254
|
+
const size_t count = std::min(kRowsPerBlock, n - first);
|
|
255
|
+
rows.copy_rows(first, count, block.data());
|
|
256
|
+
for (size_t j = 0; j < count; j++) {
|
|
257
|
+
double dist = fvec_L2sqr<SL>(
|
|
258
|
+
block.data() + j * rows.d,
|
|
259
|
+
new_centroid,
|
|
260
|
+
rows.d);
|
|
261
|
+
min_distances[first + j] =
|
|
262
|
+
std::min(min_distances[first + j], dist);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
const int64_t ni = static_cast<int64_t>(n);
|
|
241
268
|
#pragma omp parallel for
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
269
|
+
for (int64_t i = 0; i < ni; i++) {
|
|
270
|
+
double dist = fvec_L2sqr<SL>(
|
|
271
|
+
rows.row(i, nullptr), new_centroid, rows.d);
|
|
272
|
+
min_distances[i] = std::min(min_distances[i], dist);
|
|
273
|
+
}
|
|
245
274
|
}
|
|
246
275
|
}
|
|
247
276
|
});
|
|
248
277
|
}
|
|
249
278
|
|
|
250
|
-
|
|
279
|
+
template <typename Rows>
|
|
280
|
+
void init_afkmc2_impl(
|
|
281
|
+
const ClusteringInitialization& initializer,
|
|
251
282
|
size_t n,
|
|
252
|
-
const
|
|
283
|
+
const Rows& rows,
|
|
253
284
|
float* centroids,
|
|
254
285
|
size_t n_existing_centroids,
|
|
255
|
-
const float* existing_centroids)
|
|
256
|
-
|
|
257
|
-
// Reference: Bachem et al., "Fast and Provably Good Seedings for
|
|
258
|
-
// k-Means"
|
|
259
|
-
|
|
260
|
-
std::mt19937_64 rng(get_seed(seed));
|
|
286
|
+
const float* existing_centroids) {
|
|
287
|
+
std::mt19937_64 rng(get_seed(initializer.seed));
|
|
261
288
|
std::uniform_real_distribution<double> uniform_01(0.0, 1.0);
|
|
262
289
|
|
|
263
|
-
// Track selected centroids to prevent duplicates
|
|
264
290
|
std::unordered_set<size_t> selected_centroids;
|
|
265
291
|
|
|
266
|
-
// Compute proposal distribution q(x)
|
|
267
|
-
// If existing centroids: base q on distance to nearest existing
|
|
268
|
-
// centroid Otherwise: select first centroid randomly and base q on
|
|
269
|
-
// it
|
|
270
292
|
std::vector<double> dist_to_nearest(n);
|
|
271
293
|
auto result = init_distances_for_d2_sampling(
|
|
272
|
-
d,
|
|
273
294
|
n,
|
|
274
|
-
|
|
295
|
+
rows,
|
|
275
296
|
centroids,
|
|
276
297
|
n_existing_centroids,
|
|
277
298
|
existing_centroids,
|
|
@@ -280,12 +301,11 @@ void ClusteringInitialization::init_afkmc2(
|
|
|
280
301
|
|
|
281
302
|
if (result.first_new_centroid_idx == 1) {
|
|
282
303
|
selected_centroids.insert(result.first_selected_idx);
|
|
283
|
-
if (k == 1) {
|
|
304
|
+
if (initializer.k == 1) {
|
|
284
305
|
return;
|
|
285
306
|
}
|
|
286
307
|
}
|
|
287
308
|
|
|
288
|
-
// Compute q(x) and cumulative sum in a single pass
|
|
289
309
|
std::vector<double> q(n);
|
|
290
310
|
std::vector<double> q_cumsum(n);
|
|
291
311
|
double uniform_term = 0.5 / static_cast<double>(n);
|
|
@@ -298,55 +318,42 @@ void ClusteringInitialization::init_afkmc2(
|
|
|
298
318
|
q_cumsum[i] = (i > 0 ? q_cumsum[i - 1] : 0.0) + q[i];
|
|
299
319
|
}
|
|
300
320
|
|
|
301
|
-
|
|
302
|
-
for (size_t c = result.first_new_centroid_idx; c < k; c++) {
|
|
303
|
-
// Sample initial candidate from proposal distribution q, skip
|
|
304
|
-
// duplicates
|
|
321
|
+
auto scratch = row_scratch<Rows>(rows.d);
|
|
322
|
+
for (size_t c = result.first_new_centroid_idx; c < initializer.k; c++) {
|
|
305
323
|
size_t current_idx;
|
|
306
324
|
do {
|
|
307
325
|
current_idx = sample_from_cumsum(q_cumsum, rng);
|
|
308
326
|
} while (selected_centroids.count(current_idx) > 0);
|
|
309
327
|
|
|
310
|
-
// Compute distance to nearest centroid (existing + newly
|
|
311
|
-
// selected)
|
|
312
328
|
double current_dist = distance_to_nearest_centroid(
|
|
313
|
-
|
|
329
|
+
rows,
|
|
314
330
|
c,
|
|
315
|
-
x,
|
|
316
331
|
current_idx,
|
|
317
332
|
centroids,
|
|
318
333
|
n_existing_centroids,
|
|
319
|
-
existing_centroids
|
|
334
|
+
existing_centroids,
|
|
335
|
+
scratch.data());
|
|
320
336
|
double current_q = q[current_idx];
|
|
321
337
|
|
|
322
|
-
|
|
323
|
-
for (size_t m = 0; m < afkmc2_chain_length; m++) {
|
|
324
|
-
// Sample proposal from q
|
|
338
|
+
for (size_t m = 0; m < initializer.afkmc2_chain_length; m++) {
|
|
325
339
|
size_t proposed_idx = sample_from_cumsum(q_cumsum, rng);
|
|
326
340
|
|
|
327
|
-
// Skip duplicates before expensive distance computation
|
|
328
341
|
if (selected_centroids.count(proposed_idx) > 0) {
|
|
329
342
|
continue;
|
|
330
343
|
}
|
|
331
344
|
|
|
332
|
-
// Compute distance to nearest centroid (existing + newly
|
|
333
|
-
// selected)
|
|
334
345
|
double proposed_dist = distance_to_nearest_centroid(
|
|
335
|
-
|
|
346
|
+
rows,
|
|
336
347
|
c,
|
|
337
|
-
x,
|
|
338
348
|
proposed_idx,
|
|
339
349
|
centroids,
|
|
340
350
|
n_existing_centroids,
|
|
341
|
-
existing_centroids
|
|
351
|
+
existing_centroids,
|
|
352
|
+
scratch.data());
|
|
342
353
|
double proposed_q = q[proposed_idx];
|
|
343
354
|
|
|
344
|
-
// Metropolis-Hastings acceptance ratio:
|
|
345
|
-
// accept = min(1, d(y,C)² · q(x) / (d(x,C)² · q(y)))
|
|
346
355
|
double acceptance_prob = 0.0;
|
|
347
356
|
if (current_dist <= 0) {
|
|
348
|
-
// Current point is a centroid (distance = 0), never
|
|
349
|
-
// leave
|
|
350
357
|
acceptance_prob = 0.0;
|
|
351
358
|
} else if (proposed_q > 0) {
|
|
352
359
|
double numerator = proposed_dist * current_q;
|
|
@@ -361,10 +368,153 @@ void ClusteringInitialization::init_afkmc2(
|
|
|
361
368
|
}
|
|
362
369
|
}
|
|
363
370
|
|
|
364
|
-
// Use final chain state as new centroid
|
|
365
371
|
selected_centroids.insert(current_idx);
|
|
366
|
-
|
|
372
|
+
rows.copy_row(current_idx, centroids + c * rows.d);
|
|
367
373
|
}
|
|
368
374
|
}
|
|
369
375
|
|
|
376
|
+
void validate_initialization(
|
|
377
|
+
const ClusteringInitialization& initializer,
|
|
378
|
+
size_t n,
|
|
379
|
+
const void* x,
|
|
380
|
+
float* centroids,
|
|
381
|
+
size_t n_existing_centroids,
|
|
382
|
+
const float* existing_centroids) {
|
|
383
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
384
|
+
n >= initializer.k,
|
|
385
|
+
"Number of points (%zu) must be >= number of centroids (%zu)",
|
|
386
|
+
n,
|
|
387
|
+
initializer.k);
|
|
388
|
+
FAISS_THROW_IF_NOT(initializer.d > 0);
|
|
389
|
+
FAISS_THROW_IF_NOT(x);
|
|
390
|
+
FAISS_THROW_IF_NOT(centroids);
|
|
391
|
+
FAISS_THROW_IF_NOT(
|
|
392
|
+
n_existing_centroids == 0 || existing_centroids != nullptr);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
} // namespace
|
|
396
|
+
|
|
397
|
+
ClusteringInitialization::ClusteringInitialization(size_t d_in, size_t k_in)
|
|
398
|
+
: d(d_in), k(k_in) {}
|
|
399
|
+
|
|
400
|
+
void ClusteringInitialization::init_centroids(
|
|
401
|
+
size_t n,
|
|
402
|
+
const float* x,
|
|
403
|
+
float* centroids,
|
|
404
|
+
size_t n_existing_centroids,
|
|
405
|
+
const float* existing_centroids) const {
|
|
406
|
+
validate_initialization(
|
|
407
|
+
*this, n, x, centroids, n_existing_centroids, existing_centroids);
|
|
408
|
+
|
|
409
|
+
switch (method) {
|
|
410
|
+
case ClusteringInitMethod::RANDOM:
|
|
411
|
+
init_random(n, x, centroids);
|
|
412
|
+
break;
|
|
413
|
+
case ClusteringInitMethod::KMEANS_PLUS_PLUS:
|
|
414
|
+
init_kmeans_plus_plus(
|
|
415
|
+
n, x, centroids, n_existing_centroids, existing_centroids);
|
|
416
|
+
break;
|
|
417
|
+
case ClusteringInitMethod::AFK_MC2:
|
|
418
|
+
init_afkmc2(
|
|
419
|
+
n, x, centroids, n_existing_centroids, existing_centroids);
|
|
420
|
+
break;
|
|
421
|
+
default:
|
|
422
|
+
FAISS_THROW_MSG("Unknown initialization method");
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
void ClusteringInitialization::init_random(
|
|
427
|
+
size_t n,
|
|
428
|
+
const float* x,
|
|
429
|
+
float* centroids) const {
|
|
430
|
+
// Use rand_perm for backward compatibility with Clustering.cpp
|
|
431
|
+
// This ensures the same random sequence as the original implementation
|
|
432
|
+
std::vector<int> perm(n);
|
|
433
|
+
rand_perm(perm.data(), n, seed);
|
|
434
|
+
|
|
435
|
+
// Copy selected points to centroids
|
|
436
|
+
for (size_t i = 0; i < k; i++) {
|
|
437
|
+
std::memcpy(centroids + i * d, x + perm[i] * d, d * sizeof(float));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
void ClusteringInitialization::init_kmeans_plus_plus(
|
|
442
|
+
size_t n,
|
|
443
|
+
const float* x,
|
|
444
|
+
float* centroids,
|
|
445
|
+
size_t n_existing_centroids,
|
|
446
|
+
const float* existing_centroids) const {
|
|
447
|
+
init_kmeans_plus_plus_impl(
|
|
448
|
+
*this,
|
|
449
|
+
n,
|
|
450
|
+
FloatRows{d, x},
|
|
451
|
+
centroids,
|
|
452
|
+
n_existing_centroids,
|
|
453
|
+
existing_centroids);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
void ClusteringInitialization::init_afkmc2(
|
|
457
|
+
size_t n,
|
|
458
|
+
const float* x,
|
|
459
|
+
float* centroids,
|
|
460
|
+
size_t n_existing_centroids,
|
|
461
|
+
const float* existing_centroids) const {
|
|
462
|
+
init_afkmc2_impl(
|
|
463
|
+
*this,
|
|
464
|
+
n,
|
|
465
|
+
FloatRows{d, x},
|
|
466
|
+
centroids,
|
|
467
|
+
n_existing_centroids,
|
|
468
|
+
existing_centroids);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
namespace detail {
|
|
472
|
+
|
|
473
|
+
void init_centroids_fp16(
|
|
474
|
+
const ClusteringInitialization& initializer,
|
|
475
|
+
size_t n,
|
|
476
|
+
const uint16_t* x,
|
|
477
|
+
float* centroids,
|
|
478
|
+
size_t n_existing_centroids,
|
|
479
|
+
const float* existing_centroids) {
|
|
480
|
+
validate_initialization(
|
|
481
|
+
initializer,
|
|
482
|
+
n,
|
|
483
|
+
x,
|
|
484
|
+
centroids,
|
|
485
|
+
n_existing_centroids,
|
|
486
|
+
existing_centroids);
|
|
487
|
+
|
|
488
|
+
with_selected_simd_levels<AVAILABLE_SIMD_LEVELS_BASE>([&]<SIMDLevel SL>() {
|
|
489
|
+
switch (initializer.method) {
|
|
490
|
+
case ClusteringInitMethod::KMEANS_PLUS_PLUS:
|
|
491
|
+
init_kmeans_plus_plus_impl(
|
|
492
|
+
initializer,
|
|
493
|
+
n,
|
|
494
|
+
Fp16Rows<SL>{initializer.d, x},
|
|
495
|
+
centroids,
|
|
496
|
+
n_existing_centroids,
|
|
497
|
+
existing_centroids);
|
|
498
|
+
break;
|
|
499
|
+
case ClusteringInitMethod::AFK_MC2:
|
|
500
|
+
init_afkmc2_impl(
|
|
501
|
+
initializer,
|
|
502
|
+
n,
|
|
503
|
+
Fp16Rows<SL>{initializer.d, x},
|
|
504
|
+
centroids,
|
|
505
|
+
n_existing_centroids,
|
|
506
|
+
existing_centroids);
|
|
507
|
+
break;
|
|
508
|
+
case ClusteringInitMethod::RANDOM:
|
|
509
|
+
FAISS_THROW_MSG(
|
|
510
|
+
"fp16 centroid helper requires non-random "
|
|
511
|
+
"initialization");
|
|
512
|
+
default:
|
|
513
|
+
FAISS_THROW_MSG("Unknown initialization method");
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
} // namespace detail
|
|
519
|
+
|
|
370
520
|
} // namespace faiss
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
#include <faiss/impl/DistanceComputer.h>
|
|
9
|
+
|
|
10
|
+
#include <faiss/impl/FaissAssert.h>
|
|
11
|
+
|
|
12
|
+
namespace faiss {
|
|
13
|
+
|
|
14
|
+
void DistanceComputer::distances_batch_4(
|
|
15
|
+
const idx_t idx0,
|
|
16
|
+
const idx_t idx1,
|
|
17
|
+
const idx_t idx2,
|
|
18
|
+
const idx_t idx3,
|
|
19
|
+
float& dis0,
|
|
20
|
+
float& dis1,
|
|
21
|
+
float& dis2,
|
|
22
|
+
float& dis3) {
|
|
23
|
+
// compute first, assign next
|
|
24
|
+
const float d0 = this->operator()(idx0);
|
|
25
|
+
const float d1 = this->operator()(idx1);
|
|
26
|
+
const float d2 = this->operator()(idx2);
|
|
27
|
+
const float d3 = this->operator()(idx3);
|
|
28
|
+
dis0 = d0;
|
|
29
|
+
dis1 = d1;
|
|
30
|
+
dis2 = d2;
|
|
31
|
+
dis3 = d3;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
float FlatCodesDistanceComputer::partial_dot_product(
|
|
35
|
+
const idx_t /* i */,
|
|
36
|
+
const uint32_t /* offset */,
|
|
37
|
+
const uint32_t /* num_components */) {
|
|
38
|
+
FAISS_THROW_MSG("partial_dot_product not implemented");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void FlatCodesDistanceComputer::partial_dot_product_batch_4(
|
|
42
|
+
const idx_t idx0,
|
|
43
|
+
const idx_t idx1,
|
|
44
|
+
const idx_t idx2,
|
|
45
|
+
const idx_t idx3,
|
|
46
|
+
float& dp0,
|
|
47
|
+
float& dp1,
|
|
48
|
+
float& dp2,
|
|
49
|
+
float& dp3,
|
|
50
|
+
const uint32_t offset,
|
|
51
|
+
const uint32_t num_components) {
|
|
52
|
+
// default implementation for correctness
|
|
53
|
+
const float d0 = this->partial_dot_product(idx0, offset, num_components);
|
|
54
|
+
const float d1 = this->partial_dot_product(idx1, offset, num_components);
|
|
55
|
+
const float d2 = this->partial_dot_product(idx2, offset, num_components);
|
|
56
|
+
const float d3 = this->partial_dot_product(idx3, offset, num_components);
|
|
57
|
+
dp0 = d0;
|
|
58
|
+
dp1 = d1;
|
|
59
|
+
dp2 = d2;
|
|
60
|
+
dp3 = d3;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
} // namespace faiss
|