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,8 +53,8 @@ void kernel_accumulate_block(
|
|
|
53
53
|
|
|
54
54
|
// _mm_prefetch(codes + 768, 0);
|
|
55
55
|
for (int sq = 0; sq < nsq - scaler.nscale; sq += 2) {
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
simd32uint8 c;
|
|
57
|
+
c.loadu(codes);
|
|
58
58
|
codes += 32;
|
|
59
59
|
|
|
60
60
|
simd32uint8 mask(0xf);
|
|
@@ -79,8 +79,8 @@ void kernel_accumulate_block(
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
for (int sq = 0; sq < scaler.nscale; sq += 2) {
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
simd32uint8 c;
|
|
83
|
+
c.loadu(codes);
|
|
84
84
|
codes += 32;
|
|
85
85
|
|
|
86
86
|
simd32uint8 mask(0xf);
|
|
@@ -623,7 +623,6 @@ void accumulate(
|
|
|
623
623
|
ResultHandler& res,
|
|
624
624
|
const Scaler& scaler) {
|
|
625
625
|
assert(nsq % 2 == 0);
|
|
626
|
-
assert(is_aligned_pointer(codes));
|
|
627
626
|
assert(is_aligned_pointer(LUT));
|
|
628
627
|
|
|
629
628
|
#define DISPATCH(NQ) \
|
|
@@ -782,7 +781,7 @@ void accumulate_to_mem(
|
|
|
782
781
|
}
|
|
783
782
|
|
|
784
783
|
int pq4_preferred_qbs(int n) {
|
|
785
|
-
// from
|
|
784
|
+
// from timings in P141901742, P141902828
|
|
786
785
|
static int map[12] = {
|
|
787
786
|
0, 1, 2, 3, 0x13, 0x23, 0x33, 0x223, 0x233, 0x333, 0x2233, 0x2333};
|
|
788
787
|
if (n <= 11) {
|
|
@@ -46,7 +46,7 @@ struct SIMDResultHandler {
|
|
|
46
46
|
virtual ~SIMDResultHandler() {}
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
/* Result handler that will return float
|
|
49
|
+
/* Result handler that will return float results eventually */
|
|
50
50
|
struct SIMDResultHandlerToFloat : SIMDResultHandler {
|
|
51
51
|
size_t nq; // number of queries
|
|
52
52
|
size_t ntotal; // ignore excess elements after ntotal
|
|
@@ -70,13 +70,35 @@ struct SIMDResultHandlerToFloat : SIMDResultHandler {
|
|
|
70
70
|
virtual void end() {
|
|
71
71
|
normalizers = nullptr;
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
// Number of updates made to the underlying data structure.
|
|
75
|
+
// For example: number of heap updates.
|
|
76
|
+
virtual size_t num_updates() {
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Set context information for handlers that need additional data
|
|
81
|
+
*
|
|
82
|
+
* This method can be overridden by handlers that need list numbers
|
|
83
|
+
* and probe mappings (e.g., RaBitQ handlers). Base implementation
|
|
84
|
+
* does nothing since most handlers don't need this context.
|
|
85
|
+
*
|
|
86
|
+
* @param list_no current inverted list number being processed
|
|
87
|
+
* @param probe_map mapping from local query index to probe index
|
|
88
|
+
*/
|
|
89
|
+
virtual void set_list_context(
|
|
90
|
+
size_t /* list_no */,
|
|
91
|
+
const std::vector<int>& /* probe_map */) {
|
|
92
|
+
// Default implementation does nothing
|
|
93
|
+
// Derived handlers can override if they need this context
|
|
94
|
+
}
|
|
73
95
|
};
|
|
74
96
|
|
|
75
97
|
FAISS_API extern bool simd_result_handlers_accept_virtual;
|
|
76
98
|
|
|
77
99
|
namespace simd_result_handlers {
|
|
78
100
|
|
|
79
|
-
/** Dummy structure that just computes a
|
|
101
|
+
/** Dummy structure that just computes a checksum on results
|
|
80
102
|
* (to avoid the computation to be optimized away) */
|
|
81
103
|
struct DummyResultHandler : SIMDResultHandler {
|
|
82
104
|
size_t cs = 0;
|
|
@@ -318,8 +340,8 @@ struct HeapHandler : ResultHandlerCompare<C, with_id_map> {
|
|
|
318
340
|
std::vector<TI> iids;
|
|
319
341
|
float* dis;
|
|
320
342
|
int64_t* ids;
|
|
321
|
-
|
|
322
|
-
|
|
343
|
+
size_t k; // number of results to keep
|
|
344
|
+
size_t nup = 0; // number of heap updates
|
|
323
345
|
|
|
324
346
|
HeapHandler(
|
|
325
347
|
size_t nq,
|
|
@@ -327,14 +349,30 @@ struct HeapHandler : ResultHandlerCompare<C, with_id_map> {
|
|
|
327
349
|
int64_t k,
|
|
328
350
|
float* dis,
|
|
329
351
|
int64_t* ids,
|
|
330
|
-
const IDSelector* sel_in
|
|
352
|
+
const IDSelector* sel_in,
|
|
353
|
+
const float* normalizers = nullptr)
|
|
331
354
|
: RHC(nq, ntotal, sel_in),
|
|
332
|
-
idis(nq * k),
|
|
333
|
-
iids(nq * k),
|
|
355
|
+
idis(nq * k, threshold_idis(dis, normalizers)),
|
|
356
|
+
iids(nq * k, -1),
|
|
334
357
|
dis(dis),
|
|
335
358
|
ids(ids),
|
|
336
|
-
k(k) {
|
|
337
|
-
|
|
359
|
+
k(k) {}
|
|
360
|
+
|
|
361
|
+
static uint16_t threshold_idis(float* dis_in, const float* normalizers) {
|
|
362
|
+
if (dis_in[0] == std::numeric_limits<float>::max()) {
|
|
363
|
+
return std::numeric_limits<uint16_t>::max();
|
|
364
|
+
}
|
|
365
|
+
if (dis_in[0] == std::numeric_limits<float>::lowest()) {
|
|
366
|
+
return 0;
|
|
367
|
+
}
|
|
368
|
+
if (normalizers) {
|
|
369
|
+
float one_a = 1 / normalizers[0], b = normalizers[1];
|
|
370
|
+
float f = (dis_in[0] - b) / one_a;
|
|
371
|
+
f = C::is_max ? std::ceil(f) : std::floor(f);
|
|
372
|
+
return std::clamp<float>(
|
|
373
|
+
f, 0, std::numeric_limits<uint16_t>::max());
|
|
374
|
+
}
|
|
375
|
+
return C::neutral();
|
|
338
376
|
}
|
|
339
377
|
|
|
340
378
|
void handle(size_t q, size_t b, simd16uint16 d0, simd16uint16 d1) final {
|
|
@@ -372,6 +410,7 @@ struct HeapHandler : ResultHandlerCompare<C, with_id_map> {
|
|
|
372
410
|
if (C::cmp(heap_dis[0], dis_2)) {
|
|
373
411
|
heap_replace_top<C>(
|
|
374
412
|
k, heap_dis, heap_ids, dis_2, real_idx);
|
|
413
|
+
nup++;
|
|
375
414
|
}
|
|
376
415
|
}
|
|
377
416
|
}
|
|
@@ -384,6 +423,7 @@ struct HeapHandler : ResultHandlerCompare<C, with_id_map> {
|
|
|
384
423
|
if (C::cmp(heap_dis[0], dis_2)) {
|
|
385
424
|
int64_t idx = this->adjust_id(b, j);
|
|
386
425
|
heap_replace_top<C>(k, heap_dis, heap_ids, dis_2, idx);
|
|
426
|
+
nup++;
|
|
387
427
|
}
|
|
388
428
|
}
|
|
389
429
|
}
|
|
@@ -408,6 +448,10 @@ struct HeapHandler : ResultHandlerCompare<C, with_id_map> {
|
|
|
408
448
|
}
|
|
409
449
|
}
|
|
410
450
|
}
|
|
451
|
+
|
|
452
|
+
size_t num_updates() override {
|
|
453
|
+
return nup;
|
|
454
|
+
}
|
|
411
455
|
};
|
|
412
456
|
|
|
413
457
|
/** Simple top-N implementation using a reservoir.
|
|
@@ -726,7 +770,7 @@ void dispatch_SIMDResultHandler_fixedCW(
|
|
|
726
770
|
} else { // generic handler -- will not be inlined
|
|
727
771
|
FAISS_THROW_IF_NOT_FMT(
|
|
728
772
|
simd_result_handlers_accept_virtual,
|
|
729
|
-
"Running
|
|
773
|
+
"Running virtual handler for %s",
|
|
730
774
|
typeid(res).name());
|
|
731
775
|
consumer.template f<SIMDResultHandler>(res, args...);
|
|
732
776
|
}
|
|
@@ -757,7 +801,7 @@ void dispatch_SIMDResultHandler(
|
|
|
757
801
|
} else { // generic path
|
|
758
802
|
FAISS_THROW_IF_NOT_FMT(
|
|
759
803
|
simd_result_handlers_accept_virtual,
|
|
760
|
-
"Running
|
|
804
|
+
"Running virtual handler for %s",
|
|
761
805
|
typeid(res).name());
|
|
762
806
|
consumer.template f<SIMDResultHandler>(res, args...);
|
|
763
807
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
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/impl/svs_io.h>
|
|
25
|
+
|
|
26
|
+
#include <algorithm>
|
|
27
|
+
#include <cstdlib>
|
|
28
|
+
|
|
29
|
+
#include <faiss/impl/FaissAssert.h>
|
|
30
|
+
|
|
31
|
+
namespace faiss {
|
|
32
|
+
namespace svs_io {
|
|
33
|
+
|
|
34
|
+
WriterStreambuf::WriterStreambuf(IOWriter* w_) : w(w_) {}
|
|
35
|
+
|
|
36
|
+
WriterStreambuf::~WriterStreambuf() = default;
|
|
37
|
+
|
|
38
|
+
std::streamsize WriterStreambuf::xsputn(const char* s, std::streamsize n) {
|
|
39
|
+
if (n <= 0)
|
|
40
|
+
return 0;
|
|
41
|
+
size_t wrote = (*w)(s, 1, static_cast<size_t>(n));
|
|
42
|
+
return static_cast<std::streamsize>(wrote);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
int WriterStreambuf::overflow(int ch) {
|
|
46
|
+
if (ch == traits_type::eof())
|
|
47
|
+
return 0;
|
|
48
|
+
char c = static_cast<char>(ch);
|
|
49
|
+
size_t wrote = (*w)(&c, 1, 1);
|
|
50
|
+
return wrote == 1 ? ch : traits_type::eof();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ReaderStreambuf::ReaderStreambuf(IOReader* rr) : r(rr), single_char_buffer(0) {
|
|
54
|
+
// Initialize with empty get area
|
|
55
|
+
setg(nullptr, nullptr, nullptr);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ReaderStreambuf::~ReaderStreambuf() = default;
|
|
59
|
+
|
|
60
|
+
std::streambuf::int_type ReaderStreambuf::underflow() {
|
|
61
|
+
// Called by std::istream for single-character operations (get, peek, etc.)
|
|
62
|
+
// when the get area is exhausted. Reads one byte from IOReader.
|
|
63
|
+
size_t got = (*r)(&single_char_buffer, 1, 1);
|
|
64
|
+
if (got == 0) {
|
|
65
|
+
return traits_type::eof();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Configure get area to expose the single buffered character
|
|
69
|
+
setg(&single_char_buffer, &single_char_buffer, &single_char_buffer + 1);
|
|
70
|
+
return traits_type::to_int_type(single_char_buffer);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
std::streamsize ReaderStreambuf::xsgetn(char* s, std::streamsize n) {
|
|
74
|
+
// Called by std::istream for bulk reads (read, readsome, etc.).
|
|
75
|
+
// Forwards directly to IOReader without intermediate buffering to avoid
|
|
76
|
+
// advancing IOReader beyond what the stream consumer requested.
|
|
77
|
+
if (n <= 0) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
size_t got = (*r)(s, 1, n);
|
|
82
|
+
return static_cast<std::streamsize>(got);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
} // namespace svs_io
|
|
86
|
+
} // namespace faiss
|
|
@@ -0,0 +1,67 @@
|
|
|
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 <iostream>
|
|
27
|
+
#include <streambuf>
|
|
28
|
+
#include <vector>
|
|
29
|
+
|
|
30
|
+
#include <faiss/impl/io.h>
|
|
31
|
+
|
|
32
|
+
namespace faiss {
|
|
33
|
+
namespace svs_io {
|
|
34
|
+
|
|
35
|
+
// Bridges IOWriter to std::ostream for streaming serialization.
|
|
36
|
+
// No buffering concerns since consumer is expected to write everything
|
|
37
|
+
// he receives.
|
|
38
|
+
struct WriterStreambuf : std::streambuf {
|
|
39
|
+
IOWriter* w;
|
|
40
|
+
explicit WriterStreambuf(IOWriter* w_);
|
|
41
|
+
~WriterStreambuf() override;
|
|
42
|
+
|
|
43
|
+
protected:
|
|
44
|
+
std::streamsize xsputn(const char* s, std::streamsize n) override;
|
|
45
|
+
int overflow(int ch) override;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Bridges IOReader to std::istream for streaming deserialization.
|
|
49
|
+
// Uses minimal buffering (single byte) to avoid over-reading from IOReader,
|
|
50
|
+
// which would advance its position beyond what the stream consumer actually
|
|
51
|
+
// read. This ensures subsequent direct reads from IOReader continue at the
|
|
52
|
+
// correct position. Bulk reads via xsgetn() forward directly to IOReader
|
|
53
|
+
// without intermediate buffering.
|
|
54
|
+
struct ReaderStreambuf : std::streambuf {
|
|
55
|
+
IOReader* r;
|
|
56
|
+
char single_char_buffer; // Single-byte buffer for underflow() operations
|
|
57
|
+
|
|
58
|
+
explicit ReaderStreambuf(IOReader* rr);
|
|
59
|
+
~ReaderStreambuf() override;
|
|
60
|
+
|
|
61
|
+
protected:
|
|
62
|
+
int_type underflow() override;
|
|
63
|
+
std::streamsize xsgetn(char* s, std::streamsize n) override;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace svs_io
|
|
67
|
+
} // namespace faiss
|
|
@@ -20,7 +20,7 @@ struct ZeroCopyIOReader : public faiss::IOReader {
|
|
|
20
20
|
size_t total_ = 0;
|
|
21
21
|
|
|
22
22
|
ZeroCopyIOReader(const uint8_t* data, size_t size);
|
|
23
|
-
~ZeroCopyIOReader();
|
|
23
|
+
~ZeroCopyIOReader() override;
|
|
24
24
|
|
|
25
25
|
void reset();
|
|
26
26
|
size_t get_data_view(void** ptr, size_t size, size_t nitems);
|
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
#include <faiss/IndexIVFAdditiveQuantizer.h>
|
|
28
28
|
#include <faiss/IndexIVFAdditiveQuantizerFastScan.h>
|
|
29
29
|
#include <faiss/IndexIVFFlat.h>
|
|
30
|
+
#include <faiss/IndexIVFFlatPanorama.h>
|
|
30
31
|
#include <faiss/IndexIVFPQ.h>
|
|
31
32
|
#include <faiss/IndexIVFPQFastScan.h>
|
|
32
33
|
#include <faiss/IndexIVFPQR.h>
|
|
33
34
|
#include <faiss/IndexIVFRaBitQ.h>
|
|
35
|
+
#include <faiss/IndexIVFRaBitQFastScan.h>
|
|
34
36
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
35
37
|
#include <faiss/IndexLSH.h>
|
|
36
38
|
#include <faiss/IndexLattice.h>
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
#include <faiss/IndexPQFastScan.h>
|
|
40
42
|
#include <faiss/IndexPreTransform.h>
|
|
41
43
|
#include <faiss/IndexRaBitQ.h>
|
|
44
|
+
#include <faiss/IndexRaBitQFastScan.h>
|
|
42
45
|
#include <faiss/IndexRefine.h>
|
|
43
46
|
#include <faiss/IndexRowwiseMinMax.h>
|
|
44
47
|
#include <faiss/IndexScalarQuantizer.h>
|
|
@@ -49,6 +52,16 @@
|
|
|
49
52
|
#include <faiss/IndexBinaryHNSW.h>
|
|
50
53
|
#include <faiss/IndexBinaryHash.h>
|
|
51
54
|
#include <faiss/IndexBinaryIVF.h>
|
|
55
|
+
|
|
56
|
+
#ifdef FAISS_ENABLE_SVS
|
|
57
|
+
#include <faiss/svs/IndexSVSFlat.h>
|
|
58
|
+
#include <faiss/svs/IndexSVSVamana.h>
|
|
59
|
+
#include <faiss/svs/IndexSVSVamanaLVQ.h>
|
|
60
|
+
#include <faiss/svs/IndexSVSVamanaLeanVec.h>
|
|
61
|
+
#endif
|
|
62
|
+
#include <faiss/IndexIDMap.h>
|
|
63
|
+
#include <algorithm>
|
|
64
|
+
#include <cctype>
|
|
52
65
|
#include <string>
|
|
53
66
|
|
|
54
67
|
namespace faiss {
|
|
@@ -187,8 +200,6 @@ std::vector<size_t> aq_parse_nbits(std::string stok) {
|
|
|
187
200
|
return nbits;
|
|
188
201
|
}
|
|
189
202
|
|
|
190
|
-
const std::string rabitq_pattern = "(RaBitQ)";
|
|
191
|
-
|
|
192
203
|
/***************************************************************
|
|
193
204
|
* Parse VectorTransform
|
|
194
205
|
*/
|
|
@@ -326,6 +337,10 @@ IndexIVF* parse_IndexIVF(
|
|
|
326
337
|
if (match("FlatDedup")) {
|
|
327
338
|
return new IndexIVFFlatDedup(get_q(), d, nlist, mt, own_il);
|
|
328
339
|
}
|
|
340
|
+
if (match("FlatPanorama([0-9]+)?")) {
|
|
341
|
+
int nlevels = mres_to_int(sm[1], 8); // default to 8 levels
|
|
342
|
+
return new IndexIVFFlatPanorama(get_q(), d, nlist, nlevels, mt, own_il);
|
|
343
|
+
}
|
|
329
344
|
if (match(sq_pattern)) {
|
|
330
345
|
return new IndexIVFScalarQuantizer(
|
|
331
346
|
get_q(),
|
|
@@ -447,8 +462,21 @@ IndexIVF* parse_IndexIVF(
|
|
|
447
462
|
}
|
|
448
463
|
return index_ivf;
|
|
449
464
|
}
|
|
450
|
-
|
|
451
|
-
|
|
465
|
+
// IndexIVFRaBitQ with optional nb_bits (1-9)
|
|
466
|
+
// Accepts: "RaBitQ" (default 1-bit) or "RaBitQ{nb_bits}" (e.g., "RaBitQ4")
|
|
467
|
+
if (match("RaBitQ([1-9])?")) {
|
|
468
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
469
|
+
return new IndexIVFRaBitQ(get_q(), d, nlist, mt, own_il, nb_bits);
|
|
470
|
+
}
|
|
471
|
+
// Accepts: "RaBitQfs" (default 1-bit, batch size 32)
|
|
472
|
+
// "RaBitQfs{nb_bits}" (e.g., "RaBitQfs4")
|
|
473
|
+
// "RaBitQfs_64" (1-bit, batch size 64)
|
|
474
|
+
// "RaBitQfs{nb_bits}_{bbs}" (e.g., "RaBitQfs4_64")
|
|
475
|
+
if (match("RaBitQfs([1-9])?(_[0-9]+)?")) {
|
|
476
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
477
|
+
int bbs = mres_to_int(sm[2], 32, 1);
|
|
478
|
+
return new IndexIVFRaBitQFastScan(
|
|
479
|
+
get_q(), d, nlist, mt, bbs, own_il, nb_bits);
|
|
452
480
|
}
|
|
453
481
|
return nullptr;
|
|
454
482
|
}
|
|
@@ -471,6 +499,11 @@ IndexHNSW* parse_IndexHNSW(
|
|
|
471
499
|
return new IndexHNSWFlat(d, hnsw_M, mt);
|
|
472
500
|
}
|
|
473
501
|
|
|
502
|
+
if (match("FlatPanorama([0-9]+)?")) {
|
|
503
|
+
int nlevels = mres_to_int(sm[1], 8); // default to 8 levels
|
|
504
|
+
return new IndexHNSWFlatPanorama(d, hnsw_M, nlevels, mt);
|
|
505
|
+
}
|
|
506
|
+
|
|
474
507
|
if (match("PQ([0-9]+)(x[0-9]+)?(np)?")) {
|
|
475
508
|
int M = std::stoi(sm[1].str());
|
|
476
509
|
int nbit = mres_to_int(sm[2], 8, 1);
|
|
@@ -537,6 +570,109 @@ IndexNSG* parse_IndexNSG(
|
|
|
537
570
|
return nullptr;
|
|
538
571
|
}
|
|
539
572
|
|
|
573
|
+
#ifdef FAISS_ENABLE_SVS
|
|
574
|
+
/***************************************************************
|
|
575
|
+
* Parse IndexSVS
|
|
576
|
+
*/
|
|
577
|
+
|
|
578
|
+
SVSStorageKind parse_lvq(const std::string& lvq_string) {
|
|
579
|
+
if (lvq_string == "LVQ4x0") {
|
|
580
|
+
return SVSStorageKind::SVS_LVQ4x0;
|
|
581
|
+
}
|
|
582
|
+
if (lvq_string == "LVQ4x4") {
|
|
583
|
+
return SVSStorageKind::SVS_LVQ4x4;
|
|
584
|
+
}
|
|
585
|
+
if (lvq_string == "LVQ4x8") {
|
|
586
|
+
return SVSStorageKind::SVS_LVQ4x8;
|
|
587
|
+
}
|
|
588
|
+
FAISS_ASSERT(!"not supported SVS LVQ level");
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
SVSStorageKind parse_leanvec(const std::string& leanvec_string) {
|
|
592
|
+
if (leanvec_string == "LeanVec4x4") {
|
|
593
|
+
return SVSStorageKind::SVS_LeanVec4x4;
|
|
594
|
+
}
|
|
595
|
+
if (leanvec_string == "LeanVec4x8") {
|
|
596
|
+
return SVSStorageKind::SVS_LeanVec4x8;
|
|
597
|
+
}
|
|
598
|
+
if (leanvec_string == "LeanVec8x8") {
|
|
599
|
+
return SVSStorageKind::SVS_LeanVec8x8;
|
|
600
|
+
}
|
|
601
|
+
FAISS_ASSERT(!"not supported SVS Leanvec level");
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
Index* parse_svs_datatype(
|
|
605
|
+
const std::string& index_type,
|
|
606
|
+
const std::string& arg_string,
|
|
607
|
+
const std::string& datatype_string,
|
|
608
|
+
int d,
|
|
609
|
+
MetricType mt) {
|
|
610
|
+
std::smatch sm;
|
|
611
|
+
|
|
612
|
+
if (datatype_string.empty()) {
|
|
613
|
+
if (index_type == "Vamana")
|
|
614
|
+
return new IndexSVSVamana(d, std::stoul(arg_string), mt);
|
|
615
|
+
if (index_type == "Flat")
|
|
616
|
+
return new IndexSVSFlat(d, mt);
|
|
617
|
+
FAISS_ASSERT(!"Unspported SVS index type");
|
|
618
|
+
}
|
|
619
|
+
if (re_match(datatype_string, "FP16", sm)) {
|
|
620
|
+
if (index_type == "Vamana")
|
|
621
|
+
return new IndexSVSVamana(
|
|
622
|
+
d, std::stoul(arg_string), mt, SVSStorageKind::SVS_FP16);
|
|
623
|
+
FAISS_ASSERT(!"Unspported SVS index type for Float16");
|
|
624
|
+
}
|
|
625
|
+
if (re_match(datatype_string, "SQI8", sm)) {
|
|
626
|
+
if (index_type == "Vamana")
|
|
627
|
+
return new IndexSVSVamana(
|
|
628
|
+
d, std::stoul(arg_string), mt, SVSStorageKind::SVS_SQI8);
|
|
629
|
+
FAISS_ASSERT(!"Unspported SVS index type for SQI8");
|
|
630
|
+
}
|
|
631
|
+
if (re_match(datatype_string, "(LVQ[0-9]+x[0-9]+)", sm)) {
|
|
632
|
+
if (index_type == "Vamana")
|
|
633
|
+
return new IndexSVSVamanaLVQ(
|
|
634
|
+
d, std::stoul(arg_string), mt, parse_lvq(sm[0].str()));
|
|
635
|
+
FAISS_ASSERT(!"Unspported SVS index type for LVQ");
|
|
636
|
+
}
|
|
637
|
+
if (re_match(datatype_string, "(LeanVec[0-9]+x[0-9]+)(_[0-9]+)?", sm)) {
|
|
638
|
+
std::string leanvec_d_string =
|
|
639
|
+
sm[2].length() > 0 ? sm[2].str().substr(1) : "0";
|
|
640
|
+
int leanvec_d = std::stoul(leanvec_d_string);
|
|
641
|
+
|
|
642
|
+
if (index_type == "Vamana")
|
|
643
|
+
return new IndexSVSVamanaLeanVec(
|
|
644
|
+
d,
|
|
645
|
+
std::stoul(arg_string),
|
|
646
|
+
mt,
|
|
647
|
+
leanvec_d,
|
|
648
|
+
parse_leanvec(sm[1].str()));
|
|
649
|
+
FAISS_ASSERT(!"Unspported SVS index type for LeanVec");
|
|
650
|
+
}
|
|
651
|
+
return nullptr;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
Index* parse_IndexSVS(const std::string& code_string, int d, MetricType mt) {
|
|
655
|
+
std::smatch sm;
|
|
656
|
+
if (re_match(code_string, "Flat(,.+)?", sm)) {
|
|
657
|
+
std::string datatype_string =
|
|
658
|
+
sm[1].length() > 0 ? sm[1].str().substr(1) : "";
|
|
659
|
+
return parse_svs_datatype("Flat", "", datatype_string, d, mt);
|
|
660
|
+
}
|
|
661
|
+
if (re_match(code_string, "Vamana([0-9]+)(,.+)?", sm)) {
|
|
662
|
+
Index* index{nullptr};
|
|
663
|
+
std::string degree_string = sm[1].str();
|
|
664
|
+
std::string datatype_string =
|
|
665
|
+
sm[2].length() > 0 ? sm[2].str().substr(1) : "";
|
|
666
|
+
return parse_svs_datatype(
|
|
667
|
+
"Vamana", degree_string, datatype_string, d, mt);
|
|
668
|
+
}
|
|
669
|
+
if (re_match(code_string, "IVF([0-9]+)(,.+)?", sm)) {
|
|
670
|
+
FAISS_ASSERT(!"Unspported SVS index type");
|
|
671
|
+
}
|
|
672
|
+
return nullptr;
|
|
673
|
+
}
|
|
674
|
+
#endif // FAISS_ENABLE_SVS
|
|
675
|
+
|
|
540
676
|
/***************************************************************
|
|
541
677
|
* Parse basic indexes
|
|
542
678
|
*/
|
|
@@ -555,6 +691,18 @@ Index* parse_other_indexes(
|
|
|
555
691
|
return new IndexFlat(d, metric);
|
|
556
692
|
}
|
|
557
693
|
|
|
694
|
+
// IndexFlatL2Panorama
|
|
695
|
+
if (match("FlatL2Panorama([0-9]+)(_[0-9]+)?")) {
|
|
696
|
+
FAISS_THROW_IF_NOT(metric == METRIC_L2);
|
|
697
|
+
int nlevels = std::stoi(sm[1].str());
|
|
698
|
+
if (sm[2].length() > 0) {
|
|
699
|
+
int batch_size = std::stoi(sm[2].str().substr(1));
|
|
700
|
+
return new IndexFlatL2Panorama(d, nlevels, (size_t)batch_size);
|
|
701
|
+
} else {
|
|
702
|
+
return new IndexFlatL2Panorama(d, nlevels);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
558
706
|
// IndexLSH
|
|
559
707
|
if (match("LSH([0-9]*)(r?)(t?)")) {
|
|
560
708
|
int nbits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : d;
|
|
@@ -671,9 +819,17 @@ Index* parse_other_indexes(
|
|
|
671
819
|
}
|
|
672
820
|
}
|
|
673
821
|
|
|
674
|
-
// IndexRaBitQ
|
|
675
|
-
|
|
676
|
-
|
|
822
|
+
// IndexRaBitQ with optional nb_bits (1-9)
|
|
823
|
+
// Accepts: "RaBitQ" (default 1-bit) or "RaBitQ{nb_bits}" (e.g., "RaBitQ4")
|
|
824
|
+
if (match("RaBitQ([1-9])?")) {
|
|
825
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
826
|
+
return new IndexRaBitQ(d, metric, nb_bits);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (match("RaBitQfs([1-9])?(_[0-9]+)?")) {
|
|
830
|
+
uint8_t nb_bits = sm[1].length() > 0 ? std::stoi(sm[1].str()) : 1;
|
|
831
|
+
int bbs = mres_to_int(sm[2], 32, 1);
|
|
832
|
+
return new IndexRaBitQFastScan(d, metric, bbs, nb_bits);
|
|
677
833
|
}
|
|
678
834
|
|
|
679
835
|
return nullptr;
|
|
@@ -716,6 +872,18 @@ std::unique_ptr<Index> index_factory_sub(
|
|
|
716
872
|
return std::unique_ptr<Index>(idmap);
|
|
717
873
|
}
|
|
718
874
|
|
|
875
|
+
// handle refine Panorama
|
|
876
|
+
// TODO(aknayar): Add tests to test_factory.py
|
|
877
|
+
if (re_match(description, "(.+),RefinePanorama\\((.+)\\)", sm)) {
|
|
878
|
+
std::unique_ptr<Index> filter_index =
|
|
879
|
+
index_factory_sub(d, sm[1].str(), metric);
|
|
880
|
+
std::unique_ptr<Index> refine_index =
|
|
881
|
+
index_factory_sub(d, sm[2].str(), metric);
|
|
882
|
+
auto* index_rf = new IndexRefinePanorama(
|
|
883
|
+
filter_index.release(), refine_index.release());
|
|
884
|
+
return std::unique_ptr<Index>(index_rf);
|
|
885
|
+
}
|
|
886
|
+
|
|
719
887
|
// handle refines
|
|
720
888
|
if (re_match(description, "(.+),RFlat", sm) ||
|
|
721
889
|
re_match(description, "(.+),Refine\\((.+)\\)", sm)) {
|
|
@@ -822,6 +990,25 @@ std::unique_ptr<Index> index_factory_sub(
|
|
|
822
990
|
return std::unique_ptr<Index>(index);
|
|
823
991
|
}
|
|
824
992
|
|
|
993
|
+
#ifdef FAISS_ENABLE_SVS
|
|
994
|
+
if (re_match(description, "SVS((?:Flat|Vamana|IVF).*)", sm)) {
|
|
995
|
+
std::string code_string = sm[1].str();
|
|
996
|
+
if (verbose) {
|
|
997
|
+
printf("parsing SVS string %s code_string=%s",
|
|
998
|
+
description.c_str(),
|
|
999
|
+
code_string.c_str());
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
Index* index = parse_IndexSVS(code_string, d, metric);
|
|
1003
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
1004
|
+
index,
|
|
1005
|
+
"could not parse SVS code description %s in %s",
|
|
1006
|
+
code_string.c_str(),
|
|
1007
|
+
description.c_str());
|
|
1008
|
+
return std::unique_ptr<Index>(index);
|
|
1009
|
+
}
|
|
1010
|
+
#endif // FAISS_ENABLE_SVS
|
|
1011
|
+
|
|
825
1012
|
// NSG variants (it was unclear in the old version that the separator was a
|
|
826
1013
|
// "," so we support both "_" and ",")
|
|
827
1014
|
if (re_match(description, "NSG([0-9]*)([,_].*)?", sm)) {
|
|
@@ -934,6 +1121,28 @@ IndexBinary* index_binary_factory(
|
|
|
934
1121
|
bool own_invlists) {
|
|
935
1122
|
IndexBinary* index = nullptr;
|
|
936
1123
|
|
|
1124
|
+
std::smatch sm;
|
|
1125
|
+
std::string desc_str(description);
|
|
1126
|
+
|
|
1127
|
+
// Handle IDMap2 and IDMap wrappers (prefix or suffix)
|
|
1128
|
+
if (re_match(desc_str, "(.+),IDMap2", sm) ||
|
|
1129
|
+
re_match(desc_str, "IDMap2,(.+)", sm)) {
|
|
1130
|
+
IndexBinary* sub_index =
|
|
1131
|
+
index_binary_factory(d, sm[1].str().c_str(), own_invlists);
|
|
1132
|
+
IndexBinaryIDMap2* idmap2 = new IndexBinaryIDMap2(sub_index);
|
|
1133
|
+
idmap2->own_fields = true;
|
|
1134
|
+
return idmap2;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (re_match(desc_str, "(.+),IDMap", sm) ||
|
|
1138
|
+
re_match(desc_str, "IDMap,(.+)", sm)) {
|
|
1139
|
+
IndexBinary* sub_index =
|
|
1140
|
+
index_binary_factory(d, sm[1].str().c_str(), own_invlists);
|
|
1141
|
+
IndexBinaryIDMap* idmap = new IndexBinaryIDMap(sub_index);
|
|
1142
|
+
idmap->own_fields = true;
|
|
1143
|
+
return idmap;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
937
1146
|
int ncentroids = -1;
|
|
938
1147
|
int M, nhash, b;
|
|
939
1148
|
|
|
@@ -959,7 +1168,7 @@ IndexBinary* index_binary_factory(
|
|
|
959
1168
|
} else if (sscanf(description, "BHash%d", &b) == 1) {
|
|
960
1169
|
index = new IndexBinaryHash(d, b);
|
|
961
1170
|
|
|
962
|
-
} else if (
|
|
1171
|
+
} else if (desc_str == "BFlat") {
|
|
963
1172
|
index = new IndexBinaryFlat(d);
|
|
964
1173
|
|
|
965
1174
|
} else {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* object that abstracts the medium.
|
|
17
17
|
*
|
|
18
18
|
* The read functions return objects that should be deallocated with
|
|
19
|
-
* delete. All references within these
|
|
19
|
+
* delete. All references within these objects are owned by the
|
|
20
20
|
* object.
|
|
21
21
|
*/
|
|
22
22
|
|
|
@@ -20,7 +20,7 @@ struct IDSelector;
|
|
|
20
20
|
/** Inverted Lists that are organized by blocks.
|
|
21
21
|
*
|
|
22
22
|
* Different from the regular inverted lists, the codes are organized by blocks
|
|
23
|
-
* of size block_size bytes that
|
|
23
|
+
* of size block_size bytes that represent a set of n_per_block. Therefore, code
|
|
24
24
|
* allocations are always rounded up to block_size bytes. The codes are also
|
|
25
25
|
* aligned on 32-byte boundaries for use with SIMD.
|
|
26
26
|
*
|