faiss 0.6.1 → 0.6.2
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/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/Index.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +6 -7
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +3 -3
- data/vendor/faiss/faiss/IndexHNSW.cpp +173 -143
- data/vendor/faiss/faiss/IndexIVF.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +3 -1
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +2 -3
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -3
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +4 -13
- data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +1 -2
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +68 -6
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
- data/vendor/faiss/faiss/factory_tools.cpp +4 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +11 -12
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +3 -3
- data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +7 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +181 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +48 -3
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +556 -199
- data/vendor/faiss/faiss/impl/HNSW.h +51 -13
- data/vendor/faiss/faiss/impl/NSG.cpp +15 -11
- data/vendor/faiss/faiss/impl/Panorama.h +11 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -2
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +1 -1
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +7 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +1 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +271 -8
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +50 -0
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +10 -10
- data/vendor/faiss/faiss/impl/VisitedTable.h +69 -34
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +3 -1
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +35 -43
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -15
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +86 -40
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +81 -50
- data/vendor/faiss/faiss/impl/index_read.cpp +100 -39
- data/vendor/faiss/faiss/impl/index_write.cpp +1 -0
- data/vendor/faiss/faiss/impl/io_macros.h +25 -0
- data/vendor/faiss/faiss/impl/platform_macros.h +12 -8
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +20 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +36 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +2 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +6 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +327 -18
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +264 -27
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +559 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +199 -27
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +366 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +144 -19
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +26 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +65 -8
- data/vendor/faiss/faiss/index_factory.cpp +5 -1
- data/vendor/faiss/faiss/index_io.h +16 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +4 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +13 -13
- data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +119 -22
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +15 -5
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +65 -24
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +3 -2
- data/vendor/faiss/faiss/utils/bf16.h +34 -0
- data/vendor/faiss/faiss/utils/distances_simd.cpp +0 -1
- data/vendor/faiss/faiss/utils/hamming.cpp +8 -8
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +2 -1
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +6 -30
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +0 -2
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +14 -68
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +343 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +12 -2
- metadata +12 -2
|
@@ -309,12 +309,12 @@ void IndexIVFRaBitQ::reconstruct_from_offset(
|
|
|
309
309
|
int64_t list_no,
|
|
310
310
|
int64_t offset,
|
|
311
311
|
float* recons) const {
|
|
312
|
-
|
|
312
|
+
InvertedLists::ScopedCodes sc(invlists, list_no, offset);
|
|
313
313
|
|
|
314
314
|
std::vector<float> centroid(d);
|
|
315
315
|
quantizer->reconstruct(list_no, centroid.data());
|
|
316
316
|
|
|
317
|
-
rabitq.decode_core(
|
|
317
|
+
rabitq.decode_core(sc.get(), recons, 1, centroid.data());
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
void IndexIVFRaBitQ::sa_decode(idx_t n, const uint8_t* codes, float* x) const {
|
|
@@ -357,26 +357,17 @@ float IVFRaBitDistanceComputer::operator()(idx_t i) {
|
|
|
357
357
|
uint64_t list_no = lo_listno(lo);
|
|
358
358
|
uint64_t offset = lo_offset(lo);
|
|
359
359
|
|
|
360
|
-
|
|
360
|
+
InvertedLists::ScopedCodes sc(parent->invlists, list_no, offset);
|
|
361
361
|
|
|
362
362
|
// ok, we know the appropriate cluster that we need
|
|
363
363
|
std::vector<float> centroid(parent->d);
|
|
364
364
|
parent->quantizer->reconstruct(list_no, centroid.data());
|
|
365
365
|
|
|
366
|
-
// compute the distance
|
|
367
|
-
float distance = 0;
|
|
368
|
-
|
|
369
366
|
std::unique_ptr<FlatCodesDistanceComputer> dc(
|
|
370
367
|
parent->rabitq.get_distance_computer(
|
|
371
368
|
parent->qb, centroid.data(), /*centered=*/false));
|
|
372
369
|
dc->set_query(q);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
// deallocate
|
|
376
|
-
parent->invlists->release_codes(list_no, code);
|
|
377
|
-
|
|
378
|
-
// done
|
|
379
|
-
return distance;
|
|
370
|
+
return dc->distance_to_code(sc.get());
|
|
380
371
|
}
|
|
381
372
|
|
|
382
373
|
float IVFRaBitDistanceComputer::symmetric_dis(idx_t /*i*/, idx_t /*j*/) {
|
|
@@ -126,7 +126,7 @@ void IndexNNDescent::search(
|
|
|
126
126
|
std::unique_ptr<DistanceComputer> dis;
|
|
127
127
|
std::unique_ptr<VisitedTable> vt;
|
|
128
128
|
try {
|
|
129
|
-
vt =
|
|
129
|
+
vt = VisitedTable::create(ntotal);
|
|
130
130
|
dis.reset(storage_distance_computer(storage));
|
|
131
131
|
} catch (...) {
|
|
132
132
|
omp_capture_exception(ex, [&] { interrupt = true; });
|
|
@@ -81,8 +81,7 @@ void IndexNSG::search(
|
|
|
81
81
|
std::unique_ptr<DistanceComputer> dis;
|
|
82
82
|
std::unique_ptr<VisitedTable> vt;
|
|
83
83
|
try {
|
|
84
|
-
vt =
|
|
85
|
-
ntotal, nsg.use_visited_hashset);
|
|
84
|
+
vt = VisitedTable::create(ntotal, nsg.use_visited_hashset);
|
|
86
85
|
dis.reset(storage_distance_computer(storage));
|
|
87
86
|
} catch (...) {
|
|
88
87
|
omp_capture_exception(ex, [&] { interrupt = true; });
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
#include <omp.h>
|
|
16
16
|
|
|
17
|
+
#include <faiss/impl/ResultHandler.h>
|
|
18
|
+
#include <faiss/impl/expanded_scanners.h>
|
|
19
|
+
|
|
17
20
|
#include <faiss/impl/FaissAssert.h>
|
|
18
21
|
#include <faiss/impl/IDSelector.h>
|
|
19
22
|
#include <faiss/impl/ScalarQuantizer.h>
|
|
@@ -137,6 +140,9 @@ IndexIVFScalarQuantizer::IndexIVFScalarQuantizer(
|
|
|
137
140
|
by_residual = false;
|
|
138
141
|
is_trained = true; // no training needed
|
|
139
142
|
}
|
|
143
|
+
if (ScalarQuantizer::TurboQuantRefine::is_turboq_full(qtype)) {
|
|
144
|
+
by_residual = false;
|
|
145
|
+
}
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
IndexIVFScalarQuantizer::IndexIVFScalarQuantizer() : IndexIVF() {
|
|
@@ -330,9 +336,65 @@ void IndexIVFScalarQuantizer::add_core(
|
|
|
330
336
|
InvertedListScanner* IndexIVFScalarQuantizer::get_InvertedListScanner(
|
|
331
337
|
bool store_pairs,
|
|
332
338
|
const IDSelector* sel,
|
|
333
|
-
const IVFSearchParameters*) const {
|
|
334
|
-
|
|
335
|
-
|
|
339
|
+
const IVFSearchParameters* search_params) const {
|
|
340
|
+
if (!ScalarQuantizer::TurboQuantRefine::is_turboq_full(sq.qtype)) {
|
|
341
|
+
return sq.select_InvertedListScanner(
|
|
342
|
+
metric_type, quantizer, store_pairs, sel, by_residual);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// TurboQ full types: create a TQ-specific scanner that supports
|
|
346
|
+
// search params (qb, int_qjl) and pre-screening.
|
|
347
|
+
uint8_t tq_qb = 0;
|
|
348
|
+
bool tq_int_qjl = false;
|
|
349
|
+
if (auto* tp = dynamic_cast<const IVFSQTurboQSearchParameters*>(
|
|
350
|
+
search_params)) {
|
|
351
|
+
tq_qb = tp->qb;
|
|
352
|
+
tq_int_qjl = tp->int_qjl;
|
|
353
|
+
}
|
|
354
|
+
using TurboQDC = ScalarQuantizer::TurboQuantRefine::DistanceComputer;
|
|
355
|
+
auto* dc = static_cast<TurboQDC*>(sq.get_distance_computer(metric_type));
|
|
356
|
+
dc->configure(tq_qb, tq_int_qjl);
|
|
357
|
+
|
|
358
|
+
struct TQScanner : InvertedListScanner {
|
|
359
|
+
std::unique_ptr<TurboQDC> dc;
|
|
360
|
+
|
|
361
|
+
explicit TQScanner(
|
|
362
|
+
TurboQDC* dc_in,
|
|
363
|
+
bool store_pairs_in,
|
|
364
|
+
const IDSelector* sel_in,
|
|
365
|
+
bool keep_max_in)
|
|
366
|
+
: InvertedListScanner(store_pairs_in, sel_in), dc(dc_in) {
|
|
367
|
+
this->keep_max = keep_max_in;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
void set_query(const float* query) override {
|
|
371
|
+
dc->set_query(query);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
void set_list(idx_t list_no_in, float) override {
|
|
375
|
+
this->list_no = list_no_in;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
float distance_to_code(const uint8_t* code) const final {
|
|
379
|
+
return dc->distance_to_code(code);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
size_t scan_codes(
|
|
383
|
+
size_t list_size,
|
|
384
|
+
const uint8_t* codes,
|
|
385
|
+
const idx_t* ids,
|
|
386
|
+
ResultHandler& handler) const override {
|
|
387
|
+
dc->set_prescreen_threshold(&handler.threshold, !keep_max);
|
|
388
|
+
size_t nup = run_scan_codes(*this, list_size, codes, ids, handler);
|
|
389
|
+
dc->clear_prescreen_threshold();
|
|
390
|
+
return nup;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
auto* scanner = new TQScanner(
|
|
395
|
+
dc, store_pairs, sel, is_similarity_metric(metric_type));
|
|
396
|
+
scanner->code_size = code_size;
|
|
397
|
+
return scanner;
|
|
336
398
|
}
|
|
337
399
|
|
|
338
400
|
void IndexIVFScalarQuantizer::reconstruct_from_offset(
|
|
@@ -344,18 +406,18 @@ void IndexIVFScalarQuantizer::reconstruct_from_offset(
|
|
|
344
406
|
quantizer->reconstruct(list_no, recons);
|
|
345
407
|
return;
|
|
346
408
|
}
|
|
347
|
-
|
|
409
|
+
InvertedLists::ScopedCodes sc(invlists, list_no, offset);
|
|
348
410
|
|
|
349
411
|
if (by_residual) {
|
|
350
412
|
std::vector<float> centroid(d);
|
|
351
413
|
quantizer->reconstruct(list_no, centroid.data());
|
|
352
414
|
|
|
353
|
-
sq.decode(
|
|
415
|
+
sq.decode(sc.get(), recons, 1);
|
|
354
416
|
for (int i = 0; i < d; ++i) {
|
|
355
417
|
recons[i] += centroid[i];
|
|
356
418
|
}
|
|
357
419
|
} else {
|
|
358
|
-
sq.decode(
|
|
420
|
+
sq.decode(sc.get(), recons, 1);
|
|
359
421
|
}
|
|
360
422
|
}
|
|
361
423
|
|
|
@@ -63,6 +63,16 @@ struct IndexScalarQuantizer : IndexFlatCodes {
|
|
|
63
63
|
* distances are computed.
|
|
64
64
|
*/
|
|
65
65
|
|
|
66
|
+
/// Search parameters for TurboQuant full types (QT_*_tq).
|
|
67
|
+
struct IVFSQTurboQSearchParameters : IVFSearchParameters {
|
|
68
|
+
/// Query quantization bits for integer MSE pre-screening.
|
|
69
|
+
/// 0 = float path (default), 1-8 = integer popcount path.
|
|
70
|
+
uint8_t qb = 0;
|
|
71
|
+
|
|
72
|
+
/// Also use integer popcount for QJL stage (requires qb > 0).
|
|
73
|
+
bool int_qjl = false;
|
|
74
|
+
};
|
|
75
|
+
|
|
66
76
|
struct IndexIVFScalarQuantizer : IndexIVF {
|
|
67
77
|
ScalarQuantizer sq;
|
|
68
78
|
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
#ifdef __AVX2__
|
|
314
314
|
#include <faiss/cppcontrib/sa_decode/Level2-avx2-inl.h>
|
|
315
315
|
#include <faiss/cppcontrib/sa_decode/PQ-avx2-inl.h>
|
|
316
|
-
#elif defined(__ARM_NEON)
|
|
316
|
+
#elif defined(__ARM_NEON) || defined(__aarch64__)
|
|
317
317
|
#include <faiss/cppcontrib/sa_decode/Level2-neon-inl.h>
|
|
318
318
|
#include <faiss/cppcontrib/sa_decode/PQ-neon-inl.h>
|
|
319
319
|
#else
|