faiss 0.3.4 → 0.4.0
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 +5 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +11 -8
- data/vendor/faiss/faiss/Clustering.cpp +0 -16
- data/vendor/faiss/faiss/IVFlib.cpp +213 -0
- data/vendor/faiss/faiss/IVFlib.h +42 -0
- data/vendor/faiss/faiss/Index.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -7
- data/vendor/faiss/faiss/IndexBinaryFlat.h +2 -1
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +1 -1
- data/vendor/faiss/faiss/IndexFlatCodes.h +4 -2
- data/vendor/faiss/faiss/IndexHNSW.cpp +13 -20
- data/vendor/faiss/faiss/IndexHNSW.h +1 -1
- data/vendor/faiss/faiss/IndexIVF.cpp +20 -3
- data/vendor/faiss/faiss/IndexIVF.h +5 -2
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +2 -1
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +2 -1
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +2 -1
- data/vendor/faiss/faiss/IndexIVFFlat.h +2 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +2 -1
- data/vendor/faiss/faiss/IndexIVFPQ.h +2 -1
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +277 -0
- data/vendor/faiss/faiss/IndexIVFRaBitQ.h +70 -0
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +2 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +2 -1
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +148 -0
- data/vendor/faiss/faiss/IndexRaBitQ.h +65 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +2 -1
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +2 -1
- data/vendor/faiss/faiss/clone_index.cpp +38 -3
- data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +19 -0
- data/vendor/faiss/faiss/cppcontrib/factory_tools.h +4 -11
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +2 -1
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +13 -3
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +1 -1
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +1 -1
- data/vendor/faiss/faiss/gpu/test/TestGpuIcmEncoder.cpp +112 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +35 -13
- data/vendor/faiss/faiss/impl/HNSW.h +5 -4
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -1
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +519 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +78 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +2 -2
- data/vendor/faiss/faiss/impl/code_distance/code_distance-sve.h +3 -4
- data/vendor/faiss/faiss/impl/index_read.cpp +220 -25
- data/vendor/faiss/faiss/impl/index_write.cpp +29 -0
- data/vendor/faiss/faiss/impl/io.h +2 -2
- data/vendor/faiss/faiss/impl/io_macros.h +2 -0
- data/vendor/faiss/faiss/impl/mapped_io.cpp +313 -0
- data/vendor/faiss/faiss/impl/mapped_io.h +51 -0
- data/vendor/faiss/faiss/impl/maybe_owned_vector.h +316 -0
- data/vendor/faiss/faiss/impl/platform_macros.h +7 -3
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +1 -1
- data/vendor/faiss/faiss/impl/zerocopy_io.cpp +67 -0
- data/vendor/faiss/faiss/impl/zerocopy_io.h +32 -0
- data/vendor/faiss/faiss/index_factory.cpp +16 -5
- data/vendor/faiss/faiss/index_io.h +4 -0
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +3 -3
- data/vendor/faiss/faiss/invlists/InvertedLists.h +5 -3
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +3 -3
- data/vendor/faiss/faiss/python/python_callbacks.cpp +24 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +22 -0
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +30 -12
- data/vendor/faiss/faiss/utils/hamming.cpp +45 -21
- data/vendor/faiss/faiss/utils/hamming.h +7 -3
- data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +1 -1
- data/vendor/faiss/faiss/utils/utils.cpp +4 -4
- data/vendor/faiss/faiss/utils/utils.h +3 -3
- metadata +16 -4
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
#include <cstdio>
|
14
14
|
#include <cstdlib>
|
15
|
+
#include <optional>
|
15
16
|
|
16
17
|
#include <faiss/impl/FaissAssert.h>
|
17
18
|
#include <faiss/impl/io.h>
|
@@ -33,6 +34,7 @@
|
|
33
34
|
#include <faiss/IndexIVFPQ.h>
|
34
35
|
#include <faiss/IndexIVFPQFastScan.h>
|
35
36
|
#include <faiss/IndexIVFPQR.h>
|
37
|
+
#include <faiss/IndexIVFRaBitQ.h>
|
36
38
|
#include <faiss/IndexIVFSpectralHash.h>
|
37
39
|
#include <faiss/IndexLSH.h>
|
38
40
|
#include <faiss/IndexLattice.h>
|
@@ -41,6 +43,7 @@
|
|
41
43
|
#include <faiss/IndexPQ.h>
|
42
44
|
#include <faiss/IndexPQFastScan.h>
|
43
45
|
#include <faiss/IndexPreTransform.h>
|
46
|
+
#include <faiss/IndexRaBitQ.h>
|
44
47
|
#include <faiss/IndexRefine.h>
|
45
48
|
#include <faiss/IndexRowwiseMinMax.h>
|
46
49
|
#include <faiss/IndexScalarQuantizer.h>
|
@@ -53,8 +56,141 @@
|
|
53
56
|
#include <faiss/IndexBinaryHash.h>
|
54
57
|
#include <faiss/IndexBinaryIVF.h>
|
55
58
|
|
59
|
+
// mmap-ing and viewing facilities
|
60
|
+
#include <faiss/impl/maybe_owned_vector.h>
|
61
|
+
|
62
|
+
#include <faiss/impl/mapped_io.h>
|
63
|
+
#include <faiss/impl/zerocopy_io.h>
|
64
|
+
|
56
65
|
namespace faiss {
|
57
66
|
|
67
|
+
/*************************************************************
|
68
|
+
* Mmap-ing and viewing facilities
|
69
|
+
**************************************************************/
|
70
|
+
|
71
|
+
// This is a baseline functionality for reading mmapped and zerocopied vector.
|
72
|
+
// * if `beforeknown_size` is defined, then a size of the vector won't be read.
|
73
|
+
// * if `size_multiplier` is defined, then a size will be multiplied by it.
|
74
|
+
// * returns true is the case was handled; ownerwise, false
|
75
|
+
template <typename VectorT>
|
76
|
+
bool read_vector_base(
|
77
|
+
VectorT& target,
|
78
|
+
IOReader* f,
|
79
|
+
const std::optional<size_t> beforeknown_size,
|
80
|
+
const std::optional<size_t> size_multiplier) {
|
81
|
+
// check if the use case is right
|
82
|
+
if constexpr (is_maybe_owned_vector_v<VectorT>) {
|
83
|
+
// is it a mmap-enabled reader?
|
84
|
+
MappedFileIOReader* mf = dynamic_cast<MappedFileIOReader*>(f);
|
85
|
+
if (mf != nullptr) {
|
86
|
+
// read the size or use a known one
|
87
|
+
size_t size = 0;
|
88
|
+
if (beforeknown_size.has_value()) {
|
89
|
+
size = beforeknown_size.value();
|
90
|
+
} else {
|
91
|
+
READANDCHECK(&size, 1);
|
92
|
+
}
|
93
|
+
|
94
|
+
// perform the size multiplication
|
95
|
+
size *= size_multiplier.value_or(1);
|
96
|
+
|
97
|
+
// ok, mmap and check
|
98
|
+
char* address = nullptr;
|
99
|
+
const size_t nread = mf->mmap(
|
100
|
+
(void**)&address,
|
101
|
+
sizeof(typename VectorT::value_type),
|
102
|
+
size);
|
103
|
+
|
104
|
+
FAISS_THROW_IF_NOT_FMT(
|
105
|
+
nread == (size),
|
106
|
+
"read error in %s: %zd != %zd (%s)",
|
107
|
+
f->name.c_str(),
|
108
|
+
nread,
|
109
|
+
size,
|
110
|
+
strerror(errno));
|
111
|
+
|
112
|
+
VectorT mmapped_view =
|
113
|
+
VectorT::create_view(address, nread, mf->mmap_owner);
|
114
|
+
target = std::move(mmapped_view);
|
115
|
+
|
116
|
+
return true;
|
117
|
+
}
|
118
|
+
|
119
|
+
// is it a zero-copy reader?
|
120
|
+
ZeroCopyIOReader* zr = dynamic_cast<ZeroCopyIOReader*>(f);
|
121
|
+
if (zr != nullptr) {
|
122
|
+
// read the size or use a known one
|
123
|
+
size_t size = 0;
|
124
|
+
if (beforeknown_size.has_value()) {
|
125
|
+
size = beforeknown_size.value();
|
126
|
+
} else {
|
127
|
+
READANDCHECK(&size, 1);
|
128
|
+
}
|
129
|
+
|
130
|
+
// perform the size multiplication
|
131
|
+
size *= size_multiplier.value_or(1);
|
132
|
+
|
133
|
+
// create a view
|
134
|
+
char* address = nullptr;
|
135
|
+
size_t nread = zr->get_data_view(
|
136
|
+
(void**)&address,
|
137
|
+
sizeof(typename VectorT::value_type),
|
138
|
+
size);
|
139
|
+
|
140
|
+
FAISS_THROW_IF_NOT_FMT(
|
141
|
+
nread == (size),
|
142
|
+
"read error in %s: %zd != %zd (%s)",
|
143
|
+
f->name.c_str(),
|
144
|
+
nread,
|
145
|
+
size_t(size),
|
146
|
+
strerror(errno));
|
147
|
+
|
148
|
+
VectorT view = VectorT::create_view(address, nread, nullptr);
|
149
|
+
target = std::move(view);
|
150
|
+
|
151
|
+
return true;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
return false;
|
156
|
+
}
|
157
|
+
|
158
|
+
// a replacement for READANDCHECK for reading data into std::vector
|
159
|
+
template <typename VectorT>
|
160
|
+
void read_vector_with_known_size(VectorT& target, IOReader* f, size_t size) {
|
161
|
+
// size is known beforehand, no size multiplication
|
162
|
+
if (read_vector_base<VectorT>(target, f, size, std::nullopt)) {
|
163
|
+
return;
|
164
|
+
}
|
165
|
+
|
166
|
+
// the default case
|
167
|
+
READANDCHECK(target.data(), size);
|
168
|
+
}
|
169
|
+
|
170
|
+
// a replacement for READVECTOR
|
171
|
+
template <typename VectorT>
|
172
|
+
void read_vector(VectorT& target, IOReader* f) {
|
173
|
+
// size is not known beforehand, no size multiplication
|
174
|
+
if (read_vector_base<VectorT>(target, f, std::nullopt, std::nullopt)) {
|
175
|
+
return;
|
176
|
+
}
|
177
|
+
|
178
|
+
// the default case
|
179
|
+
READVECTOR(target);
|
180
|
+
}
|
181
|
+
|
182
|
+
// a replacement for READXBVECTOR
|
183
|
+
template <typename VectorT>
|
184
|
+
void read_xb_vector(VectorT& target, IOReader* f) {
|
185
|
+
// size is not known beforehand, nultiply the size 4x
|
186
|
+
if (read_vector_base<VectorT>(target, f, std::nullopt, 4)) {
|
187
|
+
return;
|
188
|
+
}
|
189
|
+
|
190
|
+
// the default case
|
191
|
+
READXBVECTOR(target);
|
192
|
+
}
|
193
|
+
|
58
194
|
/*************************************************************
|
59
195
|
* Read
|
60
196
|
**************************************************************/
|
@@ -205,8 +341,9 @@ InvertedLists* read_InvertedLists(IOReader* f, int io_flags) {
|
|
205
341
|
for (size_t i = 0; i < ails->nlist; i++) {
|
206
342
|
size_t n = ails->ids[i].size();
|
207
343
|
if (n > 0) {
|
208
|
-
|
209
|
-
|
344
|
+
read_vector_with_known_size(
|
345
|
+
ails->codes[i], f, n * ails->code_size);
|
346
|
+
read_vector_with_known_size(ails->ids[i], f, n);
|
210
347
|
}
|
211
348
|
}
|
212
349
|
return ails;
|
@@ -275,7 +412,7 @@ static void read_AdditiveQuantizer(AdditiveQuantizer* aq, IOReader* f) {
|
|
275
412
|
aq->search_type == AdditiveQuantizer::ST_norm_cqint4 ||
|
276
413
|
aq->search_type == AdditiveQuantizer::ST_norm_lsq2x4 ||
|
277
414
|
aq->search_type == AdditiveQuantizer::ST_norm_rq2x4) {
|
278
|
-
|
415
|
+
read_xb_vector(aq->qnorm.codes, f);
|
279
416
|
aq->qnorm.ntotal = aq->qnorm.codes.size() / 4;
|
280
417
|
aq->qnorm.update_permutation();
|
281
418
|
}
|
@@ -365,7 +502,7 @@ static void read_HNSW(HNSW* hnsw, IOReader* f) {
|
|
365
502
|
READVECTOR(hnsw->cum_nneighbor_per_level);
|
366
503
|
READVECTOR(hnsw->levels);
|
367
504
|
READVECTOR(hnsw->offsets);
|
368
|
-
|
505
|
+
read_vector(hnsw->neighbors, f);
|
369
506
|
|
370
507
|
READ1(hnsw->entry_point);
|
371
508
|
READ1(hnsw->max_level);
|
@@ -439,6 +576,13 @@ ProductQuantizer* read_ProductQuantizer(IOReader* reader) {
|
|
439
576
|
return pq;
|
440
577
|
}
|
441
578
|
|
579
|
+
static void read_RaBitQuantizer(RaBitQuantizer* rabitq, IOReader* f) {
|
580
|
+
// don't care about rabitq->centroid
|
581
|
+
READ1(rabitq->d);
|
582
|
+
READ1(rabitq->code_size);
|
583
|
+
READ1(rabitq->metric_type);
|
584
|
+
}
|
585
|
+
|
442
586
|
void read_direct_map(DirectMap* dm, IOReader* f) {
|
443
587
|
char maintain_direct_map;
|
444
588
|
READ1(maintain_direct_map);
|
@@ -478,7 +622,12 @@ ArrayInvertedLists* set_array_invlist(
|
|
478
622
|
std::vector<std::vector<idx_t>>& ids) {
|
479
623
|
ArrayInvertedLists* ail =
|
480
624
|
new ArrayInvertedLists(ivf->nlist, ivf->code_size);
|
481
|
-
|
625
|
+
|
626
|
+
ail->ids.resize(ids.size());
|
627
|
+
for (size_t i = 0; i < ids.size(); i++) {
|
628
|
+
ail->ids[i] = MaybeOwnedVector<idx_t>(std::move(ids[i]));
|
629
|
+
}
|
630
|
+
|
482
631
|
ivf->invlists = ail;
|
483
632
|
ivf->own_invlists = true;
|
484
633
|
return ail;
|
@@ -545,7 +694,7 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
545
694
|
}
|
546
695
|
read_index_header(idxf, f);
|
547
696
|
idxf->code_size = idxf->d * sizeof(float);
|
548
|
-
|
697
|
+
read_xb_vector(idxf->codes, f);
|
549
698
|
FAISS_THROW_IF_NOT(
|
550
699
|
idxf->codes.size() == idxf->ntotal * idxf->code_size);
|
551
700
|
// leak!
|
@@ -576,7 +725,7 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
576
725
|
idxl->rrot = *rrot;
|
577
726
|
delete rrot;
|
578
727
|
}
|
579
|
-
|
728
|
+
read_vector(idxl->codes, f);
|
580
729
|
FAISS_THROW_IF_NOT(
|
581
730
|
idxl->rrot.d_in == idxl->d && idxl->rrot.d_out == idxl->nbits);
|
582
731
|
FAISS_THROW_IF_NOT(
|
@@ -589,7 +738,7 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
589
738
|
read_index_header(idxp, f);
|
590
739
|
read_ProductQuantizer(&idxp->pq, f);
|
591
740
|
idxp->code_size = idxp->pq.code_size;
|
592
|
-
|
741
|
+
read_vector(idxp->codes, f);
|
593
742
|
if (h == fourcc("IxPo") || h == fourcc("IxPq")) {
|
594
743
|
READ1(idxp->search_type);
|
595
744
|
READ1(idxp->encode_signs);
|
@@ -611,28 +760,28 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
611
760
|
read_ResidualQuantizer(&idxr->rq, f, io_flags);
|
612
761
|
}
|
613
762
|
READ1(idxr->code_size);
|
614
|
-
|
763
|
+
read_vector(idxr->codes, f);
|
615
764
|
idx = idxr;
|
616
765
|
} else if (h == fourcc("IxLS")) {
|
617
766
|
auto idxr = new IndexLocalSearchQuantizer();
|
618
767
|
read_index_header(idxr, f);
|
619
768
|
read_LocalSearchQuantizer(&idxr->lsq, f);
|
620
769
|
READ1(idxr->code_size);
|
621
|
-
|
770
|
+
read_vector(idxr->codes, f);
|
622
771
|
idx = idxr;
|
623
772
|
} else if (h == fourcc("IxPR")) {
|
624
773
|
auto idxpr = new IndexProductResidualQuantizer();
|
625
774
|
read_index_header(idxpr, f);
|
626
775
|
read_ProductResidualQuantizer(&idxpr->prq, f, io_flags);
|
627
776
|
READ1(idxpr->code_size);
|
628
|
-
|
777
|
+
read_vector(idxpr->codes, f);
|
629
778
|
idx = idxpr;
|
630
779
|
} else if (h == fourcc("IxPL")) {
|
631
780
|
auto idxpl = new IndexProductLocalSearchQuantizer();
|
632
781
|
read_index_header(idxpl, f);
|
633
782
|
read_ProductLocalSearchQuantizer(&idxpl->plsq, f);
|
634
783
|
READ1(idxpl->code_size);
|
635
|
-
|
784
|
+
read_vector(idxpl->codes, f);
|
636
785
|
idx = idxpl;
|
637
786
|
} else if (h == fourcc("ImRQ")) {
|
638
787
|
ResidualCoarseQuantizer* idxr = new ResidualCoarseQuantizer();
|
@@ -789,7 +938,7 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
789
938
|
IndexScalarQuantizer* idxs = new IndexScalarQuantizer();
|
790
939
|
read_index_header(idxs, f);
|
791
940
|
read_ScalarQuantizer(&idxs->sq, f);
|
792
|
-
|
941
|
+
read_vector(idxs->codes, f);
|
793
942
|
idxs->code_size = idxs->sq.code_size;
|
794
943
|
idx = idxs;
|
795
944
|
} else if (h == fourcc("IxLa")) {
|
@@ -947,7 +1096,7 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
947
1096
|
READ1(idxp->code_size_1);
|
948
1097
|
READ1(idxp->code_size_2);
|
949
1098
|
READ1(idxp->code_size);
|
950
|
-
|
1099
|
+
read_vector(idxp->codes, f);
|
951
1100
|
idx = idxp;
|
952
1101
|
} else if (
|
953
1102
|
h == fourcc("IHNf") || h == fourcc("IHNp") || h == fourcc("IHNs") ||
|
@@ -1060,6 +1209,24 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
1060
1209
|
imm->own_fields = true;
|
1061
1210
|
|
1062
1211
|
idx = imm;
|
1212
|
+
} else if (h == fourcc("Ixrq")) {
|
1213
|
+
IndexRaBitQ* idxq = new IndexRaBitQ();
|
1214
|
+
read_index_header(idxq, f);
|
1215
|
+
read_RaBitQuantizer(&idxq->rabitq, f);
|
1216
|
+
READVECTOR(idxq->codes);
|
1217
|
+
READVECTOR(idxq->center);
|
1218
|
+
READ1(idxq->qb);
|
1219
|
+
idxq->code_size = idxq->rabitq.code_size;
|
1220
|
+
idx = idxq;
|
1221
|
+
} else if (h == fourcc("Iwrq")) {
|
1222
|
+
IndexIVFRaBitQ* ivrq = new IndexIVFRaBitQ();
|
1223
|
+
read_ivf_header(ivrq, f);
|
1224
|
+
read_RaBitQuantizer(&ivrq->rabitq, f);
|
1225
|
+
READ1(ivrq->code_size);
|
1226
|
+
READ1(ivrq->by_residual);
|
1227
|
+
READ1(ivrq->qb);
|
1228
|
+
read_InvertedLists(ivrq, f, io_flags);
|
1229
|
+
idx = ivrq;
|
1063
1230
|
} else {
|
1064
1231
|
FAISS_THROW_FMT(
|
1065
1232
|
"Index type 0x%08x (\"%s\") not recognized",
|
@@ -1071,14 +1238,28 @@ Index* read_index(IOReader* f, int io_flags) {
|
|
1071
1238
|
}
|
1072
1239
|
|
1073
1240
|
Index* read_index(FILE* f, int io_flags) {
|
1074
|
-
|
1075
|
-
|
1241
|
+
if ((io_flags & IO_FLAG_MMAP_IFC) == IO_FLAG_MMAP_IFC) {
|
1242
|
+
// enable mmap-supporting IOReader
|
1243
|
+
auto owner = std::make_shared<MmappedFileMappingOwner>(f);
|
1244
|
+
MappedFileIOReader reader(owner);
|
1245
|
+
return read_index(&reader, io_flags);
|
1246
|
+
} else {
|
1247
|
+
FileIOReader reader(f);
|
1248
|
+
return read_index(&reader, io_flags);
|
1249
|
+
}
|
1076
1250
|
}
|
1077
1251
|
|
1078
1252
|
Index* read_index(const char* fname, int io_flags) {
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1253
|
+
if ((io_flags & IO_FLAG_MMAP_IFC) == IO_FLAG_MMAP_IFC) {
|
1254
|
+
// enable mmap-supporting IOReader
|
1255
|
+
auto owner = std::make_shared<MmappedFileMappingOwner>(fname);
|
1256
|
+
MappedFileIOReader reader(owner);
|
1257
|
+
return read_index(&reader, io_flags);
|
1258
|
+
} else {
|
1259
|
+
FileIOReader reader(fname);
|
1260
|
+
Index* idx = read_index(&reader, io_flags);
|
1261
|
+
return idx;
|
1262
|
+
}
|
1082
1263
|
}
|
1083
1264
|
|
1084
1265
|
VectorTransform* read_VectorTransform(const char* fname) {
|
@@ -1181,7 +1362,7 @@ IndexBinary* read_index_binary(IOReader* f, int io_flags) {
|
|
1181
1362
|
if (h == fourcc("IBxF")) {
|
1182
1363
|
IndexBinaryFlat* idxf = new IndexBinaryFlat();
|
1183
1364
|
read_index_binary_header(idxf, f);
|
1184
|
-
|
1365
|
+
read_vector(idxf->xb, f);
|
1185
1366
|
FAISS_THROW_IF_NOT(idxf->xb.size() == idxf->ntotal * idxf->code_size);
|
1186
1367
|
// leak!
|
1187
1368
|
idx = idxf;
|
@@ -1249,14 +1430,28 @@ IndexBinary* read_index_binary(IOReader* f, int io_flags) {
|
|
1249
1430
|
}
|
1250
1431
|
|
1251
1432
|
IndexBinary* read_index_binary(FILE* f, int io_flags) {
|
1252
|
-
|
1253
|
-
|
1433
|
+
if ((io_flags & IO_FLAG_MMAP_IFC) == IO_FLAG_MMAP_IFC) {
|
1434
|
+
// enable mmap-supporting IOReader
|
1435
|
+
auto owner = std::make_shared<MmappedFileMappingOwner>(f);
|
1436
|
+
MappedFileIOReader reader(owner);
|
1437
|
+
return read_index_binary(&reader, io_flags);
|
1438
|
+
} else {
|
1439
|
+
FileIOReader reader(f);
|
1440
|
+
return read_index_binary(&reader, io_flags);
|
1441
|
+
}
|
1254
1442
|
}
|
1255
1443
|
|
1256
1444
|
IndexBinary* read_index_binary(const char* fname, int io_flags) {
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1445
|
+
if ((io_flags & IO_FLAG_MMAP_IFC) == IO_FLAG_MMAP_IFC) {
|
1446
|
+
// enable mmap-supporting IOReader
|
1447
|
+
auto owner = std::make_shared<MmappedFileMappingOwner>(fname);
|
1448
|
+
MappedFileIOReader reader(owner);
|
1449
|
+
return read_index_binary(&reader, io_flags);
|
1450
|
+
} else {
|
1451
|
+
FileIOReader reader(fname);
|
1452
|
+
IndexBinary* idx = read_index_binary(&reader, io_flags);
|
1453
|
+
return idx;
|
1454
|
+
}
|
1260
1455
|
}
|
1261
1456
|
|
1262
1457
|
} // namespace faiss
|
@@ -32,6 +32,7 @@
|
|
32
32
|
#include <faiss/IndexIVFPQ.h>
|
33
33
|
#include <faiss/IndexIVFPQFastScan.h>
|
34
34
|
#include <faiss/IndexIVFPQR.h>
|
35
|
+
#include <faiss/IndexIVFRaBitQ.h>
|
35
36
|
#include <faiss/IndexIVFSpectralHash.h>
|
36
37
|
#include <faiss/IndexLSH.h>
|
37
38
|
#include <faiss/IndexLattice.h>
|
@@ -40,6 +41,7 @@
|
|
40
41
|
#include <faiss/IndexPQ.h>
|
41
42
|
#include <faiss/IndexPQFastScan.h>
|
42
43
|
#include <faiss/IndexPreTransform.h>
|
44
|
+
#include <faiss/IndexRaBitQ.h>
|
43
45
|
#include <faiss/IndexRefine.h>
|
44
46
|
#include <faiss/IndexRowwiseMinMax.h>
|
45
47
|
#include <faiss/IndexScalarQuantizer.h>
|
@@ -364,6 +366,13 @@ static void write_NNDescent(const NNDescent* nnd, IOWriter* f) {
|
|
364
366
|
WRITEVECTOR(nnd->final_graph);
|
365
367
|
}
|
366
368
|
|
369
|
+
static void write_RaBitQuantizer(const RaBitQuantizer* rabitq, IOWriter* f) {
|
370
|
+
// don't care about rabitq->centroid
|
371
|
+
WRITE1(rabitq->d);
|
372
|
+
WRITE1(rabitq->code_size);
|
373
|
+
WRITE1(rabitq->metric_type);
|
374
|
+
}
|
375
|
+
|
367
376
|
static void write_direct_map(const DirectMap* dm, IOWriter* f) {
|
368
377
|
char maintain_direct_map =
|
369
378
|
(char)dm->type; // for backwards compatibility with bool
|
@@ -850,6 +859,26 @@ void write_index(const Index* idx, IOWriter* f, int io_flags) {
|
|
850
859
|
WRITE1(h);
|
851
860
|
write_index_header(imm_2, f);
|
852
861
|
write_index(imm_2->index, f);
|
862
|
+
} else if (
|
863
|
+
const IndexRaBitQ* idxq = dynamic_cast<const IndexRaBitQ*>(idx)) {
|
864
|
+
uint32_t h = fourcc("Ixrq");
|
865
|
+
WRITE1(h);
|
866
|
+
write_index_header(idx, f);
|
867
|
+
write_RaBitQuantizer(&idxq->rabitq, f);
|
868
|
+
WRITEVECTOR(idxq->codes);
|
869
|
+
WRITEVECTOR(idxq->center);
|
870
|
+
WRITE1(idxq->qb);
|
871
|
+
} else if (
|
872
|
+
const IndexIVFRaBitQ* ivrq =
|
873
|
+
dynamic_cast<const IndexIVFRaBitQ*>(idx)) {
|
874
|
+
uint32_t h = fourcc("Iwrq");
|
875
|
+
WRITE1(h);
|
876
|
+
write_ivf_header(ivrq, f);
|
877
|
+
write_RaBitQuantizer(&ivrq->rabitq, f);
|
878
|
+
WRITE1(ivrq->code_size);
|
879
|
+
WRITE1(ivrq->by_residual);
|
880
|
+
WRITE1(ivrq->qb);
|
881
|
+
write_InvertedLists(ivrq->invlists, f);
|
853
882
|
} else {
|
854
883
|
FAISS_THROW_MSG("don't know how to serialize this type of index");
|
855
884
|
}
|