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
|
@@ -65,7 +65,7 @@ void IndexIVFFlat::add_core(
|
|
|
65
65
|
void* inverted_list_context) {
|
|
66
66
|
FAISS_THROW_IF_NOT(is_trained);
|
|
67
67
|
FAISS_THROW_IF_NOT(coarse_idx);
|
|
68
|
-
|
|
68
|
+
FAISS_THROW_IF_MSG(by_residual, "by_residual not supported for this index");
|
|
69
69
|
FAISS_THROW_IF_NOT_MSG(invlists, "invlists not initialized");
|
|
70
70
|
direct_map.check_can_add(xids);
|
|
71
71
|
|
|
@@ -110,7 +110,7 @@ void IndexIVFFlat::encode_vectors(
|
|
|
110
110
|
const idx_t* list_nos,
|
|
111
111
|
uint8_t* codes,
|
|
112
112
|
bool include_listnos) const {
|
|
113
|
-
|
|
113
|
+
FAISS_THROW_IF_MSG(by_residual, "by_residual not supported for this index");
|
|
114
114
|
if (!include_listnos) {
|
|
115
115
|
memcpy(codes, x, code_size * n);
|
|
116
116
|
} else {
|
|
@@ -291,8 +291,7 @@ void IndexIVFFlatDedup::search_preassigned(
|
|
|
291
291
|
bool store_pairs,
|
|
292
292
|
const IVFSearchParameters* params,
|
|
293
293
|
IndexIVFStats* /*stats*/) const {
|
|
294
|
-
|
|
295
|
-
!store_pairs, "store_pairs not supported in IVFDedup");
|
|
294
|
+
FAISS_THROW_IF_MSG(store_pairs, "store_pairs not supported in IVFDedup");
|
|
296
295
|
|
|
297
296
|
IndexIVFFlat::search_preassigned(
|
|
298
297
|
n, x, k, assign, centroid_dis, distances, labels, false, params);
|
|
@@ -90,7 +90,7 @@ void IndexIVFIndependentQuantizer::search(
|
|
|
90
90
|
float* distances,
|
|
91
91
|
idx_t* labels,
|
|
92
92
|
const SearchParameters* params) const {
|
|
93
|
-
|
|
93
|
+
FAISS_THROW_IF_MSG(params, "search parameters not supported");
|
|
94
94
|
size_t nprobe = index_ivf->nprobe;
|
|
95
95
|
std::vector<float> D(n * nprobe);
|
|
96
96
|
std::vector<idx_t> I(n * nprobe);
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
#include <cstdint>
|
|
15
15
|
#include <cstdio>
|
|
16
16
|
|
|
17
|
+
#include <omp.h>
|
|
18
|
+
|
|
17
19
|
#include <algorithm>
|
|
18
20
|
|
|
19
21
|
#include <faiss/utils/distances_dispatch.h>
|
|
@@ -28,6 +30,7 @@
|
|
|
28
30
|
#include <faiss/impl/IDSelector.h>
|
|
29
31
|
#include <faiss/impl/ProductQuantizer.h>
|
|
30
32
|
#include <faiss/impl/ResultHandler.h>
|
|
33
|
+
// NOLINTNEXTLINE(facebook-hte-InlineHeader,facebook-unused-include-check)
|
|
31
34
|
#include <faiss/impl/pq_code_distance/pq_code_distance-generic.h>
|
|
32
35
|
#include <faiss/impl/simd_dispatch.h>
|
|
33
36
|
|
|
@@ -292,34 +295,49 @@ void IndexIVFPQ::add_core_o(
|
|
|
292
295
|
pq.compute_codes(to_encode, xcodes.get(), n);
|
|
293
296
|
|
|
294
297
|
double t2 = getmillisecs();
|
|
295
|
-
// TODO: parallelize?
|
|
296
298
|
size_t n_ignore = 0;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
299
|
+
DirectMapAdd dm_adder(direct_map, n, xids);
|
|
300
|
+
|
|
301
|
+
#pragma omp parallel reduction(+ : n_ignore)
|
|
302
|
+
{
|
|
303
|
+
int nt = omp_get_num_threads();
|
|
304
|
+
int rank = omp_get_thread_num();
|
|
305
|
+
|
|
306
|
+
// each thread takes care of a subset of lists
|
|
307
|
+
for (idx_t i = 0; i < n; i++) {
|
|
308
|
+
idx_t key = idx[i];
|
|
309
|
+
if (key < 0) {
|
|
310
|
+
if (rank == 0) {
|
|
311
|
+
dm_adder.add(i, -1, 0);
|
|
312
|
+
n_ignore++;
|
|
313
|
+
if (residuals_2) {
|
|
314
|
+
memset(residuals_2 + i * d,
|
|
315
|
+
0,
|
|
316
|
+
sizeof(*residuals_2) * d);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (key % nt != rank) {
|
|
322
|
+
continue;
|
|
305
323
|
}
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
324
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
325
|
+
idx_t id = xids ? xids[i] : ntotal + i;
|
|
326
|
+
uint8_t* code = xcodes.get() + i * code_size;
|
|
327
|
+
size_t offset =
|
|
328
|
+
invlists->add_entry(key, id, code, inverted_list_context);
|
|
312
329
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
330
|
+
if (residuals_2) {
|
|
331
|
+
float* res2 = residuals_2 + i * d;
|
|
332
|
+
const float* xi = to_encode + i * d;
|
|
333
|
+
pq.decode(code, res2);
|
|
334
|
+
for (int j = 0; j < d; j++) {
|
|
335
|
+
res2[j] = xi[j] - res2[j];
|
|
336
|
+
}
|
|
319
337
|
}
|
|
320
|
-
}
|
|
321
338
|
|
|
322
|
-
|
|
339
|
+
dm_adder.add(i, key, offset);
|
|
340
|
+
}
|
|
323
341
|
}
|
|
324
342
|
|
|
325
343
|
double t3 = getmillisecs();
|
|
@@ -508,9 +526,17 @@ InvertedListScanner* IndexIVFPQ::get_InvertedListScanner(
|
|
|
508
526
|
bool store_pairs,
|
|
509
527
|
const IDSelector* sel,
|
|
510
528
|
const IVFSearchParameters*) const {
|
|
529
|
+
return get_InvertedListScanner(
|
|
530
|
+
store_pairs, sel, IndexIVFPQ::ScannerMode::Precomputed);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
InvertedListScanner* IndexIVFPQ::get_InvertedListScanner(
|
|
534
|
+
bool store_pairs,
|
|
535
|
+
const IDSelector* sel,
|
|
536
|
+
IndexIVFPQ::ScannerMode mode) const {
|
|
511
537
|
return with_simd_level([&]<SIMDLevel SL>() -> InvertedListScanner* {
|
|
512
538
|
return pq_code_distance::make_IVFPQInvertedListScanner<SL>(
|
|
513
|
-
*this, store_pairs, sel);
|
|
539
|
+
*this, store_pairs, sel, mode);
|
|
514
540
|
});
|
|
515
541
|
}
|
|
516
542
|
|
|
@@ -32,6 +32,11 @@ FAISS_API extern size_t precomputed_table_max_bytes;
|
|
|
32
32
|
* vector is encoded as a product quantizer code.
|
|
33
33
|
*/
|
|
34
34
|
struct IndexIVFPQ : IndexIVF {
|
|
35
|
+
enum class ScannerMode {
|
|
36
|
+
Precomputed,
|
|
37
|
+
OnTheFly,
|
|
38
|
+
};
|
|
39
|
+
|
|
35
40
|
ProductQuantizer pq; ///< produces the codes
|
|
36
41
|
|
|
37
42
|
bool do_polysemous_training; ///< reorder PQ centroids after training?
|
|
@@ -144,6 +149,12 @@ struct IndexIVFPQ : IndexIVF {
|
|
|
144
149
|
const IDSelector* sel,
|
|
145
150
|
const IVFSearchParameters* params) const override;
|
|
146
151
|
|
|
152
|
+
/** Returns a scanner with a fixed PQ distance-computation strategy. */
|
|
153
|
+
InvertedListScanner* get_InvertedListScanner(
|
|
154
|
+
bool store_pairs,
|
|
155
|
+
const IDSelector* sel,
|
|
156
|
+
ScannerMode mode) const;
|
|
157
|
+
|
|
147
158
|
/// build precomputed table
|
|
148
159
|
void precompute_table();
|
|
149
160
|
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
#include <faiss/impl/FaissAssert.h>
|
|
17
17
|
#include <faiss/impl/ResultHandler.h>
|
|
18
18
|
#include <faiss/impl/simdlib/simdlib_dispatch.h>
|
|
19
|
-
#include <faiss/utils/distances.h>
|
|
20
19
|
#include <faiss/utils/distances_dispatch.h>
|
|
21
20
|
#include <faiss/utils/extra_distances.h>
|
|
22
21
|
|
|
@@ -229,60 +229,30 @@ struct RaBitInvertedListScanner : InvertedListScanner {
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
// Multi-bit: Two-stage search with adaptive filtering
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
float est_distance = rabitq_dc->distance_to_code_1bit(codes);
|
|
244
|
-
|
|
245
|
-
size_t code_size_base = (ivf_rabitq.d + 7) / 8;
|
|
246
|
-
const rabitq_utils::SignBitFactorsWithError* base_fac =
|
|
247
|
-
reinterpret_cast<
|
|
248
|
-
const rabitq_utils::SignBitFactorsWithError*>(
|
|
249
|
-
codes + code_size_base);
|
|
250
|
-
|
|
251
|
-
bool should_refine = rabitq_utils::should_refine_candidate(
|
|
252
|
-
est_distance,
|
|
253
|
-
base_fac->f_error,
|
|
254
|
-
rabitq_dc->g_error,
|
|
255
|
-
handler.threshold,
|
|
256
|
-
keep_max);
|
|
257
|
-
if (should_refine) {
|
|
258
|
-
// Refining computes the full distance — counts as a
|
|
259
|
-
// post-filter "distance computed" for stats purposes.
|
|
260
|
-
handler.stats.scan_cnt++;
|
|
261
|
-
float dis = distance_to_code(codes);
|
|
262
|
-
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
263
|
-
|
|
264
|
-
if (handler.add_result(dis, id)) {
|
|
265
|
-
handler.stats.nheap_updates++;
|
|
266
|
-
nup++;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
codes += code_size;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return nup;
|
|
232
|
+
return rabitq_dc->scan_codes_multibit(
|
|
233
|
+
list_size,
|
|
234
|
+
codes,
|
|
235
|
+
ids,
|
|
236
|
+
code_size,
|
|
237
|
+
list_no,
|
|
238
|
+
store_pairs,
|
|
239
|
+
sel,
|
|
240
|
+
keep_max,
|
|
241
|
+
handler);
|
|
273
242
|
}
|
|
274
243
|
|
|
275
244
|
void internal_try_setup_dc() {
|
|
276
245
|
if (!query_vector.empty() && !reconstructed_centroid.empty()) {
|
|
277
|
-
// both query_vector and centroid are available
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
246
|
+
// both query_vector and centroid are available
|
|
247
|
+
if (!dc) {
|
|
248
|
+
dc.reset(ivf_rabitq.rabitq.get_distance_computer(
|
|
249
|
+
qb, nullptr, centered));
|
|
250
|
+
// Try to cast to RaBitQDistanceComputer for multi-bit support
|
|
251
|
+
rabitq_dc = dynamic_cast<RaBitQDistanceComputer*>(dc.get());
|
|
252
|
+
FAISS_THROW_IF_NOT(rabitq_dc);
|
|
253
|
+
}
|
|
254
|
+
rabitq_dc->set_centroid(reconstructed_centroid.data());
|
|
282
255
|
dc->set_query(query_vector.data());
|
|
283
|
-
|
|
284
|
-
// Try to cast to RaBitQDistanceComputer for multi-bit support
|
|
285
|
-
rabitq_dc = dynamic_cast<RaBitQDistanceComputer*>(dc.get());
|
|
286
256
|
}
|
|
287
257
|
}
|
|
288
258
|
};
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
#include <faiss/impl/ResultHandler.h>
|
|
20
20
|
#include <faiss/impl/fast_scan/FastScanDistancePostProcessing.h>
|
|
21
21
|
#include <faiss/impl/fast_scan/fast_scan.h>
|
|
22
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
22
23
|
#include <faiss/invlists/BlockInvertedLists.h>
|
|
23
24
|
#include <faiss/utils/distances.h>
|
|
25
|
+
#include <faiss/utils/rabitq_simd.h>
|
|
24
26
|
#include <faiss/utils/utils.h>
|
|
25
27
|
|
|
26
28
|
namespace faiss {
|
|
@@ -28,6 +30,7 @@ namespace faiss {
|
|
|
28
30
|
// Import shared utilities from RaBitQUtils
|
|
29
31
|
using rabitq_utils::ExtraBitsFactors;
|
|
30
32
|
using rabitq_utils::QueryFactorsData;
|
|
33
|
+
using rabitq_utils::round_nonnegative_to_uint16;
|
|
31
34
|
using rabitq_utils::SignBitFactors;
|
|
32
35
|
using rabitq_utils::SignBitFactorsWithError;
|
|
33
36
|
|
|
@@ -62,8 +65,9 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
62
65
|
metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT,
|
|
63
66
|
"RaBitQ only supports L2 and Inner Product metrics");
|
|
64
67
|
FAISS_THROW_IF_NOT_MSG(
|
|
65
|
-
bbs_in % 32 == 0,
|
|
66
|
-
|
|
68
|
+
bbs_in > 0 && bbs_in % 32 == 0,
|
|
69
|
+
"Batch size must be positive and a multiple of 32");
|
|
70
|
+
FAISS_THROW_IF_MSG(quantizer_in == nullptr, "Quantizer cannot be null");
|
|
67
71
|
|
|
68
72
|
by_residual = true;
|
|
69
73
|
qb = 8; // RaBitQ quantization bits
|
|
@@ -91,10 +95,12 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
// Constructor that converts an existing IndexIVFRaBitQ to FastScan format
|
|
98
|
+
// Constructor that converts an existing IndexIVFRaBitQ to FastScan format.
|
|
99
|
+
// Like other IVF FastScan conversion constructors, this borrows orig's
|
|
100
|
+
// quantizer and orig_invlists; orig must outlive the converted index.
|
|
95
101
|
IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
96
102
|
const IndexIVFRaBitQ& orig,
|
|
97
|
-
int
|
|
103
|
+
int bbs_in)
|
|
98
104
|
: IndexIVFFastScan(
|
|
99
105
|
orig.quantizer,
|
|
100
106
|
orig.d,
|
|
@@ -102,7 +108,93 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
102
108
|
0,
|
|
103
109
|
orig.metric_type,
|
|
104
110
|
false),
|
|
105
|
-
rabitq(orig.rabitq) {
|
|
111
|
+
rabitq(orig.rabitq) {
|
|
112
|
+
FAISS_THROW_IF_NOT_MSG(orig.d > 0, "Dimension must be positive");
|
|
113
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
114
|
+
orig.metric_type == METRIC_L2 ||
|
|
115
|
+
orig.metric_type == METRIC_INNER_PRODUCT,
|
|
116
|
+
"RaBitQ only supports L2 and Inner Product metrics");
|
|
117
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
118
|
+
bbs_in > 0 && bbs_in % 32 == 0,
|
|
119
|
+
"Batch size must be positive and a multiple of 32");
|
|
120
|
+
FAISS_THROW_IF_NOT_MSG(orig.invlists != nullptr, "Source invlists null");
|
|
121
|
+
|
|
122
|
+
by_residual = true;
|
|
123
|
+
qb = orig.qb;
|
|
124
|
+
centered = false;
|
|
125
|
+
|
|
126
|
+
const size_t M_fastscan = (orig.d + 3) / 4;
|
|
127
|
+
constexpr size_t nbits_fastscan = 4;
|
|
128
|
+
|
|
129
|
+
this->bbs = bbs_in;
|
|
130
|
+
this->fine_quantizer = &rabitq;
|
|
131
|
+
this->M = M_fastscan;
|
|
132
|
+
this->nbits = nbits_fastscan;
|
|
133
|
+
this->ksub = (1 << nbits_fastscan);
|
|
134
|
+
this->M2 = roundup(M_fastscan, 2);
|
|
135
|
+
|
|
136
|
+
const size_t bit_pattern_size = (d + 7) / 8;
|
|
137
|
+
const size_t storage_size = compute_per_vector_storage_size();
|
|
138
|
+
this->code_size = bit_pattern_size + storage_size;
|
|
139
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
140
|
+
orig.code_size == code_size,
|
|
141
|
+
"Source IndexIVFRaBitQ code size is incompatible");
|
|
142
|
+
|
|
143
|
+
ntotal = orig.ntotal;
|
|
144
|
+
is_trained = orig.is_trained;
|
|
145
|
+
nprobe = orig.nprobe;
|
|
146
|
+
|
|
147
|
+
replace_invlists(new BlockInvertedLists(nlist, get_CodePacker()), true);
|
|
148
|
+
|
|
149
|
+
#pragma omp parallel for if (nlist > 100)
|
|
150
|
+
for (idx_t list_no = 0; list_no < static_cast<idx_t>(nlist); list_no++) {
|
|
151
|
+
const size_t nb = orig.invlists->list_size(list_no);
|
|
152
|
+
if (nb == 0) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
AlignedTable<uint8_t> flat_codes(nb * code_size);
|
|
157
|
+
memset(flat_codes.get(), 0, nb * code_size);
|
|
158
|
+
|
|
159
|
+
InvertedLists::ScopedCodes orig_codes(orig.invlists, list_no);
|
|
160
|
+
for (size_t i = 0; i < nb; i++) {
|
|
161
|
+
const uint8_t* orig_code = orig_codes.get() + i * orig.code_size;
|
|
162
|
+
uint8_t* fs_code = flat_codes.get() + i * code_size;
|
|
163
|
+
|
|
164
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
165
|
+
const size_t orig_byte_idx = j / 8;
|
|
166
|
+
const size_t orig_bit_offset = j % 8;
|
|
167
|
+
const bool bit_value =
|
|
168
|
+
(orig_code[orig_byte_idx] >> orig_bit_offset) & 1;
|
|
169
|
+
if (bit_value) {
|
|
170
|
+
rabitq_utils::set_bit_fastscan(fs_code, j);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
memcpy(fs_code + bit_pattern_size,
|
|
175
|
+
orig_code + bit_pattern_size,
|
|
176
|
+
storage_size);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
std::unique_ptr<CodePacker> packer(get_CodePacker());
|
|
180
|
+
const size_t nb2 = roundup(nb, bbs);
|
|
181
|
+
AlignedTable<uint8_t> block_codes(nb2 / bbs * packer->block_size);
|
|
182
|
+
memset(block_codes.get(), 0, block_codes.size());
|
|
183
|
+
|
|
184
|
+
for (size_t i = 0; i < nb; i++) {
|
|
185
|
+
packer->pack_1(
|
|
186
|
+
flat_codes.get() + i * code_size, i, block_codes.get());
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
invlists->add_entries(
|
|
190
|
+
list_no,
|
|
191
|
+
nb,
|
|
192
|
+
InvertedLists::ScopedIds(orig.invlists, list_no).get(),
|
|
193
|
+
block_codes.get());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
orig_invlists = orig.invlists;
|
|
197
|
+
}
|
|
106
198
|
|
|
107
199
|
size_t IndexIVFRaBitQFastScan::compute_per_vector_storage_size() const {
|
|
108
200
|
return rabitq_utils::compute_per_vector_storage_size(rabitq.nb_bits, d);
|
|
@@ -161,8 +253,10 @@ void IndexIVFRaBitQFastScan::train_encoder(
|
|
|
161
253
|
const float* x,
|
|
162
254
|
const idx_t* assign) {
|
|
163
255
|
FAISS_THROW_IF_NOT(n > 0);
|
|
164
|
-
FAISS_THROW_IF_NOT(x
|
|
165
|
-
|
|
256
|
+
FAISS_THROW_IF_NOT(x);
|
|
257
|
+
FAISS_THROW_IF_MSG(
|
|
258
|
+
assign == nullptr && by_residual,
|
|
259
|
+
"assign is required when by_residual is set");
|
|
166
260
|
|
|
167
261
|
rabitq.train(n, x);
|
|
168
262
|
is_trained = true;
|
|
@@ -176,9 +270,9 @@ void IndexIVFRaBitQFastScan::encode_vectors(
|
|
|
176
270
|
uint8_t* codes,
|
|
177
271
|
bool include_listnos) const {
|
|
178
272
|
FAISS_THROW_IF_NOT(n > 0);
|
|
179
|
-
FAISS_THROW_IF_NOT(x
|
|
180
|
-
FAISS_THROW_IF_NOT(list_nos
|
|
181
|
-
FAISS_THROW_IF_NOT(codes
|
|
273
|
+
FAISS_THROW_IF_NOT(x);
|
|
274
|
+
FAISS_THROW_IF_NOT(list_nos);
|
|
275
|
+
FAISS_THROW_IF_NOT(codes);
|
|
182
276
|
FAISS_THROW_IF_NOT(is_trained);
|
|
183
277
|
|
|
184
278
|
size_t coarse_size = include_listnos ? coarse_code_size() : 0;
|
|
@@ -416,9 +510,9 @@ void IndexIVFRaBitQFastScan::search_preassigned(
|
|
|
416
510
|
IndexIVFStats* stats) const {
|
|
417
511
|
FAISS_THROW_IF_NOT(is_trained);
|
|
418
512
|
FAISS_THROW_IF_NOT(k > 0);
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
513
|
+
FAISS_THROW_IF_MSG(
|
|
514
|
+
store_pairs, "store_pairs not supported for RaBitQFastScan");
|
|
515
|
+
FAISS_THROW_IF_MSG(stats, "stats not supported for this index");
|
|
422
516
|
|
|
423
517
|
size_t cur_nprobe = this->nprobe;
|
|
424
518
|
uint8_t used_qb = qb;
|
|
@@ -453,6 +547,7 @@ void IndexIVFRaBitQFastScan::compute_LUT(
|
|
|
453
547
|
const FastScanDistancePostProcessing& context) const {
|
|
454
548
|
FAISS_THROW_IF_NOT(is_trained);
|
|
455
549
|
FAISS_THROW_IF_NOT(by_residual);
|
|
550
|
+
FAISS_ASSERT(ksub == 16);
|
|
456
551
|
|
|
457
552
|
// Use overridden qb/centered from context if provided, else index defaults
|
|
458
553
|
const uint8_t used_qb = context.qb > 0 ? context.qb : qb;
|
|
@@ -515,6 +610,7 @@ void IndexIVFRaBitQFastScan::compute_LUT_uint8(
|
|
|
515
610
|
const FastScanDistancePostProcessing& context) const {
|
|
516
611
|
FAISS_THROW_IF_NOT(is_trained);
|
|
517
612
|
FAISS_THROW_IF_NOT(by_residual);
|
|
613
|
+
FAISS_ASSERT(ksub == 16);
|
|
518
614
|
|
|
519
615
|
const uint8_t used_qb = context.qb > 0 ? context.qb : qb;
|
|
520
616
|
const bool used_centered = context.qb > 0 ? context.centered : centered;
|
|
@@ -572,45 +668,53 @@ void IndexIVFRaBitQFastScan::compute_LUT_uint8(
|
|
|
572
668
|
float glob_max_span = -HUGE_VAL;
|
|
573
669
|
float glob_max_dis = -HUGE_VAL;
|
|
574
670
|
float glob_b = HUGE_VAL;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
671
|
+
float a;
|
|
672
|
+
with_selected_simd_levels<rabitq::RABITQ_QUANTIZATION_SIMD_LEVELS>(
|
|
673
|
+
[&]<SIMDLevel SL>() {
|
|
674
|
+
for (size_t j2 = 0; j2 < cur_nprobe; j2++) {
|
|
675
|
+
float b_j = 0;
|
|
676
|
+
float span_j = 0;
|
|
677
|
+
for (size_t m = 0; m < M; m++) {
|
|
678
|
+
const float* tab =
|
|
679
|
+
lut_float.get() + j2 * dim12 + m * ksub;
|
|
680
|
+
float mn, mx;
|
|
681
|
+
rabitq::lut_minmax_16<SL>(tab, mn, mx);
|
|
682
|
+
all_mins[j2 * M + m] = mn;
|
|
683
|
+
float span = mx - mn;
|
|
684
|
+
glob_max_span = std::max(glob_max_span, span);
|
|
685
|
+
b_j += mn;
|
|
686
|
+
span_j += span;
|
|
687
|
+
}
|
|
688
|
+
probe_b[j2] = b_j;
|
|
689
|
+
glob_max_dis = std::max(glob_max_dis, span_j);
|
|
690
|
+
glob_b = std::min(glob_b, b_j);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
a = std::min(
|
|
694
|
+
255.0f / glob_max_span,
|
|
695
|
+
65535.0f / glob_max_dis);
|
|
696
|
+
|
|
697
|
+
// Second pass: quantize LUT and compute biasq.
|
|
698
|
+
uint8_t* out_base =
|
|
699
|
+
dis_tables.get() + i * cur_nprobe * dim12_2;
|
|
700
|
+
uint16_t* bq = biases.get() + i * cur_nprobe;
|
|
701
|
+
for (size_t j2 = 0; j2 < cur_nprobe; j2++) {
|
|
702
|
+
for (size_t m = 0; m < M; m++) {
|
|
703
|
+
const float* tab =
|
|
704
|
+
lut_float.get() + j2 * dim12 + m * ksub;
|
|
705
|
+
const float mn = all_mins[j2 * M + m];
|
|
706
|
+
uint8_t* out =
|
|
707
|
+
out_base + j2 * dim12_2 + m * ksub;
|
|
708
|
+
rabitq::lut_quantize_16_to_uint8<SL>(
|
|
709
|
+
tab, mn, a, out);
|
|
710
|
+
}
|
|
711
|
+
memset(out_base + j2 * dim12_2 + M * ksub,
|
|
712
|
+
0,
|
|
713
|
+
(M2 - M) * ksub);
|
|
714
|
+
bq[j2] = round_nonnegative_to_uint16(
|
|
715
|
+
a * (probe_b[j2] - glob_b));
|
|
716
|
+
}
|
|
717
|
+
});
|
|
614
718
|
normalizers[2 * i] = a;
|
|
615
719
|
normalizers[2 * i + 1] = glob_b;
|
|
616
720
|
}
|
|
@@ -676,8 +780,8 @@ void IndexIVFRaBitQFastScan::sa_decode(idx_t n, const uint8_t* bytes, float* x)
|
|
|
676
780
|
const {
|
|
677
781
|
FAISS_THROW_IF_NOT(is_trained);
|
|
678
782
|
FAISS_THROW_IF_NOT(n > 0);
|
|
679
|
-
FAISS_THROW_IF_NOT(bytes
|
|
680
|
-
FAISS_THROW_IF_NOT(x
|
|
783
|
+
FAISS_THROW_IF_NOT(bytes);
|
|
784
|
+
FAISS_THROW_IF_NOT(x);
|
|
681
785
|
|
|
682
786
|
size_t coarse_size = coarse_code_size();
|
|
683
787
|
size_t total_code_size = code_size + coarse_size;
|
|
@@ -826,35 +930,35 @@ struct IVFRaBitQFastScanScanner : InvertedListScanner {
|
|
|
826
930
|
const size_t M = index.M;
|
|
827
931
|
const size_t M2 = index.M2;
|
|
828
932
|
const size_t ksub = index.ksub;
|
|
933
|
+
FAISS_ASSERT(ksub == 16);
|
|
829
934
|
|
|
830
935
|
float max_span = -HUGE_VAL;
|
|
831
936
|
float max_dis = 0;
|
|
832
937
|
float b = 0;
|
|
833
938
|
float* mins = mins_buf.data();
|
|
834
939
|
|
|
835
|
-
|
|
836
|
-
const float* tab = lut_float.get() + m * ksub;
|
|
837
|
-
float mn = tab[0], mx = tab[0];
|
|
838
|
-
for (size_t s = 1; s < ksub; s++) {
|
|
839
|
-
mn = std::min(mn, tab[s]);
|
|
840
|
-
mx = std::max(mx, tab[s]);
|
|
841
|
-
}
|
|
842
|
-
mins[m] = mn;
|
|
843
|
-
float span = mx - mn;
|
|
844
|
-
max_span = std::max(max_span, span);
|
|
845
|
-
max_dis += span;
|
|
846
|
-
b += mn;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
float a = std::min(255.0f / max_span, 65535.0f / max_dis);
|
|
940
|
+
float a;
|
|
850
941
|
uint8_t* out = dis_tables.get();
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
942
|
+
with_selected_simd_levels<rabitq::RABITQ_QUANTIZATION_SIMD_LEVELS>(
|
|
943
|
+
[&]<SIMDLevel SL>() {
|
|
944
|
+
for (size_t m = 0; m < M; m++) {
|
|
945
|
+
const float* tab = lut_float.get() + m * ksub;
|
|
946
|
+
float mn, mx;
|
|
947
|
+
rabitq::lut_minmax_16<SL>(tab, mn, mx);
|
|
948
|
+
mins[m] = mn;
|
|
949
|
+
float span = mx - mn;
|
|
950
|
+
max_span = std::max(max_span, span);
|
|
951
|
+
max_dis += span;
|
|
952
|
+
b += mn;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
a = std::min(255.0f / max_span, 65535.0f / max_dis);
|
|
956
|
+
for (size_t m = 0; m < M; m++) {
|
|
957
|
+
const float* tab = lut_float.get() + m * ksub;
|
|
958
|
+
rabitq::lut_quantize_16_to_uint8<SL>(
|
|
959
|
+
tab, mins[m], a, out + m * ksub);
|
|
960
|
+
}
|
|
961
|
+
});
|
|
858
962
|
memset(out + M * ksub, 0, (M2 - M) * ksub);
|
|
859
963
|
biases[0] = 0;
|
|
860
964
|
normalizers[0] = a;
|
|
@@ -267,11 +267,12 @@ void IVFRaBitQHeapHandler<C, SL>::handle(
|
|
|
267
267
|
}
|
|
268
268
|
const size_t max_positions = std::min<size_t>(32, this->ntotal - idx_base);
|
|
269
269
|
|
|
270
|
-
// Hoist aux pointer base out of loop:
|
|
271
|
-
// the
|
|
272
|
-
// varies.
|
|
270
|
+
// Hoist aux pointer base out of loop: it points at this 32-lane sub-block's
|
|
271
|
+
// factors, i.e. the bbs block base plus the loop-invariant intra-block
|
|
272
|
+
// offset ((idx_base % bbs)). Only the per-element j term varies below.
|
|
273
273
|
const uint8_t* aux_base = this->list_codes_ptr +
|
|
274
|
-
(idx_base / index->bbs) * full_block_size + packed_block_size
|
|
274
|
+
(idx_base / index->bbs) * full_block_size + packed_block_size +
|
|
275
|
+
(idx_base % index->bbs) * storage_size;
|
|
275
276
|
|
|
276
277
|
// Cache index fields used in the inner loop.
|
|
277
278
|
// Use overridden qb/centered from context if provided, else index defaults.
|