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 | 
             
                }
         |