faiss 0.4.3 → 0.5.1
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 +10 -0
- data/README.md +2 -0
- data/ext/faiss/index.cpp +33 -6
- data/ext/faiss/index_binary.cpp +17 -4
- data/ext/faiss/kmeans.cpp +6 -6
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +2 -3
- data/vendor/faiss/faiss/AutoTune.h +1 -1
- data/vendor/faiss/faiss/Clustering.cpp +2 -2
- data/vendor/faiss/faiss/Clustering.h +2 -2
- data/vendor/faiss/faiss/IVFlib.cpp +26 -51
- data/vendor/faiss/faiss/IVFlib.h +1 -1
- data/vendor/faiss/faiss/Index.cpp +11 -0
- data/vendor/faiss/faiss/Index.h +34 -11
- data/vendor/faiss/faiss/Index2Layer.cpp +1 -1
- data/vendor/faiss/faiss/Index2Layer.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +1 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +9 -4
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexBinary.h +7 -7
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +8 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +3 -3
- data/vendor/faiss/faiss/IndexBinaryHash.h +5 -5
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +7 -6
- data/vendor/faiss/faiss/IndexFastScan.cpp +125 -49
- data/vendor/faiss/faiss/IndexFastScan.h +102 -7
- data/vendor/faiss/faiss/IndexFlat.cpp +374 -4
- data/vendor/faiss/faiss/IndexFlat.h +81 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +93 -2
- data/vendor/faiss/faiss/IndexHNSW.h +58 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +14 -13
- data/vendor/faiss/faiss/IndexIDMap.h +6 -6
- data/vendor/faiss/faiss/IndexIVF.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVF.h +5 -5
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +9 -3
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +3 -1
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +176 -90
- data/vendor/faiss/faiss/IndexIVFFastScan.h +173 -18
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +1 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +251 -0
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.h +64 -0
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +3 -1
- data/vendor/faiss/faiss/IndexIVFPQ.h +1 -1
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +134 -2
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +99 -8
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +4 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +828 -0
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +252 -0
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +1 -1
- data/vendor/faiss/faiss/IndexNNDescent.cpp +1 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +1 -1
- data/vendor/faiss/faiss/IndexNeuralNetCodec.h +1 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +4 -1
- data/vendor/faiss/faiss/IndexPQ.h +1 -1
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +6 -2
- data/vendor/faiss/faiss/IndexPQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexPreTransform.cpp +14 -0
- data/vendor/faiss/faiss/IndexPreTransform.h +9 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +96 -13
- data/vendor/faiss/faiss/IndexRaBitQ.h +11 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +731 -0
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +175 -0
- data/vendor/faiss/faiss/IndexRefine.cpp +49 -0
- data/vendor/faiss/faiss/IndexRefine.h +17 -0
- data/vendor/faiss/faiss/IndexShards.cpp +1 -1
- data/vendor/faiss/faiss/MatrixStats.cpp +3 -3
- data/vendor/faiss/faiss/MetricType.h +1 -1
- data/vendor/faiss/faiss/VectorTransform.h +2 -2
- data/vendor/faiss/faiss/clone_index.cpp +5 -1
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +1 -1
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +3 -1
- data/vendor/faiss/faiss/gpu/GpuIndex.h +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryCagra.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +1 -1
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +11 -7
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIcmEncoder.cpp +7 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +2 -2
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -1
- data/vendor/faiss/faiss/impl/CodePacker.h +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +77 -6
- data/vendor/faiss/faiss/impl/FastScanDistancePostProcessing.h +53 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +295 -16
- data/vendor/faiss/faiss/impl/HNSW.h +35 -6
- data/vendor/faiss/faiss/impl/IDSelector.cpp +2 -2
- data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +1 -1
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
- data/vendor/faiss/faiss/impl/NNDescent.h +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -1
- data/vendor/faiss/faiss/impl/Panorama.cpp +193 -0
- data/vendor/faiss/faiss/impl/Panorama.h +204 -0
- data/vendor/faiss/faiss/impl/PanoramaStats.cpp +33 -0
- data/vendor/faiss/faiss/impl/PanoramaStats.h +38 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +5 -5
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +2 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/RaBitQStats.cpp +29 -0
- data/vendor/faiss/faiss/impl/RaBitQStats.h +56 -0
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +294 -0
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +330 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +304 -223
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +72 -4
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +362 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +112 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResultHandler.h +4 -4
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +7 -10
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +2 -4
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +7 -4
- data/vendor/faiss/faiss/impl/index_read.cpp +238 -10
- data/vendor/faiss/faiss/impl/index_write.cpp +212 -19
- data/vendor/faiss/faiss/impl/io.cpp +2 -2
- data/vendor/faiss/faiss/impl/io.h +4 -4
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +1 -1
- data/vendor/faiss/faiss/impl/kmeans1d.h +1 -1
- data/vendor/faiss/faiss/impl/lattice_Zn.h +2 -2
- data/vendor/faiss/faiss/impl/mapped_io.cpp +2 -2
- data/vendor/faiss/faiss/impl/mapped_io.h +4 -3
- data/vendor/faiss/faiss/impl/maybe_owned_vector.h +8 -1
- data/vendor/faiss/faiss/impl/platform_macros.h +12 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +30 -4
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +14 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +5 -6
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +55 -11
- data/vendor/faiss/faiss/impl/svs_io.cpp +86 -0
- data/vendor/faiss/faiss/impl/svs_io.h +67 -0
- data/vendor/faiss/faiss/impl/zerocopy_io.h +1 -1
- data/vendor/faiss/faiss/index_factory.cpp +217 -8
- data/vendor/faiss/faiss/index_factory.h +1 -1
- data/vendor/faiss/faiss/index_io.h +1 -1
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +1 -1
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +115 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.h +46 -0
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +261 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +117 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +66 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +245 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +137 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +39 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +42 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +149 -0
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +58 -0
- data/vendor/faiss/faiss/utils/AlignedTable.h +1 -1
- data/vendor/faiss/faiss/utils/Heap.cpp +2 -2
- data/vendor/faiss/faiss/utils/Heap.h +3 -3
- data/vendor/faiss/faiss/utils/NeuralNet.cpp +1 -1
- data/vendor/faiss/faiss/utils/NeuralNet.h +3 -3
- data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +2 -2
- data/vendor/faiss/faiss/utils/approx_topk/mode.h +1 -1
- data/vendor/faiss/faiss/utils/distances.cpp +0 -3
- data/vendor/faiss/faiss/utils/distances.h +2 -2
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +3 -1
- data/vendor/faiss/faiss/utils/hamming-inl.h +2 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +7 -6
- data/vendor/faiss/faiss/utils/hamming.h +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -2
- data/vendor/faiss/faiss/utils/partitioning.cpp +5 -5
- data/vendor/faiss/faiss/utils/partitioning.h +2 -2
- data/vendor/faiss/faiss/utils/rabitq_simd.h +222 -336
- data/vendor/faiss/faiss/utils/random.cpp +1 -1
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +1 -1
- data/vendor/faiss/faiss/utils/simdlib_avx512.h +1 -1
- data/vendor/faiss/faiss/utils/simdlib_neon.h +2 -2
- data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +1 -1
- data/vendor/faiss/faiss/utils/utils.cpp +9 -2
- data/vendor/faiss/faiss/utils/utils.h +2 -2
- metadata +29 -1
|
@@ -53,7 +53,7 @@ void DirectMap::set_type(
|
|
|
53
53
|
for (long ofs = 0; ofs < list_size; ofs++) {
|
|
54
54
|
FAISS_THROW_IF_NOT_MSG(
|
|
55
55
|
0 <= idlist[ofs] && idlist[ofs] < ntotal,
|
|
56
|
-
"direct map supported only for
|
|
56
|
+
"direct map supported only for sequential ids");
|
|
57
57
|
array[idlist[ofs]] = lo_build(key, ofs);
|
|
58
58
|
}
|
|
59
59
|
} else if (new_type == Hashtable) {
|
|
@@ -229,7 +229,7 @@ bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context)
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
//
|
|
232
|
+
// implement iterator on top of get_codes / get_ids
|
|
233
233
|
namespace {
|
|
234
234
|
|
|
235
235
|
struct CodeArrayIterator : InvertedListsIterator {
|
|
@@ -346,6 +346,120 @@ void ArrayInvertedLists::permute_invlists(const idx_t* map) {
|
|
|
346
346
|
|
|
347
347
|
ArrayInvertedLists::~ArrayInvertedLists() {}
|
|
348
348
|
|
|
349
|
+
/***********************************************
|
|
350
|
+
* ArrayInvertedListsPanorama implementation
|
|
351
|
+
**********************************************/
|
|
352
|
+
|
|
353
|
+
ArrayInvertedListsPanorama::ArrayInvertedListsPanorama(
|
|
354
|
+
size_t nlist,
|
|
355
|
+
size_t code_size,
|
|
356
|
+
size_t n_levels)
|
|
357
|
+
: ArrayInvertedLists(nlist, code_size),
|
|
358
|
+
n_levels(n_levels),
|
|
359
|
+
level_width(
|
|
360
|
+
(((code_size / sizeof(float)) + n_levels - 1) / n_levels) *
|
|
361
|
+
sizeof(float)),
|
|
362
|
+
pano(code_size, n_levels, kBatchSize) {
|
|
363
|
+
FAISS_THROW_IF_NOT(n_levels > 0);
|
|
364
|
+
FAISS_THROW_IF_NOT(code_size % sizeof(float) == 0);
|
|
365
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
366
|
+
!use_iterator,
|
|
367
|
+
"IndexIVFFlatPanorama does not support iterators, use vanilla IndexIVFFlat instead");
|
|
368
|
+
FAISS_ASSERT(level_width % sizeof(float) == 0);
|
|
369
|
+
|
|
370
|
+
cum_sums.resize(nlist);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const float* ArrayInvertedListsPanorama::get_cum_sums(size_t list_no) const {
|
|
374
|
+
assert(list_no < nlist);
|
|
375
|
+
return cum_sums[list_no].data();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
size_t ArrayInvertedListsPanorama::add_entries(
|
|
379
|
+
size_t list_no,
|
|
380
|
+
size_t n_entry,
|
|
381
|
+
const idx_t* ids_in,
|
|
382
|
+
const uint8_t* code) {
|
|
383
|
+
assert(list_no < nlist);
|
|
384
|
+
size_t o = ids[list_no].size();
|
|
385
|
+
|
|
386
|
+
ids[list_no].resize(o + n_entry);
|
|
387
|
+
memcpy(&ids[list_no][o], ids_in, sizeof(ids_in[0]) * n_entry);
|
|
388
|
+
|
|
389
|
+
size_t new_size = o + n_entry;
|
|
390
|
+
size_t num_batches = (new_size + kBatchSize - 1) / kBatchSize;
|
|
391
|
+
codes[list_no].resize(num_batches * kBatchSize * code_size);
|
|
392
|
+
cum_sums[list_no].resize(num_batches * kBatchSize * (n_levels + 1));
|
|
393
|
+
|
|
394
|
+
// Cast to float* is safe here as we guarantee codes are always float
|
|
395
|
+
// vectors for `IndexIVFFlatPanorama` (verified by the constructor).
|
|
396
|
+
const float* vectors = reinterpret_cast<const float*>(code);
|
|
397
|
+
pano.copy_codes_to_level_layout(codes[list_no].data(), o, n_entry, code);
|
|
398
|
+
pano.compute_cumulative_sums(cum_sums[list_no].data(), o, n_entry, vectors);
|
|
399
|
+
|
|
400
|
+
return o;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
void ArrayInvertedListsPanorama::update_entries(
|
|
404
|
+
size_t list_no,
|
|
405
|
+
size_t offset,
|
|
406
|
+
size_t n_entry,
|
|
407
|
+
const idx_t* ids_in,
|
|
408
|
+
const uint8_t* code) {
|
|
409
|
+
assert(list_no < nlist);
|
|
410
|
+
assert(n_entry + offset <= ids[list_no].size());
|
|
411
|
+
|
|
412
|
+
memcpy(&ids[list_no][offset], ids_in, sizeof(ids_in[0]) * n_entry);
|
|
413
|
+
|
|
414
|
+
// Cast to float* is safe here as we guarantee codes are always float
|
|
415
|
+
// vectors for `IndexIVFFlatPanorama` (verified by the constructor).
|
|
416
|
+
const float* vectors = reinterpret_cast<const float*>(code);
|
|
417
|
+
pano.copy_codes_to_level_layout(
|
|
418
|
+
codes[list_no].data(), offset, n_entry, code);
|
|
419
|
+
pano.compute_cumulative_sums(
|
|
420
|
+
cum_sums[list_no].data(), offset, n_entry, vectors);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
void ArrayInvertedListsPanorama::resize(size_t list_no, size_t new_size) {
|
|
424
|
+
ids[list_no].resize(new_size);
|
|
425
|
+
|
|
426
|
+
size_t num_batches = (new_size + kBatchSize - 1) / kBatchSize;
|
|
427
|
+
codes[list_no].resize(num_batches * kBatchSize * code_size);
|
|
428
|
+
cum_sums[list_no].resize(num_batches * kBatchSize * (n_levels + 1));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const uint8_t* ArrayInvertedListsPanorama::get_single_code(
|
|
432
|
+
size_t list_no,
|
|
433
|
+
size_t offset) const {
|
|
434
|
+
assert(list_no < nlist);
|
|
435
|
+
assert(offset < ids[list_no].size());
|
|
436
|
+
|
|
437
|
+
uint8_t* recons_buffer = new uint8_t[code_size];
|
|
438
|
+
|
|
439
|
+
float* recons = reinterpret_cast<float*>(recons_buffer);
|
|
440
|
+
pano.reconstruct(offset, recons, codes[list_no].data());
|
|
441
|
+
|
|
442
|
+
return recons_buffer;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
void ArrayInvertedListsPanorama::release_codes(
|
|
446
|
+
size_t list_no,
|
|
447
|
+
const uint8_t* codes) const {
|
|
448
|
+
// Only delete if it's heap-allocated (from get_single_code).
|
|
449
|
+
// If it's from get_codes (raw storage), it will be codes[list_no].data()
|
|
450
|
+
if (codes != this->codes[list_no].data()) {
|
|
451
|
+
delete[] codes;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
InvertedListsIterator* ArrayInvertedListsPanorama::get_iterator(
|
|
456
|
+
size_t /* list_no */,
|
|
457
|
+
void* /* inverted_list_context */) const {
|
|
458
|
+
FAISS_THROW_MSG(
|
|
459
|
+
"IndexIVFFlatPanorama does not support iterators, use vanilla IndexIVFFlat instead");
|
|
460
|
+
return nullptr;
|
|
461
|
+
}
|
|
462
|
+
|
|
349
463
|
/*****************************************************************
|
|
350
464
|
* Meta-inverted list implementations
|
|
351
465
|
*****************************************************************/
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
#include <vector>
|
|
19
19
|
|
|
20
20
|
#include <faiss/MetricType.h>
|
|
21
|
+
#include <faiss/impl/Panorama.h>
|
|
21
22
|
#include <faiss/impl/maybe_owned_vector.h>
|
|
22
23
|
|
|
23
24
|
namespace faiss {
|
|
@@ -276,6 +277,51 @@ struct ArrayInvertedLists : InvertedLists {
|
|
|
276
277
|
~ArrayInvertedLists() override;
|
|
277
278
|
};
|
|
278
279
|
|
|
280
|
+
/// Level-oriented storage as defined in the IVFFlat section of Panorama
|
|
281
|
+
/// (https://www.arxiv.org/pdf/2510.00566).
|
|
282
|
+
struct ArrayInvertedListsPanorama : ArrayInvertedLists {
|
|
283
|
+
static constexpr size_t kBatchSize = 128;
|
|
284
|
+
std::vector<MaybeOwnedVector<float>> cum_sums;
|
|
285
|
+
const size_t n_levels;
|
|
286
|
+
const size_t level_width; // in code units
|
|
287
|
+
Panorama pano;
|
|
288
|
+
|
|
289
|
+
ArrayInvertedListsPanorama(size_t nlist, size_t code_size, size_t n_levels);
|
|
290
|
+
|
|
291
|
+
const float* get_cum_sums(size_t list_no) const;
|
|
292
|
+
|
|
293
|
+
size_t add_entries(
|
|
294
|
+
size_t list_no,
|
|
295
|
+
size_t n_entry,
|
|
296
|
+
const idx_t* ids,
|
|
297
|
+
const uint8_t* code) override;
|
|
298
|
+
|
|
299
|
+
void update_entries(
|
|
300
|
+
size_t list_no,
|
|
301
|
+
size_t offset,
|
|
302
|
+
size_t n_entry,
|
|
303
|
+
const idx_t* ids,
|
|
304
|
+
const uint8_t* code) override;
|
|
305
|
+
|
|
306
|
+
void resize(size_t list_no, size_t new_size) override;
|
|
307
|
+
|
|
308
|
+
/// Panorama's layout make it impractical to support iterators as defined
|
|
309
|
+
/// by Faiss (i.e. `InvertedListsIterator` API). The iterator would require
|
|
310
|
+
/// to allocate and reassemble the vector at each call.
|
|
311
|
+
/// Hence, we override this method to throw an error, this effectively
|
|
312
|
+
/// disables the `iterate_codes` and `iterate_codes_range` methods.
|
|
313
|
+
InvertedListsIterator* get_iterator(
|
|
314
|
+
size_t list_no,
|
|
315
|
+
void* inverted_list_context = nullptr) const override;
|
|
316
|
+
|
|
317
|
+
/// Reconstructs a single code from level-oriented storage to flat format.
|
|
318
|
+
const uint8_t* get_single_code(size_t list_no, size_t offset)
|
|
319
|
+
const override;
|
|
320
|
+
|
|
321
|
+
/// Frees codes returned by `get_single_code`.
|
|
322
|
+
void release_codes(size_t list_no, const uint8_t* codes) const override;
|
|
323
|
+
};
|
|
324
|
+
|
|
279
325
|
/*****************************************************************
|
|
280
326
|
* Meta-inverted lists
|
|
281
327
|
*
|
|
@@ -372,7 +372,7 @@ OnDiskInvertedLists::~OnDiskInvertedLists() {
|
|
|
372
372
|
if (ptr != nullptr) {
|
|
373
373
|
int err = munmap(ptr, totsize);
|
|
374
374
|
if (err != 0) {
|
|
375
|
-
fprintf(stderr, "
|
|
375
|
+
fprintf(stderr, "munmap error: %s", strerror(errno));
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
delete locks;
|
|
@@ -121,7 +121,7 @@ struct OnDiskInvertedLists : InvertedLists {
|
|
|
121
121
|
|
|
122
122
|
LockLevels* locks;
|
|
123
123
|
|
|
124
|
-
// encapsulates the threads that are busy
|
|
124
|
+
// encapsulates the threads that are busy prefetching
|
|
125
125
|
struct OngoingPrefetch;
|
|
126
126
|
OngoingPrefetch* pf;
|
|
127
127
|
int prefetch_nthread;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/*
|
|
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 2025 Intel Corporation
|
|
10
|
+
*
|
|
11
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
+
* you may not use this file except in compliance with the License.
|
|
13
|
+
* You may obtain a copy of the License at
|
|
14
|
+
*
|
|
15
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
+
*
|
|
17
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
+
* See the License for the specific language governing permissions and
|
|
21
|
+
* limitations under the License.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#pragma once
|
|
25
|
+
|
|
26
|
+
#include <svs/runtime/api_defs.h>
|
|
27
|
+
|
|
28
|
+
#include <faiss/Index.h>
|
|
29
|
+
#include <faiss/MetricType.h>
|
|
30
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
31
|
+
#include <faiss/impl/FaissAssert.h>
|
|
32
|
+
#include <faiss/impl/IDSelector.h>
|
|
33
|
+
|
|
34
|
+
#include <algorithm>
|
|
35
|
+
#include <concepts>
|
|
36
|
+
#include <memory>
|
|
37
|
+
#include <span>
|
|
38
|
+
#include <type_traits>
|
|
39
|
+
#include <vector>
|
|
40
|
+
|
|
41
|
+
// validate FAISS_SVS_RUNTIME_VERSION is set
|
|
42
|
+
#ifndef FAISS_SVS_RUNTIME_VERSION
|
|
43
|
+
#error "FAISS_SVS_RUNTIME_VERSION is not defined"
|
|
44
|
+
#endif
|
|
45
|
+
// create svs_runtime as alias for svs::runtime::FAISS_SVS_RUNTIME_VERSION
|
|
46
|
+
SVS_RUNTIME_CREATE_API_ALIAS(svs_runtime, FAISS_SVS_RUNTIME_VERSION);
|
|
47
|
+
|
|
48
|
+
// SVS forward declarations
|
|
49
|
+
namespace svs {
|
|
50
|
+
namespace runtime {
|
|
51
|
+
inline namespace v0 {
|
|
52
|
+
struct FlatIndex;
|
|
53
|
+
struct VamanaIndex;
|
|
54
|
+
struct DynamicVamanaIndex;
|
|
55
|
+
struct LeanVecTrainingData;
|
|
56
|
+
} // namespace v0
|
|
57
|
+
} // namespace runtime
|
|
58
|
+
} // namespace svs
|
|
59
|
+
|
|
60
|
+
namespace faiss {
|
|
61
|
+
|
|
62
|
+
inline svs_runtime::MetricType to_svs_metric(faiss::MetricType metric) {
|
|
63
|
+
switch (metric) {
|
|
64
|
+
case METRIC_INNER_PRODUCT:
|
|
65
|
+
return svs_runtime::MetricType::INNER_PRODUCT;
|
|
66
|
+
case METRIC_L2:
|
|
67
|
+
return svs_runtime::MetricType::L2;
|
|
68
|
+
default:
|
|
69
|
+
FAISS_ASSERT(!"not supported SVS distance");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
struct FaissIDFilter : public svs_runtime::IDFilter {
|
|
74
|
+
FaissIDFilter(const faiss::IDSelector& sel) : selector(sel) {}
|
|
75
|
+
|
|
76
|
+
bool is_member(size_t id) const override {
|
|
77
|
+
return selector.is_member(static_cast<faiss::idx_t>(id));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private:
|
|
81
|
+
const faiss::IDSelector& selector;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
inline std::unique_ptr<FaissIDFilter> make_faiss_id_filter(
|
|
85
|
+
const SearchParameters* params = nullptr) {
|
|
86
|
+
if (params && params->sel) {
|
|
87
|
+
return std::make_unique<FaissIDFilter>(*params->sel);
|
|
88
|
+
}
|
|
89
|
+
return nullptr;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
template <typename T, typename U, typename = void>
|
|
93
|
+
struct InputBufferConverter {
|
|
94
|
+
InputBufferConverter(std::span<const U> data = {}) : buffer(data.size()) {
|
|
95
|
+
FAISS_ASSERT(
|
|
96
|
+
!"InputBufferConverter: there is no suitable user code for this type conversion");
|
|
97
|
+
std::transform(
|
|
98
|
+
data.begin(), data.end(), buffer.begin(), [](const U& val) {
|
|
99
|
+
return static_cast<T>(val);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
operator T*() {
|
|
104
|
+
return buffer.data();
|
|
105
|
+
}
|
|
106
|
+
operator const T*() const {
|
|
107
|
+
return buffer.data();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
operator std::span<T>() {
|
|
111
|
+
return buffer;
|
|
112
|
+
}
|
|
113
|
+
operator std::span<const T>() const {
|
|
114
|
+
return buffer;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private:
|
|
118
|
+
std::vector<T> buffer;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Specialization for reinterpret cast when types are integral and have the same
|
|
122
|
+
// size
|
|
123
|
+
template <typename T, typename U>
|
|
124
|
+
struct InputBufferConverter<
|
|
125
|
+
T,
|
|
126
|
+
U,
|
|
127
|
+
std::enable_if_t<
|
|
128
|
+
std::is_same_v<T, U> ||
|
|
129
|
+
(std::is_integral_v<T> && std::is_integral_v<U> &&
|
|
130
|
+
sizeof(T) == sizeof(U))>> {
|
|
131
|
+
InputBufferConverter(std::span<const U> data = {}) : data_span(data) {}
|
|
132
|
+
operator T*() {
|
|
133
|
+
return reinterpret_cast<T*>(data_span.data());
|
|
134
|
+
}
|
|
135
|
+
operator const T*() const {
|
|
136
|
+
return reinterpret_cast<const T*>(data_span.data());
|
|
137
|
+
}
|
|
138
|
+
operator std::span<T>() {
|
|
139
|
+
return std::span<T>(
|
|
140
|
+
reinterpret_cast<T*>(data_span.data()), data_span.size());
|
|
141
|
+
}
|
|
142
|
+
operator std::span<const T>() const {
|
|
143
|
+
return std::span<const T>(
|
|
144
|
+
reinterpret_cast<const T*>(data_span.data()), data_span.size());
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private:
|
|
148
|
+
std::span<const U> data_span;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
template <typename T, typename U, typename = void>
|
|
152
|
+
struct OutputBufferConverter {
|
|
153
|
+
OutputBufferConverter(std::span<U> data = {})
|
|
154
|
+
: data_span(data), buffer(data.size()) {
|
|
155
|
+
FAISS_ASSERT(
|
|
156
|
+
!"OutputBufferConverter: there is no suitable user code for this type conversion");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
~OutputBufferConverter() {
|
|
160
|
+
std::transform(
|
|
161
|
+
buffer.begin(),
|
|
162
|
+
buffer.end(),
|
|
163
|
+
data_span.begin(),
|
|
164
|
+
[](const T& val) { return static_cast<U>(val); });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
operator T*() {
|
|
168
|
+
return buffer.data();
|
|
169
|
+
}
|
|
170
|
+
operator std::span<T>() {
|
|
171
|
+
return buffer;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private:
|
|
175
|
+
std::span<U> data_span;
|
|
176
|
+
std::vector<T> buffer;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// Specialization for reinterpret cast when types are integral and have the same
|
|
180
|
+
// size
|
|
181
|
+
template <typename T, typename U>
|
|
182
|
+
struct OutputBufferConverter<
|
|
183
|
+
T,
|
|
184
|
+
U,
|
|
185
|
+
std::enable_if_t<
|
|
186
|
+
std::is_same_v<T, U> ||
|
|
187
|
+
(std::is_integral_v<T> && std::is_integral_v<U> &&
|
|
188
|
+
sizeof(T) == sizeof(U))>> {
|
|
189
|
+
OutputBufferConverter(std::span<U> data = {}) : data_span(data) {}
|
|
190
|
+
operator T*() {
|
|
191
|
+
return reinterpret_cast<T*>(data_span.data());
|
|
192
|
+
}
|
|
193
|
+
operator std::span<T>() {
|
|
194
|
+
return std::span<T>(
|
|
195
|
+
reinterpret_cast<T*>(data_span.data()), data_span.size());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private:
|
|
199
|
+
std::span<U> data_span;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
template <typename T, typename U>
|
|
203
|
+
auto convert_input_buffer(std::span<const U> data) {
|
|
204
|
+
// Create temporary buffer and convert input data
|
|
205
|
+
// to target type T in the temporary buffer
|
|
206
|
+
// The temporary buffer will be destroyed
|
|
207
|
+
// when going out of scope
|
|
208
|
+
return InputBufferConverter<T, U>(data);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
template <typename T, typename U>
|
|
212
|
+
auto convert_input_buffer(const U* data, size_t size) {
|
|
213
|
+
return convert_input_buffer<T, U>(std::span<const U>(data, size));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Output buffer conversion
|
|
217
|
+
template <typename T, typename U>
|
|
218
|
+
auto convert_output_buffer(std::span<U> data) {
|
|
219
|
+
// Create temporary buffer for output data
|
|
220
|
+
// The temporary buffer will be destroyed
|
|
221
|
+
// when going out of scope, copying back
|
|
222
|
+
// the converted data to original buffer
|
|
223
|
+
return OutputBufferConverter<T, U>(data);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
template <typename T, typename U>
|
|
227
|
+
auto convert_output_buffer(U* data, size_t size) {
|
|
228
|
+
return convert_output_buffer<T, U>(std::span<U>(data, size));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
struct FaissResultsAllocator : public svs_runtime::ResultsAllocator {
|
|
232
|
+
FaissResultsAllocator(faiss::RangeSearchResult* result) : result(result) {
|
|
233
|
+
FAISS_ASSERT(result != nullptr);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
svs_runtime::SearchResultsStorage allocate(
|
|
237
|
+
std::span<size_t> result_counts) const override {
|
|
238
|
+
FAISS_ASSERT(result != nullptr);
|
|
239
|
+
FAISS_ASSERT(result_counts.size() == result->nq);
|
|
240
|
+
|
|
241
|
+
// RangeSearchResult .ctor() allows unallocated lims
|
|
242
|
+
if (result->lims == nullptr) {
|
|
243
|
+
result->lims = new size_t[result->nq + 1];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
std::copy(result_counts.begin(), result_counts.end(), result->lims);
|
|
247
|
+
result->do_allocation();
|
|
248
|
+
this->labels_converter = LabelsConverter{
|
|
249
|
+
std::span(result->labels, result->lims[result_counts.size()])};
|
|
250
|
+
return svs_runtime::SearchResultsStorage{
|
|
251
|
+
labels_converter,
|
|
252
|
+
std::span<float>(
|
|
253
|
+
result->distances, result->lims[result_counts.size()])};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private:
|
|
257
|
+
faiss::RangeSearchResult* result;
|
|
258
|
+
using LabelsConverter = OutputBufferConverter<size_t, faiss::idx_t>;
|
|
259
|
+
mutable LabelsConverter labels_converter;
|
|
260
|
+
};
|
|
261
|
+
} // namespace faiss
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/*
|
|
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 2025 Intel Corporation
|
|
10
|
+
*
|
|
11
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
+
* you may not use this file except in compliance with the License.
|
|
13
|
+
* You may obtain a copy of the License at
|
|
14
|
+
*
|
|
15
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
+
*
|
|
17
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
+
* See the License for the specific language governing permissions and
|
|
21
|
+
* limitations under the License.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#include <faiss/Index.h>
|
|
25
|
+
#include <faiss/svs/IndexSVSFaissUtils.h>
|
|
26
|
+
#include <faiss/svs/IndexSVSFlat.h>
|
|
27
|
+
|
|
28
|
+
#include <svs/runtime/flat_index.h>
|
|
29
|
+
|
|
30
|
+
#include <iostream>
|
|
31
|
+
|
|
32
|
+
namespace faiss {
|
|
33
|
+
|
|
34
|
+
IndexSVSFlat::IndexSVSFlat(idx_t d, MetricType metric) : Index(d, metric) {}
|
|
35
|
+
|
|
36
|
+
IndexSVSFlat::~IndexSVSFlat() {
|
|
37
|
+
if (impl) {
|
|
38
|
+
auto status = svs_runtime::FlatIndex::destroy(impl);
|
|
39
|
+
FAISS_ASSERT(status.ok());
|
|
40
|
+
impl = nullptr;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void IndexSVSFlat::add(idx_t n, const float* x) {
|
|
45
|
+
if (!impl) {
|
|
46
|
+
create_impl();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
auto status = impl->add(n, x);
|
|
50
|
+
if (!status.ok()) {
|
|
51
|
+
FAISS_THROW_MSG(status.message());
|
|
52
|
+
}
|
|
53
|
+
ntotal += n;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void IndexSVSFlat::reset() {
|
|
57
|
+
if (impl) {
|
|
58
|
+
auto status = impl->reset();
|
|
59
|
+
if (!status.ok()) {
|
|
60
|
+
FAISS_THROW_MSG(status.message());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
ntotal = 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void IndexSVSFlat::search(
|
|
67
|
+
idx_t n,
|
|
68
|
+
const float* x,
|
|
69
|
+
idx_t k,
|
|
70
|
+
float* distances,
|
|
71
|
+
idx_t* labels,
|
|
72
|
+
const SearchParameters* params) const {
|
|
73
|
+
FAISS_THROW_IF_NOT(impl);
|
|
74
|
+
auto status = impl->search(
|
|
75
|
+
n,
|
|
76
|
+
x,
|
|
77
|
+
static_cast<size_t>(k),
|
|
78
|
+
distances,
|
|
79
|
+
reinterpret_cast<size_t*>(labels));
|
|
80
|
+
if (!status.ok()) {
|
|
81
|
+
FAISS_THROW_MSG(status.message());
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Initializes the implementation*/
|
|
86
|
+
void IndexSVSFlat::create_impl() {
|
|
87
|
+
FAISS_ASSERT(impl == nullptr);
|
|
88
|
+
auto svs_metric = to_svs_metric(metric_type);
|
|
89
|
+
auto status = svs_runtime::FlatIndex::build(&impl, d, svs_metric);
|
|
90
|
+
if (!status.ok()) {
|
|
91
|
+
FAISS_THROW_MSG(status.message());
|
|
92
|
+
}
|
|
93
|
+
FAISS_THROW_IF_NOT(impl);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Serialization */
|
|
97
|
+
void IndexSVSFlat::serialize_impl(std::ostream& out) const {
|
|
98
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
99
|
+
impl, "Cannot serialize: SVS index not initialized.");
|
|
100
|
+
|
|
101
|
+
auto status = impl->save(out);
|
|
102
|
+
if (!status.ok()) {
|
|
103
|
+
FAISS_THROW_MSG(status.message());
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void IndexSVSFlat::deserialize_impl(std::istream& in) {
|
|
108
|
+
FAISS_THROW_IF_MSG(impl, "Cannot deserialize: SVS index already loaded.");
|
|
109
|
+
auto metric = to_svs_metric(metric_type);
|
|
110
|
+
auto status = impl->load(&impl, in, metric);
|
|
111
|
+
if (!status.ok()) {
|
|
112
|
+
FAISS_THROW_MSG(status.message());
|
|
113
|
+
}
|
|
114
|
+
FAISS_THROW_IF_NOT(impl);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
} // namespace faiss
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
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 2025 Intel Corporation
|
|
10
|
+
*
|
|
11
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
+
* you may not use this file except in compliance with the License.
|
|
13
|
+
* You may obtain a copy of the License at
|
|
14
|
+
*
|
|
15
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
+
*
|
|
17
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
+
* See the License for the specific language governing permissions and
|
|
21
|
+
* limitations under the License.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#pragma once
|
|
25
|
+
|
|
26
|
+
#include <faiss/Index.h>
|
|
27
|
+
#include <faiss/svs/IndexSVSFaissUtils.h>
|
|
28
|
+
|
|
29
|
+
#include <iostream>
|
|
30
|
+
|
|
31
|
+
namespace faiss {
|
|
32
|
+
|
|
33
|
+
struct IndexSVSFlat : Index {
|
|
34
|
+
// sequential labels
|
|
35
|
+
size_t nlabels{0};
|
|
36
|
+
|
|
37
|
+
IndexSVSFlat() = default;
|
|
38
|
+
IndexSVSFlat(idx_t d, MetricType metric = METRIC_L2);
|
|
39
|
+
|
|
40
|
+
~IndexSVSFlat() override;
|
|
41
|
+
|
|
42
|
+
void add(idx_t n, const float* x) override;
|
|
43
|
+
|
|
44
|
+
void search(
|
|
45
|
+
idx_t n,
|
|
46
|
+
const float* x,
|
|
47
|
+
idx_t k,
|
|
48
|
+
float* distances,
|
|
49
|
+
idx_t* labels,
|
|
50
|
+
const SearchParameters* params = nullptr) const override;
|
|
51
|
+
|
|
52
|
+
void reset() override;
|
|
53
|
+
|
|
54
|
+
/* The actual SVS implementation */
|
|
55
|
+
svs_runtime::FlatIndex* impl{nullptr};
|
|
56
|
+
|
|
57
|
+
/* Serialization */
|
|
58
|
+
void serialize_impl(std::ostream& out) const;
|
|
59
|
+
void deserialize_impl(std::istream& in);
|
|
60
|
+
|
|
61
|
+
protected:
|
|
62
|
+
/* Initializes the implementation*/
|
|
63
|
+
virtual void create_impl();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace faiss
|