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
|
@@ -9,13 +9,22 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/utils/distances.h>
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
|
|
12
|
+
#include <faiss/impl/FaissAssert.h>
|
|
14
13
|
#include <faiss/utils/extra_distances.h>
|
|
15
14
|
#include <riscv_vector.h>
|
|
16
15
|
|
|
16
|
+
#include <faiss/utils/simd_impl/distances_rvv_kernel.h>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
17
19
|
namespace faiss {
|
|
18
20
|
|
|
21
|
+
// Clang rejects a builtin used as a function argument, so wrap the call in a
|
|
22
|
+
// lambda. GCC accepts the bare name; the wrapper compiles on both.
|
|
23
|
+
#define FAISS_RVV_REDUCE_OP(intrinsic) \
|
|
24
|
+
[](auto value_, auto init_, size_t vl_) { \
|
|
25
|
+
return intrinsic(value_, init_, vl_); \
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
template <typename Vec, typename Reduce>
|
|
20
29
|
static inline float rvv_reduce(
|
|
21
30
|
Vec value,
|
|
@@ -38,7 +47,10 @@ static inline size_t rvv_argmin(const float* values, size_t n) {
|
|
|
38
47
|
i += vl;
|
|
39
48
|
}
|
|
40
49
|
float min_val = rvv_reduce(
|
|
41
|
-
vmin,
|
|
50
|
+
vmin,
|
|
51
|
+
vlmax,
|
|
52
|
+
__builtin_inff(),
|
|
53
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredmin_vs_f32m8_f32m1));
|
|
42
54
|
i = 0;
|
|
43
55
|
while (i < n) {
|
|
44
56
|
size_t vl = __riscv_vsetvl_e32m8(n - i);
|
|
@@ -52,6 +64,126 @@ static inline size_t rvv_argmin(const float* values, size_t n) {
|
|
|
52
64
|
return n;
|
|
53
65
|
}
|
|
54
66
|
|
|
67
|
+
// Write the ksub table entries of one subquantizer that has dsub = 2.
|
|
68
|
+
// The function computes one of these 2 results:
|
|
69
|
+
// inner product: out[k] = x0 * c0[k] + x1 * c1[k]
|
|
70
|
+
// L2: out[k] = (c0[k] - x0)^2 + (c1[k] - x1)^2
|
|
71
|
+
template <bool is_inner_product>
|
|
72
|
+
static inline void rvv_pq2_row(
|
|
73
|
+
const float* c0,
|
|
74
|
+
const float* c1,
|
|
75
|
+
float x0,
|
|
76
|
+
float x1,
|
|
77
|
+
size_t ksub,
|
|
78
|
+
size_t vl,
|
|
79
|
+
float* out) {
|
|
80
|
+
for (size_t k = 0; k < ksub; k += vl) {
|
|
81
|
+
vfloat32m1_t vc0 = __riscv_vle32_v_f32m1(c0 + k, vl);
|
|
82
|
+
vfloat32m1_t vc1 = __riscv_vle32_v_f32m1(c1 + k, vl);
|
|
83
|
+
if constexpr (is_inner_product) {
|
|
84
|
+
vfloat32m1_t r = __riscv_vfmacc_vf_f32m1(
|
|
85
|
+
__riscv_vfmul_vf_f32m1(vc0, x0, vl), x1, vc1, vl);
|
|
86
|
+
__riscv_vse32_v_f32m1(out + k, r, vl);
|
|
87
|
+
} else {
|
|
88
|
+
vfloat32m1_t d0 = __riscv_vfsub_vf_f32m1(vc0, x0, vl);
|
|
89
|
+
vfloat32m1_t d1 = __riscv_vfsub_vf_f32m1(vc1, x1, vl);
|
|
90
|
+
d0 = __riscv_vfmul_vv_f32m1(d0, d0, vl);
|
|
91
|
+
d1 = __riscv_vfmul_vv_f32m1(d1, d1, vl);
|
|
92
|
+
vfloat32m1_t r = __riscv_vfadd_vv_f32m1(d0, d1, vl);
|
|
93
|
+
__riscv_vse32_v_f32m1(out + k, r, vl);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
template <bool is_inner_product>
|
|
99
|
+
static void rvv_pq2_tables(
|
|
100
|
+
size_t M,
|
|
101
|
+
size_t ksub,
|
|
102
|
+
const float* c0_all,
|
|
103
|
+
const float* c1_all,
|
|
104
|
+
size_t nx,
|
|
105
|
+
const float* x,
|
|
106
|
+
size_t vl,
|
|
107
|
+
float* dis_tables) {
|
|
108
|
+
const size_t d = 2 * M;
|
|
109
|
+
for (size_t i = 0; i < nx; i++) {
|
|
110
|
+
const float* xi = x + i * d;
|
|
111
|
+
float* oi = dis_tables + i * M * ksub;
|
|
112
|
+
size_t m = 0;
|
|
113
|
+
// The loop computes 2 subquantizers per iteration. The 2 computations
|
|
114
|
+
// are independent, so the processor can run them at the same time.
|
|
115
|
+
for (; m + 1 < M; m += 2) {
|
|
116
|
+
rvv_pq2_row<is_inner_product>(
|
|
117
|
+
c0_all + m * ksub,
|
|
118
|
+
c1_all + m * ksub,
|
|
119
|
+
xi[2 * m],
|
|
120
|
+
xi[2 * m + 1],
|
|
121
|
+
ksub,
|
|
122
|
+
vl,
|
|
123
|
+
oi + m * ksub);
|
|
124
|
+
rvv_pq2_row<is_inner_product>(
|
|
125
|
+
c0_all + (m + 1) * ksub,
|
|
126
|
+
c1_all + (m + 1) * ksub,
|
|
127
|
+
xi[2 * (m + 1)],
|
|
128
|
+
xi[2 * (m + 1) + 1],
|
|
129
|
+
ksub,
|
|
130
|
+
vl,
|
|
131
|
+
oi + (m + 1) * ksub);
|
|
132
|
+
}
|
|
133
|
+
// If M is odd, the loop above skips the last subquantizer. This loop
|
|
134
|
+
// computes it.
|
|
135
|
+
for (; m < M; m++) {
|
|
136
|
+
rvv_pq2_row<is_inner_product>(
|
|
137
|
+
c0_all + m * ksub,
|
|
138
|
+
c1_all + m * ksub,
|
|
139
|
+
xi[2 * m],
|
|
140
|
+
xi[2 * m + 1],
|
|
141
|
+
ksub,
|
|
142
|
+
vl,
|
|
143
|
+
oi + m * ksub);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
template <>
|
|
149
|
+
void compute_PQ_dis_tables_dsub2<SIMDLevel::RISCV_RVV>(
|
|
150
|
+
size_t d,
|
|
151
|
+
size_t ksub,
|
|
152
|
+
const float* all_centroids,
|
|
153
|
+
size_t nx,
|
|
154
|
+
const float* x,
|
|
155
|
+
bool is_inner_product,
|
|
156
|
+
float* dis_tables) {
|
|
157
|
+
const size_t M = d / 2;
|
|
158
|
+
FAISS_THROW_IF_NOT(ksub % 8 == 0);
|
|
159
|
+
|
|
160
|
+
// Separate the centroids into 2 planes. Each plane holds one component of
|
|
161
|
+
// every centroid, so a unit-stride load can read the plane.
|
|
162
|
+
std::vector<float> c0_all(M * ksub);
|
|
163
|
+
std::vector<float> c1_all(M * ksub);
|
|
164
|
+
for (size_t m = 0; m < M; m++) {
|
|
165
|
+
const float* cm = all_centroids + m * ksub * 2;
|
|
166
|
+
float* c0m = c0_all.data() + m * ksub;
|
|
167
|
+
float* c1m = c1_all.data() + m * ksub;
|
|
168
|
+
for (size_t k = 0; k < ksub; k++) {
|
|
169
|
+
c0m[k] = cm[2 * k];
|
|
170
|
+
c1m[k] = cm[2 * k + 1];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ksub is a power of 2, and ksub is a multiple of 8. Therefore vl divides
|
|
175
|
+
// ksub exactly.
|
|
176
|
+
const size_t vl = __riscv_vsetvl_e32m1(ksub);
|
|
177
|
+
|
|
178
|
+
if (is_inner_product) {
|
|
179
|
+
rvv_pq2_tables<true>(
|
|
180
|
+
M, ksub, c0_all.data(), c1_all.data(), nx, x, vl, dis_tables);
|
|
181
|
+
} else {
|
|
182
|
+
rvv_pq2_tables<false>(
|
|
183
|
+
M, ksub, c0_all.data(), c1_all.data(), nx, x, vl, dis_tables);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
55
187
|
template <>
|
|
56
188
|
float fvec_norm_L2sqr<SIMDLevel::RISCV_RVV>(const float* x, size_t d) {
|
|
57
189
|
size_t vlmax = __riscv_vsetvlmax_e32m8();
|
|
@@ -63,7 +195,11 @@ float fvec_norm_L2sqr<SIMDLevel::RISCV_RVV>(const float* x, size_t d) {
|
|
|
63
195
|
acc = __riscv_vfmacc_vv_f32m8_tu(acc, vx, vx, vl);
|
|
64
196
|
i += vl;
|
|
65
197
|
}
|
|
66
|
-
return rvv_reduce(
|
|
198
|
+
return rvv_reduce(
|
|
199
|
+
acc,
|
|
200
|
+
vlmax,
|
|
201
|
+
0.0f,
|
|
202
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m8_f32m1));
|
|
67
203
|
}
|
|
68
204
|
|
|
69
205
|
template <>
|
|
@@ -71,18 +207,7 @@ float fvec_L2sqr<SIMDLevel::RISCV_RVV>(
|
|
|
71
207
|
const float* x,
|
|
72
208
|
const float* y,
|
|
73
209
|
size_t d) {
|
|
74
|
-
|
|
75
|
-
vfloat32m8_t acc = __riscv_vfmv_v_f_f32m8(0.0f, vlmax);
|
|
76
|
-
size_t i = 0;
|
|
77
|
-
while (i < d) {
|
|
78
|
-
size_t vl = __riscv_vsetvl_e32m8(d - i);
|
|
79
|
-
vfloat32m8_t vx = __riscv_vle32_v_f32m8(x + i, vl);
|
|
80
|
-
vfloat32m8_t vy = __riscv_vle32_v_f32m8(y + i, vl);
|
|
81
|
-
vx = __riscv_vfsub_vv_f32m8(vx, vy, vl);
|
|
82
|
-
acc = __riscv_vfmacc_vv_f32m8_tu(acc, vx, vx, vl);
|
|
83
|
-
i += vl;
|
|
84
|
-
}
|
|
85
|
-
return rvv_reduce(acc, vlmax, 0.0f, __riscv_vfredusum_vs_f32m8_f32m1);
|
|
210
|
+
return rvv_kernel::l2_sqr(x, y, d);
|
|
86
211
|
}
|
|
87
212
|
|
|
88
213
|
template <>
|
|
@@ -90,17 +215,7 @@ float fvec_inner_product<SIMDLevel::RISCV_RVV>(
|
|
|
90
215
|
const float* x,
|
|
91
216
|
const float* y,
|
|
92
217
|
size_t d) {
|
|
93
|
-
|
|
94
|
-
vfloat32m8_t acc = __riscv_vfmv_v_f_f32m8(0.0f, vlmax);
|
|
95
|
-
size_t i = 0;
|
|
96
|
-
while (i < d) {
|
|
97
|
-
size_t vl = __riscv_vsetvl_e32m8(d - i);
|
|
98
|
-
vfloat32m8_t vx = __riscv_vle32_v_f32m8(x + i, vl);
|
|
99
|
-
vfloat32m8_t vy = __riscv_vle32_v_f32m8(y + i, vl);
|
|
100
|
-
acc = __riscv_vfmacc_vv_f32m8_tu(acc, vx, vy, vl);
|
|
101
|
-
i += vl;
|
|
102
|
-
}
|
|
103
|
-
return rvv_reduce(acc, vlmax, 0.0f, __riscv_vfredusum_vs_f32m8_f32m1);
|
|
218
|
+
return rvv_kernel::inner_product(x, y, d);
|
|
104
219
|
}
|
|
105
220
|
|
|
106
221
|
template <>
|
|
@@ -117,7 +232,11 @@ float fvec_L1<SIMDLevel::RISCV_RVV>(const float* x, const float* y, size_t d) {
|
|
|
117
232
|
acc = __riscv_vfadd_vv_f32m8_tu(acc, acc, vx, vl);
|
|
118
233
|
i += vl;
|
|
119
234
|
}
|
|
120
|
-
return rvv_reduce(
|
|
235
|
+
return rvv_reduce(
|
|
236
|
+
acc,
|
|
237
|
+
vlmax,
|
|
238
|
+
0.0f,
|
|
239
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m8_f32m1));
|
|
121
240
|
}
|
|
122
241
|
|
|
123
242
|
template <>
|
|
@@ -137,7 +256,11 @@ float fvec_Linf<SIMDLevel::RISCV_RVV>(
|
|
|
137
256
|
vmax = __riscv_vfmax_vv_f32m8_tu(vmax, vmax, vx, vl);
|
|
138
257
|
i += vl;
|
|
139
258
|
}
|
|
140
|
-
return rvv_reduce(
|
|
259
|
+
return rvv_reduce(
|
|
260
|
+
vmax,
|
|
261
|
+
vlmax,
|
|
262
|
+
0.0f,
|
|
263
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredmax_vs_f32m8_f32m1));
|
|
141
264
|
}
|
|
142
265
|
|
|
143
266
|
template <>
|
|
@@ -171,10 +294,26 @@ void fvec_inner_product_batch_4<SIMDLevel::RISCV_RVV>(
|
|
|
171
294
|
vacc3 = __riscv_vfmacc_vv_f32m4_tu(vacc3, vx, vy, vl);
|
|
172
295
|
i += vl;
|
|
173
296
|
}
|
|
174
|
-
dis0 = rvv_reduce(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
297
|
+
dis0 = rvv_reduce(
|
|
298
|
+
vacc0,
|
|
299
|
+
vlmax,
|
|
300
|
+
0.0f,
|
|
301
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
302
|
+
dis1 = rvv_reduce(
|
|
303
|
+
vacc1,
|
|
304
|
+
vlmax,
|
|
305
|
+
0.0f,
|
|
306
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
307
|
+
dis2 = rvv_reduce(
|
|
308
|
+
vacc2,
|
|
309
|
+
vlmax,
|
|
310
|
+
0.0f,
|
|
311
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
312
|
+
dis3 = rvv_reduce(
|
|
313
|
+
vacc3,
|
|
314
|
+
vlmax,
|
|
315
|
+
0.0f,
|
|
316
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
178
317
|
}
|
|
179
318
|
|
|
180
319
|
template <>
|
|
@@ -212,10 +351,26 @@ void fvec_L2sqr_batch_4<SIMDLevel::RISCV_RVV>(
|
|
|
212
351
|
vacc3 = __riscv_vfmacc_vv_f32m4_tu(vacc3, vy, vy, vl);
|
|
213
352
|
i += vl;
|
|
214
353
|
}
|
|
215
|
-
dis0 = rvv_reduce(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
354
|
+
dis0 = rvv_reduce(
|
|
355
|
+
vacc0,
|
|
356
|
+
vlmax,
|
|
357
|
+
0.0f,
|
|
358
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
359
|
+
dis1 = rvv_reduce(
|
|
360
|
+
vacc1,
|
|
361
|
+
vlmax,
|
|
362
|
+
0.0f,
|
|
363
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
364
|
+
dis2 = rvv_reduce(
|
|
365
|
+
vacc2,
|
|
366
|
+
vlmax,
|
|
367
|
+
0.0f,
|
|
368
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
369
|
+
dis3 = rvv_reduce(
|
|
370
|
+
vacc3,
|
|
371
|
+
vlmax,
|
|
372
|
+
0.0f,
|
|
373
|
+
FAISS_RVV_REDUCE_OP(__riscv_vfredusum_vs_f32m4_f32m1));
|
|
219
374
|
}
|
|
220
375
|
|
|
221
376
|
template <>
|
|
@@ -227,31 +382,56 @@ void fvec_L2sqr_ny_transposed<SIMDLevel::RISCV_RVV>(
|
|
|
227
382
|
size_t d,
|
|
228
383
|
size_t d_offset,
|
|
229
384
|
size_t ny) {
|
|
230
|
-
|
|
231
|
-
|
|
385
|
+
// Compute the squared length of the query subvector.
|
|
386
|
+
float x_sqlen = 0;
|
|
387
|
+
for (size_t j = 0; j < d; j++) {
|
|
388
|
+
x_sqlen += x[j] * x[j];
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// The loop below divides the ny dimension into chunks. Each chunk uses
|
|
392
|
+
// e32m8. The chunk size is VLMAX, so the kernel fills the whole vector
|
|
393
|
+
// register at every VLEN.
|
|
394
|
+
const size_t chunk = __riscv_vsetvlmax_e32m8();
|
|
232
395
|
size_t i = 0;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
396
|
+
|
|
397
|
+
// dis[i] = x_sqlen + y_sqlen[i] - 2 * sum_j x[j] * y[j * d_offset + i]
|
|
398
|
+
//
|
|
399
|
+
// The code accumulates the dot product first, and it applies the factor
|
|
400
|
+
// of 2 afterwards. Matches SIMDLevel::NONE implementation which scales the
|
|
401
|
+
// accumulated dot product in the same way.
|
|
402
|
+
for (; i + chunk <= ny; i += chunk) {
|
|
403
|
+
vfloat32m8_t dp = __riscv_vfmv_v_f_f32m8(0.0f, chunk);
|
|
404
|
+
for (size_t j = 0; j < d; j++) {
|
|
405
|
+
vfloat32m8_t y_vec =
|
|
406
|
+
__riscv_vle32_v_f32m8(y + j * d_offset + i, chunk);
|
|
407
|
+
dp = __riscv_vfmacc_vf_f32m8(dp, x[j], y_vec, chunk);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
vfloat32m8_t acc = __riscv_vle32_v_f32m8(y_sqlen + i, chunk);
|
|
411
|
+
acc = __riscv_vfadd_vf_f32m8(acc, x_sqlen, chunk);
|
|
412
|
+
dp = __riscv_vfmul_vf_f32m8(dp, 2.0f, chunk);
|
|
413
|
+
acc = __riscv_vfsub_vv_f32m8(acc, dp, chunk);
|
|
414
|
+
|
|
415
|
+
__riscv_vse32_v_f32m8(dis + i, acc, chunk);
|
|
238
416
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
i
|
|
242
|
-
while (i < ny) {
|
|
417
|
+
|
|
418
|
+
// This block computes the last ny % chunk elements.
|
|
419
|
+
if (i < ny) {
|
|
243
420
|
size_t vl = __riscv_vsetvl_e32m8(ny - i);
|
|
244
|
-
|
|
421
|
+
|
|
422
|
+
vfloat32m8_t dp = __riscv_vfmv_v_f_f32m8(0.0f, vl);
|
|
245
423
|
for (size_t j = 0; j < d; j++) {
|
|
246
|
-
vfloat32m8_t
|
|
247
|
-
|
|
424
|
+
vfloat32m8_t y_vec =
|
|
425
|
+
__riscv_vle32_v_f32m8(y + j * d_offset + i, vl);
|
|
426
|
+
dp = __riscv_vfmacc_vf_f32m8(dp, x[j], y_vec, vl);
|
|
248
427
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
acc =
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
428
|
+
|
|
429
|
+
vfloat32m8_t acc = __riscv_vle32_v_f32m8(y_sqlen + i, vl);
|
|
430
|
+
acc = __riscv_vfadd_vf_f32m8(acc, x_sqlen, vl);
|
|
431
|
+
dp = __riscv_vfmul_vf_f32m8(dp, 2.0f, vl);
|
|
432
|
+
acc = __riscv_vfsub_vv_f32m8(acc, dp, vl);
|
|
433
|
+
|
|
434
|
+
__riscv_vse32_v_f32m8(dis + i, acc, vl);
|
|
255
435
|
}
|
|
256
436
|
}
|
|
257
437
|
|
|
@@ -262,9 +442,40 @@ void fvec_inner_products_ny<SIMDLevel::RISCV_RVV>(
|
|
|
262
442
|
const float* y,
|
|
263
443
|
size_t d,
|
|
264
444
|
size_t ny) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
445
|
+
// The loop below divides the ny dimension into chunks. Each chunk uses
|
|
446
|
+
// e32m4.
|
|
447
|
+
// ip[i] = sum_{j=0}^{d-1} x[j] * y[i * d + j]
|
|
448
|
+
const size_t chunk = __riscv_vsetvlmax_e32m4();
|
|
449
|
+
const ptrdiff_t stride_bytes = (ptrdiff_t)d * (ptrdiff_t)sizeof(float);
|
|
450
|
+
size_t i = 0;
|
|
451
|
+
|
|
452
|
+
for (; i + chunk <= ny; i += chunk) {
|
|
453
|
+
vfloat32m4_t acc = __riscv_vfmv_v_f_f32m4(0.0f, chunk);
|
|
454
|
+
const float* yb = y + i * d; // the first vector of this chunk
|
|
455
|
+
|
|
456
|
+
for (size_t j = 0; j < d; j++) {
|
|
457
|
+
vfloat32m4_t y_vec =
|
|
458
|
+
__riscv_vlse32_v_f32m4(yb + j, stride_bytes, chunk);
|
|
459
|
+
acc = __riscv_vfmacc_vf_f32m4(acc, x[j], y_vec, chunk);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
__riscv_vse32_v_f32m4(ip + i, acc, chunk);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// This block computes the last ny % chunk elements.
|
|
466
|
+
if (i < ny) {
|
|
467
|
+
size_t vl = __riscv_vsetvl_e32m4(ny - i);
|
|
468
|
+
|
|
469
|
+
vfloat32m4_t acc = __riscv_vfmv_v_f_f32m4(0.0f, vl);
|
|
470
|
+
const float* yb = y + i * d;
|
|
471
|
+
|
|
472
|
+
for (size_t j = 0; j < d; j++) {
|
|
473
|
+
vfloat32m4_t y_vec =
|
|
474
|
+
__riscv_vlse32_v_f32m4(yb + j, stride_bytes, vl);
|
|
475
|
+
acc = __riscv_vfmacc_vf_f32m4(acc, x[j], y_vec, vl);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
__riscv_vse32_v_f32m4(ip + i, acc, vl);
|
|
268
479
|
}
|
|
269
480
|
}
|
|
270
481
|
|
|
@@ -275,9 +486,35 @@ void fvec_L2sqr_ny<SIMDLevel::RISCV_RVV>(
|
|
|
275
486
|
const float* y,
|
|
276
487
|
size_t d,
|
|
277
488
|
size_t ny) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
489
|
+
// The loop below divides the ny dimension into chunks. Each chunk uses
|
|
490
|
+
// e32m8.
|
|
491
|
+
const size_t chunk = __riscv_vsetvlmax_e32m8();
|
|
492
|
+
const ptrdiff_t stride_bytes = (ptrdiff_t)d * (ptrdiff_t)sizeof(float);
|
|
493
|
+
size_t i = 0;
|
|
494
|
+
|
|
495
|
+
for (; i + chunk <= ny; i += chunk) {
|
|
496
|
+
vfloat32m8_t acc = __riscv_vfmv_v_f_f32m8(0.0f, chunk);
|
|
497
|
+
const float* yb = y + i * d; // the first vector of this chunk
|
|
498
|
+
for (size_t j = 0; j < d; j++) {
|
|
499
|
+
vfloat32m8_t y_vec =
|
|
500
|
+
__riscv_vlse32_v_f32m8(yb + j, stride_bytes, chunk);
|
|
501
|
+
vfloat32m8_t diff = __riscv_vfsub_vf_f32m8(y_vec, x[j], chunk);
|
|
502
|
+
acc = __riscv_vfmacc_vv_f32m8(acc, diff, diff, chunk);
|
|
503
|
+
}
|
|
504
|
+
__riscv_vse32_v_f32m8(dis + i, acc, chunk);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (i < ny) {
|
|
508
|
+
size_t vl = __riscv_vsetvl_e32m8(ny - i);
|
|
509
|
+
vfloat32m8_t acc = __riscv_vfmv_v_f_f32m8(0.0f, vl);
|
|
510
|
+
const float* yb = y + i * d;
|
|
511
|
+
for (size_t j = 0; j < d; j++) {
|
|
512
|
+
vfloat32m8_t y_vec =
|
|
513
|
+
__riscv_vlse32_v_f32m8(yb + j, stride_bytes, vl);
|
|
514
|
+
vfloat32m8_t diff = __riscv_vfsub_vf_f32m8(y_vec, x[j], vl);
|
|
515
|
+
acc = __riscv_vfmacc_vv_f32m8(acc, diff, diff, vl);
|
|
516
|
+
}
|
|
517
|
+
__riscv_vse32_v_f32m8(dis + i, acc, vl);
|
|
281
518
|
}
|
|
282
519
|
}
|
|
283
520
|
|
|
@@ -288,9 +525,8 @@ size_t fvec_L2sqr_ny_nearest<SIMDLevel::RISCV_RVV>(
|
|
|
288
525
|
const float* y,
|
|
289
526
|
size_t d,
|
|
290
527
|
size_t ny) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
return j < ny ? j : 0;
|
|
528
|
+
return fvec_L2sqr_ny_nearest<SIMDLevel::NONE>(
|
|
529
|
+
distances_tmp_buffer, x, y, d, ny);
|
|
294
530
|
}
|
|
295
531
|
|
|
296
532
|
template <>
|
|
@@ -302,10 +538,8 @@ size_t fvec_L2sqr_ny_nearest_y_transposed<SIMDLevel::RISCV_RVV>(
|
|
|
302
538
|
size_t d,
|
|
303
539
|
size_t d_offset,
|
|
304
540
|
size_t ny) {
|
|
305
|
-
|
|
541
|
+
return fvec_L2sqr_ny_nearest_y_transposed<SIMDLevel::NONE>(
|
|
306
542
|
distances_tmp_buffer, x, y, y_sqlen, d, d_offset, ny);
|
|
307
|
-
const size_t j = rvv_argmin(distances_tmp_buffer, ny);
|
|
308
|
-
return j < ny ? j : 0;
|
|
309
543
|
}
|
|
310
544
|
|
|
311
545
|
template <>
|
|
@@ -338,6 +572,56 @@ int fvec_madd_and_argmin<SIMDLevel::RISCV_RVV>(
|
|
|
338
572
|
return j < n ? static_cast<int>(j) : -1;
|
|
339
573
|
}
|
|
340
574
|
|
|
575
|
+
template <>
|
|
576
|
+
void fvec_add<SIMDLevel::RISCV_RVV>(
|
|
577
|
+
size_t d,
|
|
578
|
+
const float* a,
|
|
579
|
+
const float* b,
|
|
580
|
+
float* c) {
|
|
581
|
+
size_t i = 0;
|
|
582
|
+
while (i < d) {
|
|
583
|
+
size_t vl = __riscv_vsetvl_e32m8(d - i);
|
|
584
|
+
vfloat32m8_t va = __riscv_vle32_v_f32m8(a + i, vl);
|
|
585
|
+
vfloat32m8_t vb = __riscv_vle32_v_f32m8(b + i, vl);
|
|
586
|
+
va = __riscv_vfadd_vv_f32m8(va, vb, vl);
|
|
587
|
+
__riscv_vse32_v_f32m8(c + i, va, vl);
|
|
588
|
+
i += vl;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
template <>
|
|
593
|
+
void fvec_add<SIMDLevel::RISCV_RVV>(
|
|
594
|
+
size_t d,
|
|
595
|
+
const float* a,
|
|
596
|
+
float b,
|
|
597
|
+
float* c) {
|
|
598
|
+
size_t i = 0;
|
|
599
|
+
while (i < d) {
|
|
600
|
+
size_t vl = __riscv_vsetvl_e32m8(d - i);
|
|
601
|
+
vfloat32m8_t va = __riscv_vle32_v_f32m8(a + i, vl);
|
|
602
|
+
va = __riscv_vfadd_vf_f32m8(va, b, vl);
|
|
603
|
+
__riscv_vse32_v_f32m8(c + i, va, vl);
|
|
604
|
+
i += vl;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
template <>
|
|
609
|
+
void fvec_sub<SIMDLevel::RISCV_RVV>(
|
|
610
|
+
size_t d,
|
|
611
|
+
const float* a,
|
|
612
|
+
const float* b,
|
|
613
|
+
float* c) {
|
|
614
|
+
size_t i = 0;
|
|
615
|
+
while (i < d) {
|
|
616
|
+
size_t vl = __riscv_vsetvl_e32m8(d - i);
|
|
617
|
+
vfloat32m8_t va = __riscv_vle32_v_f32m8(a + i, vl);
|
|
618
|
+
vfloat32m8_t vb = __riscv_vle32_v_f32m8(b + i, vl);
|
|
619
|
+
va = __riscv_vfsub_vv_f32m8(va, vb, vl);
|
|
620
|
+
__riscv_vse32_v_f32m8(c + i, va, vl);
|
|
621
|
+
i += vl;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
341
625
|
#define DEFINE_VECTOR_DISTANCE_RVV_FALLBACK(metric) \
|
|
342
626
|
template <> \
|
|
343
627
|
float VectorDistance<metric, SIMDLevel::RISCV_RVV>::operator()( \
|
|
@@ -365,5 +649,3 @@ DEFINE_VECTOR_DISTANCE_RVV_FALLBACK(METRIC_GOWER)
|
|
|
365
649
|
#define THE_SIMD_LEVEL SIMDLevel::RISCV_RVV
|
|
366
650
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
367
651
|
#include <faiss/utils/simd_impl/IVFFlatScanner-inl.h>
|
|
368
|
-
|
|
369
|
-
#endif // COMPILE_SIMD_RISCV_RVV
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
/* Vector-to-vector distance kernels for RISC-V Vector.
|
|
11
|
+
*
|
|
12
|
+
* Free-standing (no exceptions, heap or threads), so a freestanding RISC-V
|
|
13
|
+
* target can compile it. distances_rvv.cpp calls these; no Buck target here
|
|
14
|
+
* builds that RISC-V CPU path.
|
|
15
|
+
*
|
|
16
|
+
* These inline the horizontal reduction rather than passing the intrinsic to
|
|
17
|
+
* a helper. Clang rejects a builtin used as a function argument.
|
|
18
|
+
*
|
|
19
|
+
* They accumulate at LMUL 4, not 8: a group of eight leaves only four
|
|
20
|
+
* register groups, which is slower in a scan loop. The order of the
|
|
21
|
+
* additions differs from LMUL 8, so the last bits can differ.
|
|
22
|
+
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
#include <cstddef>
|
|
26
|
+
|
|
27
|
+
#include <riscv_vector.h>
|
|
28
|
+
|
|
29
|
+
namespace faiss {
|
|
30
|
+
namespace rvv_kernel {
|
|
31
|
+
|
|
32
|
+
/// Squared L2 distance between two fp32 vectors.
|
|
33
|
+
inline float l2_sqr(const float* x, const float* y, size_t d) {
|
|
34
|
+
const size_t vlmax = __riscv_vsetvlmax_e32m4();
|
|
35
|
+
vfloat32m4_t acc = __riscv_vfmv_v_f_f32m4(0.0f, vlmax);
|
|
36
|
+
size_t i = 0;
|
|
37
|
+
while (i < d) {
|
|
38
|
+
const size_t vl = __riscv_vsetvl_e32m4(d - i);
|
|
39
|
+
vfloat32m4_t vx = __riscv_vle32_v_f32m4(x + i, vl);
|
|
40
|
+
vfloat32m4_t vy = __riscv_vle32_v_f32m4(y + i, vl);
|
|
41
|
+
vx = __riscv_vfsub_vv_f32m4(vx, vy, vl);
|
|
42
|
+
acc = __riscv_vfmacc_vv_f32m4_tu(acc, vx, vx, vl);
|
|
43
|
+
i += vl;
|
|
44
|
+
}
|
|
45
|
+
vfloat32m1_t init = __riscv_vfmv_s_f_f32m1(0.0f, 1);
|
|
46
|
+
vfloat32m1_t r = __riscv_vfredusum_vs_f32m4_f32m1(acc, init, vlmax);
|
|
47
|
+
return __riscv_vfmv_f_s_f32m1_f32(r);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Inner product of two fp32 vectors.
|
|
51
|
+
inline float inner_product(const float* x, const float* y, size_t d) {
|
|
52
|
+
const size_t vlmax = __riscv_vsetvlmax_e32m4();
|
|
53
|
+
vfloat32m4_t acc = __riscv_vfmv_v_f_f32m4(0.0f, vlmax);
|
|
54
|
+
size_t i = 0;
|
|
55
|
+
while (i < d) {
|
|
56
|
+
const size_t vl = __riscv_vsetvl_e32m4(d - i);
|
|
57
|
+
vfloat32m4_t vx = __riscv_vle32_v_f32m4(x + i, vl);
|
|
58
|
+
vfloat32m4_t vy = __riscv_vle32_v_f32m4(y + i, vl);
|
|
59
|
+
acc = __riscv_vfmacc_vv_f32m4_tu(acc, vx, vy, vl);
|
|
60
|
+
i += vl;
|
|
61
|
+
}
|
|
62
|
+
vfloat32m1_t init = __riscv_vfmv_s_f_f32m1(0.0f, 1);
|
|
63
|
+
vfloat32m1_t r = __riscv_vfredusum_vs_f32m4_f32m1(acc, init, vlmax);
|
|
64
|
+
return __riscv_vfmv_f_s_f32m1_f32(r);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
} // namespace rvv_kernel
|
|
68
|
+
} // namespace faiss
|