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
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#ifdef COMPILE_SIMD_RISCV_RVV
|
|
9
|
-
|
|
10
8
|
#define THE_SIMD_LEVEL SIMDLevel::RISCV_RVV
|
|
11
9
|
|
|
12
10
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
@@ -22,5 +20,3 @@
|
|
|
22
20
|
#include <faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h>
|
|
23
21
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
24
22
|
#include <faiss/impl/binary_hamming/IndexPQ_impl.h>
|
|
25
|
-
|
|
26
|
-
#endif // COMPILE_SIMD_RISCV_RVV
|
|
@@ -67,6 +67,66 @@ size_t run_scan_codes1(
|
|
|
67
67
|
return nup;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// Batched variant of run_scan_codes1 for the SQ scanners: distances four codes
|
|
71
|
+
// per step via distance_to_codes_batch_4, then applies the threshold and heap
|
|
72
|
+
// updates in id order so results match run_scan_codes1. No-selector path only.
|
|
73
|
+
template <class ScannerType, typename C, bool store_pairs>
|
|
74
|
+
size_t run_scan_codes4(
|
|
75
|
+
const ScannerType& scanner,
|
|
76
|
+
size_t list_size,
|
|
77
|
+
const uint8_t* codes,
|
|
78
|
+
const idx_t* ids,
|
|
79
|
+
ResultHandler& handler) {
|
|
80
|
+
size_t nup = 0;
|
|
81
|
+
size_t list_no = scanner.list_no;
|
|
82
|
+
size_t code_size = scanner.code_size;
|
|
83
|
+
float threshold = handler.threshold;
|
|
84
|
+
|
|
85
|
+
size_t j = 0;
|
|
86
|
+
for (; j + 4 <= list_size; j += 4) {
|
|
87
|
+
float dis[4];
|
|
88
|
+
scanner.distance_to_codes_batch_4(
|
|
89
|
+
codes,
|
|
90
|
+
codes + code_size,
|
|
91
|
+
codes + 2 * code_size,
|
|
92
|
+
codes + 3 * code_size,
|
|
93
|
+
dis[0],
|
|
94
|
+
dis[1],
|
|
95
|
+
dis[2],
|
|
96
|
+
dis[3]);
|
|
97
|
+
handler.stats.scan_cnt += 4;
|
|
98
|
+
for (size_t b = 0; b < 4; b++) {
|
|
99
|
+
if (C::cmp(threshold, dis[b])) {
|
|
100
|
+
int64_t id =
|
|
101
|
+
store_pairs ? lo_build(list_no, j + b) : ids[j + b];
|
|
102
|
+
if (handler.add_result(dis[b], id)) {
|
|
103
|
+
handler.stats.nheap_updates++;
|
|
104
|
+
nup++;
|
|
105
|
+
threshold = handler.threshold;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
codes += 4 * code_size;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// tail: the final < 4 codes, one at a time
|
|
113
|
+
for (; j < list_size; j++) {
|
|
114
|
+
handler.stats.scan_cnt++;
|
|
115
|
+
float dis = scanner.distance_to_code(codes);
|
|
116
|
+
if (C::cmp(threshold, dis)) {
|
|
117
|
+
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
118
|
+
if (handler.add_result(dis, id)) {
|
|
119
|
+
handler.stats.nheap_updates++;
|
|
120
|
+
nup++;
|
|
121
|
+
threshold = handler.threshold;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
codes += code_size;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return nup;
|
|
128
|
+
}
|
|
129
|
+
|
|
70
130
|
/*****************************************************************************
|
|
71
131
|
* The following functions dispatch runtime parameters to templates, with
|
|
72
132
|
* possibly some already-fixed templates.
|
|
@@ -136,6 +196,34 @@ size_t run_scan_codes_fix_C(
|
|
|
136
196
|
}
|
|
137
197
|
}
|
|
138
198
|
|
|
199
|
+
// Routing wrapper for the SQ scanners: the no-selector path takes the batched
|
|
200
|
+
// run_scan_codes4, the selector path stays on run_scan_codes1.
|
|
201
|
+
template <class C, class ScannerType>
|
|
202
|
+
size_t run_scan_codes4_fix_C(
|
|
203
|
+
const ScannerType& scanner,
|
|
204
|
+
size_t list_size,
|
|
205
|
+
const uint8_t* codes,
|
|
206
|
+
const idx_t* ids,
|
|
207
|
+
ResultHandler& handler) {
|
|
208
|
+
if (scanner.sel) {
|
|
209
|
+
if (scanner.store_pairs) {
|
|
210
|
+
return run_scan_codes1<ScannerType, C, true, true>(
|
|
211
|
+
scanner, list_size, codes, ids, handler);
|
|
212
|
+
} else {
|
|
213
|
+
return run_scan_codes1<ScannerType, C, false, true>(
|
|
214
|
+
scanner, list_size, codes, ids, handler);
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
if (scanner.store_pairs) {
|
|
218
|
+
return run_scan_codes4<ScannerType, C, true>(
|
|
219
|
+
scanner, list_size, codes, ids, handler);
|
|
220
|
+
} else {
|
|
221
|
+
return run_scan_codes4<ScannerType, C, false>(
|
|
222
|
+
scanner, list_size, codes, ids, handler);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
139
227
|
template <class ScannerType>
|
|
140
228
|
size_t run_scan_codes(
|
|
141
229
|
const ScannerType& scanner,
|
|
@@ -29,6 +29,10 @@ struct FastScanDistancePostProcessing {
|
|
|
29
29
|
/// QueryFactorsData subset for this context.
|
|
30
30
|
rabitq_utils::QueryFactorsData* query_factors = nullptr;
|
|
31
31
|
|
|
32
|
+
/// Multi-bit IVF RaBitQ: rotated query per (query, probe), d floats each,
|
|
33
|
+
/// indexed like query_factors (nullptr if unused).
|
|
34
|
+
float* rotated_q = nullptr;
|
|
35
|
+
|
|
32
36
|
/// The nprobe value used when allocating query_factors storage.
|
|
33
37
|
/// This is needed because the allocation size (n * nprobe) may use a
|
|
34
38
|
/// different nprobe than index->nprobe if search params override it.
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
* Portions 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
|
+
/*
|
|
9
|
+
* Portions Copyright 2026 Arm Limited and/or its affiliates
|
|
10
|
+
* <open-source-office@arm.com>
|
|
3
11
|
*
|
|
4
12
|
* This source code is licensed under the MIT license found in the
|
|
5
13
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -14,22 +22,14 @@
|
|
|
14
22
|
* Contains:
|
|
15
23
|
* - accumulate_fixed_blocks / pq4_accumulate_loop_fixed_scaler
|
|
16
24
|
* (search_1 multi-BB path, bbs > 32)
|
|
17
|
-
* -
|
|
18
|
-
* (QBS path, bbs == 32, 256-bit kernel only)
|
|
25
|
+
* - SIMD-level-selected QBS traversal (bbs == 32)
|
|
19
26
|
*
|
|
20
|
-
* The
|
|
21
|
-
*
|
|
22
|
-
* whose 512-bit types need explicit SIMD levels. The 512-bit QBS path
|
|
23
|
-
* lives in accumulate_loops_512.h, used by the AVX512 per-ISA TU.
|
|
27
|
+
* The default PQ4QBSKernel<SL> uses the 256-bit kernel. Architecture-specific
|
|
28
|
+
* headers may specialize it while reusing the traversal and QBS dispatch.
|
|
24
29
|
*
|
|
25
30
|
* All functions live in `namespace faiss` (not anonymous) so they can be
|
|
26
31
|
* shared by both the per-SIMD TU dispatcher (dispatching.h) and the old
|
|
27
32
|
* free-function search paths (pq4_fast_scan_search_1.cpp).
|
|
28
|
-
*
|
|
29
|
-
* The QBS helpers here always use pq4_kernel_qbs_256 (never 512-bit).
|
|
30
|
-
* This is required for the per-SIMD DD TUs where SINGLE_SIMD_LEVEL=NONE
|
|
31
|
-
* leaves 512-bit types empty. The old pq4_fast_scan_search_qbs.cpp
|
|
32
|
-
* continues to use decompose_qbs.h which includes both 256 and 512 paths.
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
#include <cassert>
|
|
@@ -37,7 +37,11 @@
|
|
|
37
37
|
#include <faiss/impl/FaissAssert.h>
|
|
38
38
|
#include <faiss/impl/fast_scan/LookupTableScaler.h>
|
|
39
39
|
#include <faiss/impl/fast_scan/kernels_simd256.h>
|
|
40
|
+
#if FAISS_SIMD_TU(ARM_NEON)
|
|
41
|
+
#include <faiss/impl/fast_scan/kernels_neon.h>
|
|
42
|
+
#endif
|
|
40
43
|
#include <faiss/impl/fast_scan/simd_result_handlers.h>
|
|
44
|
+
#include <faiss/utils/simd_levels.h>
|
|
41
45
|
|
|
42
46
|
namespace faiss {
|
|
43
47
|
|
|
@@ -112,15 +116,11 @@ void pq4_accumulate_loop_fixed_scaler(
|
|
|
112
116
|
}
|
|
113
117
|
|
|
114
118
|
/***************************************************************
|
|
115
|
-
* QBS path helpers (bbs == 32
|
|
119
|
+
* QBS path helpers (bbs == 32)
|
|
116
120
|
***************************************************************/
|
|
117
121
|
|
|
118
|
-
template <
|
|
119
|
-
|
|
120
|
-
SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
|
|
121
|
-
class ResultHandler,
|
|
122
|
-
class Scaler>
|
|
123
|
-
void accumulate_q_4step_256(
|
|
122
|
+
template <int QBS, SIMDLevel SL, class ResultHandler, class Scaler>
|
|
123
|
+
void accumulate_q_4step_for_simd(
|
|
124
124
|
size_t ntotal2,
|
|
125
125
|
int nsq,
|
|
126
126
|
const uint8_t* codes,
|
|
@@ -135,33 +135,31 @@ void accumulate_q_4step_256(
|
|
|
135
135
|
constexpr int SQ = Q1 + Q2 + Q3 + Q4;
|
|
136
136
|
|
|
137
137
|
for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
|
|
138
|
-
|
|
138
|
+
// Scaler as LinkageTag: see FixedStorageHandler.
|
|
139
|
+
FixedStorageHandler<SQ, 2, SL, Scaler> res2;
|
|
139
140
|
const uint8_t* LUT = LUT0;
|
|
140
|
-
|
|
141
|
+
PQ4QBSKernel<SL>::template run<Q1>(nsq, codes, LUT, res2, scaler);
|
|
141
142
|
LUT += Q1 * nsq * 16;
|
|
142
143
|
if (Q2 > 0) {
|
|
143
144
|
res2.set_block_origin(Q1, 0);
|
|
144
|
-
|
|
145
|
+
PQ4QBSKernel<SL>::template run<Q2>(nsq, codes, LUT, res2, scaler);
|
|
145
146
|
LUT += Q2 * nsq * 16;
|
|
146
147
|
}
|
|
147
148
|
if (Q3 > 0) {
|
|
148
149
|
res2.set_block_origin(Q1 + Q2, 0);
|
|
149
|
-
|
|
150
|
+
PQ4QBSKernel<SL>::template run<Q3>(nsq, codes, LUT, res2, scaler);
|
|
150
151
|
LUT += Q3 * nsq * 16;
|
|
151
152
|
}
|
|
152
153
|
if (Q4 > 0) {
|
|
153
154
|
res2.set_block_origin(Q1 + Q2 + Q3, 0);
|
|
154
|
-
|
|
155
|
+
PQ4QBSKernel<SL>::template run<Q4>(nsq, codes, LUT, res2, scaler);
|
|
155
156
|
}
|
|
156
157
|
res2.to_other_handler(res);
|
|
157
158
|
});
|
|
158
159
|
}
|
|
159
160
|
|
|
160
|
-
template <
|
|
161
|
-
|
|
162
|
-
class ResultHandler,
|
|
163
|
-
class Scaler>
|
|
164
|
-
void pq4_accumulate_loop_qbs_fixed_scaler_256(
|
|
161
|
+
template <SIMDLevel SL = SINGLE_SIMD_LEVEL, class ResultHandler, class Scaler>
|
|
162
|
+
void pq4_accumulate_loop_qbs_fixed_scaler_simd(
|
|
165
163
|
int qbs,
|
|
166
164
|
size_t ntotal2,
|
|
167
165
|
int nsq,
|
|
@@ -175,38 +173,37 @@ void pq4_accumulate_loop_qbs_fixed_scaler_256(
|
|
|
175
173
|
assert(is_aligned_pointer(LUT0));
|
|
176
174
|
|
|
177
175
|
switch (qbs) {
|
|
178
|
-
#define
|
|
176
|
+
#define FAISS_QBS_DISPATCH(QBS) \
|
|
179
177
|
case QBS: \
|
|
180
|
-
|
|
178
|
+
accumulate_q_4step_for_simd<QBS, SL>( \
|
|
181
179
|
ntotal2, nsq, codes, LUT0, res, scaler, block_stride); \
|
|
182
180
|
return;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
#undef
|
|
181
|
+
FAISS_QBS_DISPATCH(0x3333); // 12
|
|
182
|
+
FAISS_QBS_DISPATCH(0x2333); // 11
|
|
183
|
+
FAISS_QBS_DISPATCH(0x2233); // 10
|
|
184
|
+
FAISS_QBS_DISPATCH(0x333); // 9
|
|
185
|
+
FAISS_QBS_DISPATCH(0x2223); // 9
|
|
186
|
+
FAISS_QBS_DISPATCH(0x233); // 8
|
|
187
|
+
FAISS_QBS_DISPATCH(0x1223); // 8
|
|
188
|
+
FAISS_QBS_DISPATCH(0x223); // 7
|
|
189
|
+
FAISS_QBS_DISPATCH(0x34); // 7
|
|
190
|
+
FAISS_QBS_DISPATCH(0x133); // 7
|
|
191
|
+
FAISS_QBS_DISPATCH(0x6); // 6
|
|
192
|
+
FAISS_QBS_DISPATCH(0x33); // 6
|
|
193
|
+
FAISS_QBS_DISPATCH(0x123); // 6
|
|
194
|
+
FAISS_QBS_DISPATCH(0x222); // 6
|
|
195
|
+
FAISS_QBS_DISPATCH(0x23); // 5
|
|
196
|
+
FAISS_QBS_DISPATCH(0x5); // 5
|
|
197
|
+
FAISS_QBS_DISPATCH(0x13); // 4
|
|
198
|
+
FAISS_QBS_DISPATCH(0x22); // 4
|
|
199
|
+
FAISS_QBS_DISPATCH(0x4); // 4
|
|
200
|
+
FAISS_QBS_DISPATCH(0x3); // 3
|
|
201
|
+
FAISS_QBS_DISPATCH(0x21); // 3
|
|
202
|
+
FAISS_QBS_DISPATCH(0x2); // 2
|
|
203
|
+
FAISS_QBS_DISPATCH(0x1); // 1
|
|
204
|
+
#undef FAISS_QBS_DISPATCH
|
|
207
205
|
}
|
|
208
206
|
|
|
209
|
-
// Default: qbs not known at compile time
|
|
210
207
|
for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t j0) {
|
|
211
208
|
const uint8_t* LUT = LUT0;
|
|
212
209
|
int qi = qbs;
|
|
@@ -215,16 +212,16 @@ void pq4_accumulate_loop_qbs_fixed_scaler_256(
|
|
|
215
212
|
int nq = qi & 15;
|
|
216
213
|
qi >>= 4;
|
|
217
214
|
res.set_block_origin(i0, j0);
|
|
218
|
-
#define
|
|
219
|
-
case NQ:
|
|
220
|
-
|
|
215
|
+
#define FAISS_NQ_DISPATCH(NQ) \
|
|
216
|
+
case NQ: \
|
|
217
|
+
PQ4QBSKernel<SL>::template run<NQ>(nsq, codes, LUT, res, scaler); \
|
|
221
218
|
break
|
|
222
219
|
switch (nq) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
#undef
|
|
220
|
+
FAISS_NQ_DISPATCH(1);
|
|
221
|
+
FAISS_NQ_DISPATCH(2);
|
|
222
|
+
FAISS_NQ_DISPATCH(3);
|
|
223
|
+
FAISS_NQ_DISPATCH(4);
|
|
224
|
+
#undef FAISS_NQ_DISPATCH
|
|
228
225
|
default:
|
|
229
226
|
FAISS_THROW_FMT("accumulate nq=%d not instantiated", nq);
|
|
230
227
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
* Portions 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
|
+
/*
|
|
9
|
+
* Portions Copyright 2026 Arm Limited and/or its affiliates
|
|
10
|
+
* <open-source-office@arm.com>
|
|
3
11
|
*
|
|
4
12
|
* This source code is licensed under the MIT license found in the
|
|
5
13
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -23,8 +31,6 @@
|
|
|
23
31
|
* dispatching.h's conditional include.
|
|
24
32
|
*/
|
|
25
33
|
|
|
26
|
-
#if defined(COMPILE_SIMD_AVX512) && defined(__AVX512F__)
|
|
27
|
-
|
|
28
34
|
#include <cassert>
|
|
29
35
|
|
|
30
36
|
#include <faiss/impl/FaissAssert.h>
|
|
@@ -169,17 +175,10 @@ void pq4_accumulate_loop_qbs_fixed_scaler_512(
|
|
|
169
175
|
|
|
170
176
|
// Fallback for unknown QBS values: use 256-bit path.
|
|
171
177
|
// This is rare — pq4_preferred_qbs() covers all values above.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
} else {
|
|
177
|
-
NormTableScaler<SIMDLevel::AVX2> scaler_avx2(scaler.scale_int);
|
|
178
|
-
pq4_accumulate_loop_qbs_fixed_scaler_256<SIMDLevel::AVX2>(
|
|
179
|
-
qbs, ntotal2, nsq, codes, LUT0, res, scaler_avx2, block_stride);
|
|
180
|
-
}
|
|
178
|
+
// The caller's AVX512-level scaler gives these instantiations symbol names
|
|
179
|
+
// that the AVX2 TU does not emit.
|
|
180
|
+
pq4_accumulate_loop_qbs_fixed_scaler_simd<SIMDLevel::AVX2>(
|
|
181
|
+
qbs, ntotal2, nsq, codes, LUT0, res, scaler, block_stride);
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
} // namespace faiss
|
|
184
|
-
|
|
185
|
-
#endif // COMPILE_SIMD_AVX512 && __AVX512F__
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
* Portions 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
|
+
/*
|
|
9
|
+
* Portions Copyright 2026 Arm Limited and/or its affiliates
|
|
10
|
+
* <open-source-office@arm.com>
|
|
3
11
|
*
|
|
4
12
|
* This source code is licensed under the MIT license found in the
|
|
5
13
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -12,7 +20,11 @@
|
|
|
12
20
|
#include <faiss/impl/FaissAssert.h>
|
|
13
21
|
#include <faiss/impl/fast_scan/kernels_simd256.h>
|
|
14
22
|
#include <faiss/impl/fast_scan/kernels_simd512.h>
|
|
23
|
+
#if FAISS_SIMD_TU(ARM_NEON)
|
|
24
|
+
#include <faiss/impl/fast_scan/kernels_neon.h>
|
|
25
|
+
#endif
|
|
15
26
|
#include <faiss/impl/fast_scan/simd_result_handlers.h>
|
|
27
|
+
#include <faiss/utils/simd_levels.h>
|
|
16
28
|
|
|
17
29
|
namespace faiss {
|
|
18
30
|
|
|
@@ -20,7 +32,7 @@ using namespace simd_result_handlers;
|
|
|
20
32
|
|
|
21
33
|
/*
|
|
22
34
|
* Unified kernel: selects 256-bit vs 512-bit path based on
|
|
23
|
-
* compile-time __AVX512F__ guard.
|
|
35
|
+
* compile-time COMPILE_SIMD_AVX512 && __AVX512F__ guard.
|
|
24
36
|
*
|
|
25
37
|
* KernelSL selects the SIMD type width used for the inner accumulation
|
|
26
38
|
* loop. In DD mode the caller passes the dispatch level so the kernel
|
|
@@ -37,66 +49,20 @@ void kernel_accumulate_block(
|
|
|
37
49
|
const uint8_t* LUT,
|
|
38
50
|
ResultHandler& res,
|
|
39
51
|
const Scaler& scaler) {
|
|
40
|
-
#
|
|
52
|
+
#if FAISS_SIMD_TU(AVX512)
|
|
41
53
|
if constexpr (
|
|
42
54
|
KernelSL == SIMDLevel::AVX512 ||
|
|
43
55
|
KernelSL == SIMDLevel::AVX512_VPOPCNT ||
|
|
44
56
|
KernelSL == SIMDLevel::AVX512_SPR) {
|
|
45
57
|
pq4_kernel_qbs_512<NQ>(nsq, codes, LUT, res, scaler);
|
|
46
58
|
} else {
|
|
47
|
-
|
|
59
|
+
PQ4QBSKernel<KernelSL>::template run<NQ>(nsq, codes, LUT, res, scaler);
|
|
48
60
|
}
|
|
49
61
|
#else
|
|
50
|
-
|
|
62
|
+
PQ4QBSKernel<KernelSL>::template run<NQ>(nsq, codes, LUT, res, scaler);
|
|
51
63
|
#endif
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
// handle at most 4 blocks of queries
|
|
55
|
-
template <
|
|
56
|
-
int QBS,
|
|
57
|
-
SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
|
|
58
|
-
class ResultHandler,
|
|
59
|
-
class Scaler>
|
|
60
|
-
void accumulate_q_4step(
|
|
61
|
-
size_t ntotal2,
|
|
62
|
-
int nsq,
|
|
63
|
-
const uint8_t* codes,
|
|
64
|
-
const uint8_t* LUT0,
|
|
65
|
-
ResultHandler& res,
|
|
66
|
-
const Scaler& scaler,
|
|
67
|
-
size_t block_stride) {
|
|
68
|
-
constexpr int Q1 = QBS & 15;
|
|
69
|
-
constexpr int Q2 = (QBS >> 4) & 15;
|
|
70
|
-
constexpr int Q3 = (QBS >> 8) & 15;
|
|
71
|
-
constexpr int Q4 = (QBS >> 12) & 15;
|
|
72
|
-
constexpr int SQ = Q1 + Q2 + Q3 + Q4;
|
|
73
|
-
|
|
74
|
-
for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t) {
|
|
75
|
-
FixedStorageHandler<SQ, 2, KernelSL> res2;
|
|
76
|
-
const uint8_t* LUT = LUT0;
|
|
77
|
-
kernel_accumulate_block<Q1, KernelSL>(nsq, codes, LUT, res2, scaler);
|
|
78
|
-
LUT += Q1 * nsq * 16;
|
|
79
|
-
if (Q2 > 0) {
|
|
80
|
-
res2.set_block_origin(Q1, 0);
|
|
81
|
-
kernel_accumulate_block<Q2, KernelSL>(
|
|
82
|
-
nsq, codes, LUT, res2, scaler);
|
|
83
|
-
LUT += Q2 * nsq * 16;
|
|
84
|
-
}
|
|
85
|
-
if (Q3 > 0) {
|
|
86
|
-
res2.set_block_origin(Q1 + Q2, 0);
|
|
87
|
-
kernel_accumulate_block<Q3, KernelSL>(
|
|
88
|
-
nsq, codes, LUT, res2, scaler);
|
|
89
|
-
LUT += Q3 * nsq * 16;
|
|
90
|
-
}
|
|
91
|
-
if (Q4 > 0) {
|
|
92
|
-
res2.set_block_origin(Q1 + Q2 + Q3, 0);
|
|
93
|
-
kernel_accumulate_block<Q4, KernelSL>(
|
|
94
|
-
nsq, codes, LUT, res2, scaler);
|
|
95
|
-
}
|
|
96
|
-
res2.to_other_handler(res);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
66
|
template <
|
|
101
67
|
int NQ,
|
|
102
68
|
SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
|
|
@@ -149,82 +115,4 @@ void accumulate(
|
|
|
149
115
|
#undef DISPATCH
|
|
150
116
|
}
|
|
151
117
|
|
|
152
|
-
template <
|
|
153
|
-
SIMDLevel KernelSL = SINGLE_SIMD_LEVEL,
|
|
154
|
-
class ResultHandler,
|
|
155
|
-
class Scaler>
|
|
156
|
-
void pq4_accumulate_loop_qbs_fixed_scaler(
|
|
157
|
-
int qbs,
|
|
158
|
-
size_t ntotal2,
|
|
159
|
-
int nsq,
|
|
160
|
-
const uint8_t* codes,
|
|
161
|
-
const uint8_t* LUT0,
|
|
162
|
-
ResultHandler& res,
|
|
163
|
-
const Scaler& scaler,
|
|
164
|
-
size_t block_stride = 0) {
|
|
165
|
-
assert(nsq % 2 == 0);
|
|
166
|
-
assert(is_aligned_pointer(codes));
|
|
167
|
-
assert(is_aligned_pointer(LUT0));
|
|
168
|
-
|
|
169
|
-
// try out optimized versions
|
|
170
|
-
switch (qbs) {
|
|
171
|
-
#define DISPATCH(QBS) \
|
|
172
|
-
case QBS: \
|
|
173
|
-
accumulate_q_4step<QBS, KernelSL>( \
|
|
174
|
-
ntotal2, nsq, codes, LUT0, res, scaler, block_stride); \
|
|
175
|
-
return;
|
|
176
|
-
DISPATCH(0x3333); // 12
|
|
177
|
-
DISPATCH(0x2333); // 11
|
|
178
|
-
DISPATCH(0x2233); // 10
|
|
179
|
-
DISPATCH(0x333); // 9
|
|
180
|
-
DISPATCH(0x2223); // 9
|
|
181
|
-
DISPATCH(0x233); // 8
|
|
182
|
-
DISPATCH(0x1223); // 8
|
|
183
|
-
DISPATCH(0x223); // 7
|
|
184
|
-
DISPATCH(0x34); // 7
|
|
185
|
-
DISPATCH(0x133); // 7
|
|
186
|
-
DISPATCH(0x6); // 6
|
|
187
|
-
DISPATCH(0x33); // 6
|
|
188
|
-
DISPATCH(0x123); // 6
|
|
189
|
-
DISPATCH(0x222); // 6
|
|
190
|
-
DISPATCH(0x23); // 5
|
|
191
|
-
DISPATCH(0x5); // 5
|
|
192
|
-
DISPATCH(0x13); // 4
|
|
193
|
-
DISPATCH(0x22); // 4
|
|
194
|
-
DISPATCH(0x4); // 4
|
|
195
|
-
DISPATCH(0x3); // 3
|
|
196
|
-
DISPATCH(0x21); // 3
|
|
197
|
-
DISPATCH(0x2); // 2
|
|
198
|
-
DISPATCH(0x1); // 1
|
|
199
|
-
#undef DISPATCH
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// default implementation where qbs is not known at compile time
|
|
203
|
-
for_each_block<32>(ntotal2, codes, block_stride, res, [&](size_t j0) {
|
|
204
|
-
const uint8_t* LUT = LUT0;
|
|
205
|
-
int qi = qbs;
|
|
206
|
-
int i0 = 0;
|
|
207
|
-
while (qi) {
|
|
208
|
-
int nq = qi & 15;
|
|
209
|
-
qi >>= 4;
|
|
210
|
-
res.set_block_origin(i0, j0);
|
|
211
|
-
#define DISPATCH(NQ) \
|
|
212
|
-
case NQ: \
|
|
213
|
-
kernel_accumulate_block<NQ, KernelSL>(nsq, codes, LUT, res, scaler); \
|
|
214
|
-
break
|
|
215
|
-
switch (nq) {
|
|
216
|
-
DISPATCH(1);
|
|
217
|
-
DISPATCH(2);
|
|
218
|
-
DISPATCH(3);
|
|
219
|
-
DISPATCH(4);
|
|
220
|
-
#undef DISPATCH
|
|
221
|
-
default:
|
|
222
|
-
FAISS_THROW_FMT("accumulate nq=%d not instantiated", nq);
|
|
223
|
-
}
|
|
224
|
-
i0 += nq;
|
|
225
|
-
LUT += nq * nsq * 16;
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
118
|
} // namespace faiss
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
* Portions 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
|
+
/*
|
|
9
|
+
* Portions Copyright 2026 Arm Limited and/or its affiliates
|
|
10
|
+
* <open-source-office@arm.com>
|
|
3
11
|
*
|
|
4
12
|
* This source code is licensed under the MIT license found in the
|
|
5
13
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -20,8 +28,8 @@
|
|
|
20
28
|
* #define THE_LEVEL_TO_DISPATCH SIMDLevel::AVX2
|
|
21
29
|
* #include <faiss/impl/fast_scan/dispatching.h>
|
|
22
30
|
*
|
|
23
|
-
* Kernel helpers come from accumulate_loops.h (search_1 multi-BB path
|
|
24
|
-
*
|
|
31
|
+
* Kernel helpers come from accumulate_loops.h (search_1 multi-BB path and
|
|
32
|
+
* SIMD-level-selected QBS path) and accumulate_loops_512.h (QBS 512-bit path,
|
|
25
33
|
* AVX512 TU only).
|
|
26
34
|
*/
|
|
27
35
|
|
|
@@ -35,7 +43,7 @@
|
|
|
35
43
|
#include <faiss/impl/fast_scan/fast_scan.h>
|
|
36
44
|
#include <faiss/utils/simd_levels.h>
|
|
37
45
|
|
|
38
|
-
#if
|
|
46
|
+
#if FAISS_SIMD_TU(AVX512)
|
|
39
47
|
#include <faiss/impl/fast_scan/accumulate_loops_512.h>
|
|
40
48
|
#endif
|
|
41
49
|
|
|
@@ -107,7 +115,7 @@ struct ScannerMixIn : FastScanCodeScanner {
|
|
|
107
115
|
const uint8_t* LUT,
|
|
108
116
|
int pq2x4_scale,
|
|
109
117
|
size_t block_stride) override {
|
|
110
|
-
#if
|
|
118
|
+
#if FAISS_SIMD_TU(AVX512)
|
|
111
119
|
constexpr bool use_avx512_qbs =
|
|
112
120
|
(THE_LEVEL_TO_DISPATCH == SIMDLevel::AVX512 ||
|
|
113
121
|
THE_LEVEL_TO_DISPATCH == SIMDLevel::AVX512_SPR);
|
|
@@ -115,18 +123,14 @@ struct ScannerMixIn : FastScanCodeScanner {
|
|
|
115
123
|
constexpr bool use_avx512_qbs = false;
|
|
116
124
|
#endif
|
|
117
125
|
if constexpr (use_avx512_qbs) {
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
// throughput gain but pays extra per-block LUT-assembly and
|
|
121
|
-
// cross-lane reduction overhead (measured ~14% search regression
|
|
122
|
-
// for PQ8x4fs / PQ16x4fs). Route those CPUs to the 256-bit (AVX2)
|
|
123
|
-
// QBS kernel instead -- same output, no downside on Zen 4. This is
|
|
124
|
-
// a process-constant runtime branch, hoisted out of the inner
|
|
125
|
-
// accumulate loop. Intel AVX-512 keeps the 512-bit kernel.
|
|
126
|
+
// Zen 4 runs 512-bit ops on a 256-bit datapath, so the 512-bit QBS
|
|
127
|
+
// kernel is slower there; use the AVX2 kernel.
|
|
126
128
|
if (SIMDConfig::avx512_split) {
|
|
129
|
+
// THE_LEVEL_TO_DISPATCH scalers give these AVX2-loop
|
|
130
|
+
// instantiations symbol names that the AVX2 TU does not emit.
|
|
127
131
|
if (pq2x4_scale) {
|
|
128
|
-
NormTableScaler<
|
|
129
|
-
|
|
132
|
+
NormTableScaler<THE_LEVEL_TO_DISPATCH> scaler(pq2x4_scale);
|
|
133
|
+
pq4_accumulate_loop_qbs_fixed_scaler_simd<SIMDLevel::AVX2>(
|
|
130
134
|
qbs,
|
|
131
135
|
nb,
|
|
132
136
|
nsq,
|
|
@@ -136,8 +140,8 @@ struct ScannerMixIn : FastScanCodeScanner {
|
|
|
136
140
|
scaler,
|
|
137
141
|
block_stride);
|
|
138
142
|
} else {
|
|
139
|
-
DummyScaler<
|
|
140
|
-
|
|
143
|
+
DummyScaler<THE_LEVEL_TO_DISPATCH> dummy;
|
|
144
|
+
pq4_accumulate_loop_qbs_fixed_scaler_simd<SIMDLevel::AVX2>(
|
|
141
145
|
qbs,
|
|
142
146
|
nb,
|
|
143
147
|
nsq,
|
|
@@ -174,7 +178,8 @@ struct ScannerMixIn : FastScanCodeScanner {
|
|
|
174
178
|
} else {
|
|
175
179
|
if (pq2x4_scale) {
|
|
176
180
|
NormTableScaler<THE_LEVEL_TO_DISPATCH> scaler(pq2x4_scale);
|
|
177
|
-
|
|
181
|
+
pq4_accumulate_loop_qbs_fixed_scaler_simd<
|
|
182
|
+
THE_LEVEL_TO_DISPATCH>(
|
|
178
183
|
qbs,
|
|
179
184
|
nb,
|
|
180
185
|
nsq,
|
|
@@ -185,7 +190,8 @@ struct ScannerMixIn : FastScanCodeScanner {
|
|
|
185
190
|
block_stride);
|
|
186
191
|
} else {
|
|
187
192
|
DummyScaler<THE_LEVEL_TO_DISPATCH> dummy;
|
|
188
|
-
|
|
193
|
+
pq4_accumulate_loop_qbs_fixed_scaler_simd<
|
|
194
|
+
THE_LEVEL_TO_DISPATCH>(
|
|
189
195
|
qbs,
|
|
190
196
|
nb,
|
|
191
197
|
nsq,
|