faiss 0.6.2 → 0.6.4
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 +8 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +3 -1
- data/vendor/faiss/faiss/Clustering.cpp +9 -1
- data/vendor/faiss/faiss/Clustering.h +8 -0
- data/vendor/faiss/faiss/IVFlib.cpp +14 -3
- data/vendor/faiss/faiss/Index.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +24 -4
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +16 -145
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +0 -6
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +8 -18
- data/vendor/faiss/faiss/IndexBinaryIVF.h +8 -1
- data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
- data/vendor/faiss/faiss/IndexEDEN.h +57 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +21 -54
- data/vendor/faiss/faiss/IndexFlat.h +2 -2
- data/vendor/faiss/faiss/IndexHNSW.cpp +311 -102
- data/vendor/faiss/faiss/IndexHNSW.h +31 -7
- data/vendor/faiss/faiss/IndexIDMap.cpp +26 -8
- data/vendor/faiss/faiss/IndexIDMap.h +2 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +36 -10
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
- data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +49 -23
- data/vendor/faiss/faiss/IndexIVFPQ.h +11 -0
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +19 -49
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +9 -2
- data/vendor/faiss/faiss/IndexNSG.cpp +7 -2
- data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
- data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
- data/vendor/faiss/faiss/IndexShards.cpp +5 -5
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +6 -5
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
- data/vendor/faiss/faiss/SuperKMeans.cpp +286 -247
- data/vendor/faiss/faiss/SuperKMeans.h +33 -2
- data/vendor/faiss/faiss/VectorTransform.cpp +71 -2
- data/vendor/faiss/faiss/VectorTransform.h +3 -0
- data/vendor/faiss/faiss/clone_index.cpp +8 -0
- data/vendor/faiss/faiss/factory_tools.cpp +47 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +1 -5
- data/vendor/faiss/faiss/gpu/GpuDistance.h +2 -5
- data/vendor/faiss/faiss/gpu/GpuIndex.h +38 -16
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +71 -1
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +1 -5
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +7 -4
- data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
- data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +528 -267
- data/vendor/faiss/faiss/impl/HNSW.h +46 -7
- data/vendor/faiss/faiss/impl/IDSelector.h +44 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/impl/NNDescent.cpp +10 -3
- data/vendor/faiss/faiss/impl/NSG.cpp +3 -1
- data/vendor/faiss/faiss/impl/Panorama.h +20 -9
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +38 -26
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +45 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +239 -72
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +66 -4
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +4 -13
- data/vendor/faiss/faiss/impl/ResultHandler.h +34 -34
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +287 -84
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +26 -10
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +22 -2
- data/vendor/faiss/faiss/impl/VisitedTable.h +20 -0
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +90 -14
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/expanded_scanners.h +5 -1
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +1 -0
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +35 -2
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
- data/vendor/faiss/faiss/impl/index_read.cpp +491 -50
- data/vendor/faiss/faiss/impl/index_write.cpp +86 -30
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
- data/vendor/faiss/faiss/impl/platform_macros.h +3 -1
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
- data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +73 -39
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +4 -4
- data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +887 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +2 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +9 -8
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +90 -24
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +30 -30
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +4 -5
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +101 -34
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +169 -13
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +125 -26
- data/vendor/faiss/faiss/impl/simd_dispatch.h +70 -31
- data/vendor/faiss/faiss/index_factory.cpp +40 -7
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +9 -6
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +29 -8
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +47 -5
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +23 -3
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +4 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +10 -4
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +2 -1
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
- data/vendor/faiss/faiss/utils/distances.cpp +30 -11
- data/vendor/faiss/faiss/utils/distances_dispatch.h +30 -24
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +1 -1
- data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -3
- data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
- data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +16 -10
- data/vendor/faiss/faiss/utils/hamming.h +10 -1
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +14 -3
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_vpopcnt.cpp +24 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/{hamming_computer-avx512_spr.h → hamming_computer-avx512_vpopcnt.h} +85 -24
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +141 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
- data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +194 -30
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +198 -18
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +330 -40
- data/vendor/faiss/faiss/utils/simd_impl/{rabitq_avx512_spr.cpp → rabitq_avx512_vpopcnt.cpp} +112 -23
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +2 -7
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +6 -1
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_sve.cpp +34 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +196 -47
- data/vendor/faiss/faiss/utils/simd_levels.h +33 -8
- data/vendor/faiss/faiss/utils/utils.cpp +9 -27
- metadata +21 -5
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +0 -15
|
@@ -280,7 +280,7 @@ void compute_1_code(const ProductQuantizer& pq, const float* x, uint8_t* code) {
|
|
|
280
280
|
} // namespace
|
|
281
281
|
|
|
282
282
|
void ProductQuantizer::compute_code(const float* x, uint8_t* code) const {
|
|
283
|
-
|
|
283
|
+
with_simd_level_with_sve([&]<SIMDLevel SL>() {
|
|
284
284
|
switch (nbits) {
|
|
285
285
|
case 8:
|
|
286
286
|
compute_1_code<PQEncoder8, SL>(*this, x, code);
|
|
@@ -294,7 +294,7 @@ void ProductQuantizer::compute_code(const float* x, uint8_t* code) const {
|
|
|
294
294
|
compute_1_code<PQEncoderGeneric, SL>(*this, x, code);
|
|
295
295
|
break;
|
|
296
296
|
}
|
|
297
|
-
}); //
|
|
297
|
+
}); // with_simd_level_with_sve
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
template <class PQDecoder>
|
|
@@ -442,7 +442,7 @@ void ProductQuantizer::compute_codes(const float* x, uint8_t* codes, size_t n)
|
|
|
442
442
|
|
|
443
443
|
void ProductQuantizer::compute_distance_table(const float* x, float* dis_table)
|
|
444
444
|
const {
|
|
445
|
-
|
|
445
|
+
with_simd_level_with_sve([&]<SIMDLevel SL>() {
|
|
446
446
|
if (transposed_centroids.empty()) {
|
|
447
447
|
// use regular version
|
|
448
448
|
for (size_t m = 0; m < M; m++) {
|
|
@@ -824,7 +824,7 @@ void ProductQuantizer::compute_sdc_table() {
|
|
|
824
824
|
sdc_table.resize(M * ksub * ksub);
|
|
825
825
|
|
|
826
826
|
if (dsub < 4) {
|
|
827
|
-
|
|
827
|
+
with_simd_level_with_sve([&]<SIMDLevel SL>() {
|
|
828
828
|
#pragma omp parallel for
|
|
829
829
|
for (int64_t mk = 0; mk < static_cast<int64_t>(M * ksub); mk++) {
|
|
830
830
|
// allow omp to schedule in a more fine-grained way
|
|
@@ -862,32 +862,44 @@ void ProductQuantizer::search_sdc(
|
|
|
862
862
|
size_t k = res->k;
|
|
863
863
|
int64_t nq_signed = nq;
|
|
864
864
|
|
|
865
|
-
#pragma omp parallel
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
865
|
+
#pragma omp parallel
|
|
866
|
+
{
|
|
867
|
+
// One allocation per OMP thread instead of one per query.
|
|
868
|
+
std::vector<const float*> q_row(M);
|
|
869
|
+
#pragma omp for
|
|
870
|
+
for (int64_t i = 0; i < nq_signed; i++) {
|
|
871
|
+
idx_t* heap_ids = res->ids + i * k;
|
|
872
|
+
float* heap_dis = res->val + i * k;
|
|
873
|
+
const uint8_t* qcode = qcodes + i * code_size;
|
|
874
|
+
|
|
875
|
+
if (init_finalize_heap)
|
|
876
|
+
maxheap_heapify(k, heap_dis, heap_ids);
|
|
877
|
+
|
|
878
|
+
// Precompute per-subquantizer row pointers: q_row[m] points to
|
|
879
|
+
// sdc_table[m*ksub^2 + qcode[m]*ksub], eliminating M
|
|
880
|
+
// multiplications and M pointer advances per database vector in the
|
|
881
|
+
// j-loop.
|
|
882
|
+
const float* sdc = sdc_table.data();
|
|
879
883
|
for (size_t m = 0; m < M; m++) {
|
|
880
|
-
|
|
881
|
-
|
|
884
|
+
q_row[m] = sdc + m * (size_t)(ksub * ksub) +
|
|
885
|
+
(size_t)qcode[m] * ksub;
|
|
882
886
|
}
|
|
883
|
-
|
|
884
|
-
|
|
887
|
+
|
|
888
|
+
const uint8_t* bcode = bcodes;
|
|
889
|
+
for (size_t j = 0; j < nb; j++) {
|
|
890
|
+
float dis = 0;
|
|
891
|
+
for (size_t m = 0; m < M; m++) {
|
|
892
|
+
dis += q_row[m][bcode[m]];
|
|
893
|
+
}
|
|
894
|
+
if (dis < heap_dis[0]) {
|
|
895
|
+
maxheap_replace_top(k, heap_dis, heap_ids, dis, j);
|
|
896
|
+
}
|
|
897
|
+
bcode += code_size;
|
|
885
898
|
}
|
|
886
|
-
bcode += code_size;
|
|
887
|
-
}
|
|
888
899
|
|
|
889
|
-
|
|
890
|
-
|
|
900
|
+
if (init_finalize_heap)
|
|
901
|
+
maxheap_reorder(k, heap_dis, heap_ids);
|
|
902
|
+
}
|
|
891
903
|
}
|
|
892
904
|
}
|
|
893
905
|
|
|
@@ -188,46 +188,54 @@ QueryFactorsData compute_query_factors(
|
|
|
188
188
|
|
|
189
189
|
const float inv_d_sqrt = 1.0f / std::sqrt(static_cast<float>(d));
|
|
190
190
|
|
|
191
|
-
// Compute quantization range
|
|
192
|
-
float v_min = std::numeric_limits<float>::max();
|
|
193
|
-
float v_max = std::numeric_limits<float>::lowest();
|
|
194
|
-
|
|
195
191
|
const float* rq = rotated_q.data();
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
v_min = -v_radius;
|
|
200
|
-
v_max = v_radius;
|
|
201
|
-
} else {
|
|
202
|
-
for (size_t i = 0; i < d; i++) {
|
|
203
|
-
const float v_q = rq[i];
|
|
204
|
-
v_min = std::min(v_min, v_q);
|
|
205
|
-
v_max = std::max(v_max, v_q);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Quantize the query
|
|
210
|
-
const uint8_t max_code = (1 << qb) - 1;
|
|
211
|
-
const float delta = (v_max - v_min) / max_code;
|
|
212
|
-
const float inv_delta = 1.0f / delta;
|
|
213
|
-
|
|
214
|
-
rotated_qq.resize(d);
|
|
192
|
+
float v_min;
|
|
193
|
+
float v_max;
|
|
194
|
+
float delta;
|
|
215
195
|
size_t sum_qq = 0;
|
|
216
196
|
int64_t sum2_signed_odd_int = 0;
|
|
217
|
-
|
|
197
|
+
const uint8_t max_code = (1 << qb) - 1;
|
|
198
|
+
rotated_qq.resize(d);
|
|
218
199
|
uint8_t* rqq = rotated_qq.data();
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
200
|
+
|
|
201
|
+
// Select the SIMD implementation once for both range computation and
|
|
202
|
+
// quantization. This function runs once per query/probe pair.
|
|
203
|
+
with_selected_simd_levels<rabitq::RABITQ_QUANTIZATION_SIMD_LEVELS>(
|
|
204
|
+
[&]<SIMDLevel SL>() {
|
|
205
|
+
if (centered) {
|
|
206
|
+
const float z_max = Z_MAX_BY_QB[qb - 1];
|
|
207
|
+
const float v_radius =
|
|
208
|
+
z_max * std::sqrt(query_factors.qr_to_c_L2sqr / d);
|
|
209
|
+
v_min = -v_radius;
|
|
210
|
+
v_max = v_radius;
|
|
211
|
+
} else {
|
|
212
|
+
v_min = std::numeric_limits<float>::max();
|
|
213
|
+
v_max = std::numeric_limits<float>::lowest();
|
|
214
|
+
rabitq::minmax_values<SL>(rq, d, v_min, v_max);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
delta = (v_max - v_min) / max_code;
|
|
218
|
+
// A constant (or zero-norm) query has delta == 0. Preserve the
|
|
219
|
+
// scalar path's centered correction terms while avoiding
|
|
220
|
+
// 0 * inf during quantization.
|
|
221
|
+
if (delta <= 0.0f) {
|
|
222
|
+
memset(rqq, 0, d * sizeof(uint8_t));
|
|
223
|
+
if (centered) {
|
|
224
|
+
sum2_signed_odd_int = int64_t(d) * max_code * max_code;
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
rabitq::quantize_query_values<SL>(
|
|
228
|
+
rq,
|
|
229
|
+
d,
|
|
230
|
+
v_min,
|
|
231
|
+
1.0f / delta,
|
|
232
|
+
max_code,
|
|
233
|
+
centered,
|
|
234
|
+
rqq,
|
|
235
|
+
sum_qq,
|
|
236
|
+
sum2_signed_odd_int);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
231
239
|
|
|
232
240
|
// Compute query factors
|
|
233
241
|
query_factors.c1 = 2 * delta * inv_d_sqrt;
|
|
@@ -321,7 +329,7 @@ float compute_full_multibit_distance(
|
|
|
321
329
|
size_t d,
|
|
322
330
|
size_t ex_bits,
|
|
323
331
|
MetricType metric_type) {
|
|
324
|
-
return with_selected_simd_levels<
|
|
332
|
+
return with_selected_simd_levels<AVAILABLE_SIMD_LEVELS_BASE_WITH_VPOPCNT>(
|
|
325
333
|
[&]<SIMDLevel SL>() {
|
|
326
334
|
return compute_full_multibit_distance<SL>(
|
|
327
335
|
sign_bits,
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#include <faiss/utils/rabitq_simd.h>
|
|
14
14
|
#include <faiss/utils/simd_levels.h>
|
|
15
15
|
#include <algorithm>
|
|
16
|
+
#include <cassert>
|
|
16
17
|
#include <cstddef>
|
|
17
18
|
#include <cstdint>
|
|
18
19
|
#include <cstring>
|
|
@@ -86,6 +87,40 @@ struct QueryFactorsData {
|
|
|
86
87
|
*/
|
|
87
88
|
FAISS_API extern const float Z_MAX_BY_QB[8];
|
|
88
89
|
|
|
90
|
+
/** Fast half-away rounding for non-negative RaBitQ quantization values.
|
|
91
|
+
*
|
|
92
|
+
* Contract: x must be finite, non-NaN, and in [0, 255.5). This is not a
|
|
93
|
+
* bit-exact replacement for roundf within a few ulps below k + 0.5, where the
|
|
94
|
+
* addition may round across the tie. It is intended only for RaBitQ LUT
|
|
95
|
+
* quantization paths where a +/- 1 code difference at those boundaries is
|
|
96
|
+
* acceptable.
|
|
97
|
+
*/
|
|
98
|
+
inline uint8_t round_nonnegative_to_uint8(float x) {
|
|
99
|
+
assert(x == x);
|
|
100
|
+
assert(x >= 0.0f);
|
|
101
|
+
assert(x < 255.5f);
|
|
102
|
+
return rabitq::round_nonnegative_byte_scalar(x);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Same as round_nonnegative_to_uint8 for uint16 RaBitQ bias values. */
|
|
106
|
+
inline uint16_t round_nonnegative_to_uint16(float x) {
|
|
107
|
+
assert(x == x);
|
|
108
|
+
assert(x >= 0.0f);
|
|
109
|
+
assert(x < 65535.5f);
|
|
110
|
+
return static_cast<uint16_t>(static_cast<int>(x + 0.5f));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Fast clamped rounding for query-byte quantization.
|
|
114
|
+
*
|
|
115
|
+
* Contract: x must be non-NaN. Values outside [0, max_code] are clamped before
|
|
116
|
+
* applying the same non-bit-exact rounding used by
|
|
117
|
+
* round_nonnegative_to_uint8().
|
|
118
|
+
*/
|
|
119
|
+
inline uint8_t round_clamped_to_uint8(float x, uint8_t max_code) {
|
|
120
|
+
assert(x == x);
|
|
121
|
+
return rabitq::round_clamped_byte_scalar(x, max_code);
|
|
122
|
+
}
|
|
123
|
+
|
|
89
124
|
/** Compute factors for a single database vector using RaBitQ algorithm.
|
|
90
125
|
* This function consolidates the mathematical logic that was duplicated
|
|
91
126
|
* between IndexRaBitQ and IndexRaBitQFastScan.
|