Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory-mapping and Zero-copy deserializers #4199

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

alexanderguzhva
Copy link
Contributor

@alexanderguzhva alexanderguzhva commented Feb 19, 2025

This PR introduces a backport of a combination of zilliztech/knowhere#996 and zilliztech/knowhere#1032 that allow to have memory-mapped and zerocopy indces.

The root underlying idea is that we replace certain std::vector<> containers with a custom faiss::MaybeOwnedVector<> container, which may behave either as std::vector<>, or as a view of a certain pointer / descriptor. We don't replace all the instances of std::vector<>, but the largest ones.

This change affects IndexFlatCodes-based and IndexHNSW CPU indices.

(done) alter IVF lists as well.
(done) alter binary indices as well.

Memory-mapped index works like this:

std::unique_ptr<faiss::Index> index_mm(
            faiss::read_index(filenamename.c_str(), faiss::IO_FLAG_MMAP_IFC));

In theory, it should be ready to be used from Python. All the descriptor management should be working.

Zero-copy index works like this:

#include <faiss/impl/zerocopy_io.h>

faiss::ZeroCopyIOReader reader(buffer.data(), buffer.size());
std::unique_ptr<faiss::Index> index_zc(faiss::read_index(&reader));

All the pointer management for faiss::ZeroCopyIOReader should be handled manually.
I'm not sure how to plug this into Python yet, maybe, some ref-counting is required.

(done) some refactoring

Signed-off-by: Alexandr Guzhva <[email protected]>
Signed-off-by: Alexandr Guzhva <[email protected]>
Signed-off-by: Alexandr Guzhva <[email protected]>
Signed-off-by: Alexandr Guzhva <[email protected]>
Signed-off-by: Alexandr Guzhva <[email protected]>
@alexanderguzhva
Copy link
Contributor Author

alexanderguzhva commented Feb 20, 2025

@mdouze Would please be able to suggest a solution for the following problem. Because I changed the container type for IndexFlatCodes::codes field, it triggered some errors in python unit tests, which are related to these .codes (bcz the field type got changed). What would be the most meaningful solution for dealing with it? Basically, I'm not sure how to minimize the amount of backward-compatibility problems for the code that uses Faiss across the world, as I am not an expert swig user

Signed-off-by: Alexandr Guzhva <[email protected]>
Copy link
Contributor

@mdouze mdouze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this. See a few inline reviews.
As long as the interface of MaybeOwnedVector is sufficiently close of std::vector, it should work seamlessly in Python (duck typing). I'll see if some adaptations to the swig interface are required.
It is not clear to me why the MappedFileIOReader is needed rather than the regular FileIOReader. Is it to maintain the ownership of the reader within the MaybeOwnedVector and close the file when deallocated?

impl/pq4_fast_scan.cpp
impl/pq4_fast_scan_search_1.cpp
impl/pq4_fast_scan_search_qbs.cpp
impl/residual_quantizer_encode_steps.cpp
impl/io.cpp
impl/lattice_Zn.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do these two file disappear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicates

READVECTOR(target);
}

template <typename VectorT>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible to factorize with previous function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a good suggestion, let me see...

}

template <typename VectorT>
void read_vector(VectorT& target, IOReader* f) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to enable this via an IO flag ? The IVF memory mapped files work on regular FileIOReader

https://github.com/facebookresearch/faiss/blob/main/faiss/invlists/OnDiskInvertedLists.cpp#L771

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

> OnDiskInvertedLists is unsupported on Windows.

my code allows mmap functionality on Windows as well. Let me take a look

@facebook-github-bot
Copy link
Contributor

@mdouze has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@mdouze
Copy link
Contributor

mdouze commented Feb 21, 2025

This patch should fix the python test:
https://gist.github.com/mdouze/83eff60f99ae1a3cba524c6b8320dd8f
could you integrate it?

Signed-off-by: Alexandr Guzhva <[email protected]>
@alexanderguzhva
Copy link
Contributor Author

alexanderguzhva commented Feb 21, 2025

It is not clear to me why the MappedFileIOReader is needed rather than the regular FileIOReader.

in order to have a correct support for Windows

@facebook-github-bot
Copy link
Contributor

@mdouze has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@alexanderguzhva
Copy link
Contributor Author

@mdouze I'm going to add IVFs and maybe Binary indices today as well, so please don't merge it yet :)

@alexanderguzhva alexanderguzhva changed the title [WIP] Memory-mapping and Zero-copy deserializers Memory-mapping and Zero-copy deserializers Feb 24, 2025
@alexanderguzhva
Copy link
Contributor Author

@mdouze please let me know which other unit tests are useful to have
I've added the code for ArrayInvertedLists and binary vectors as well.

@alexanderguzhva
Copy link
Contributor Author

the PR is ready to be reviewed

@facebook-github-bot
Copy link
Contributor

@mdouze has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants