-
Notifications
You must be signed in to change notification settings - Fork 92
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
[Feat] Add support of logical merge in Cagra #713
base: branch-25.04
Are you sure you want to change the base?
Conversation
rhdong
commented
Feb 20, 2025
- [FEA] Add support of logical merge in Cagra #712
* @param[in] sample_filter an optional device filter function object that greenlights samples | ||
* for a given query. (none_sample_filter for no filtering) | ||
*/ | ||
void search(raft::resources const& res, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @cjnolet @achirkin , I had to add a new search for composite_index
, the root cause is the cuve::neighbors::index
is not designed to be an abstract virtual class, which makes many pathways impossible, like inheriting from index
, which can avoid declaring a standalone composible_index
and a new search API. I was trying to refactor it, but I found it was used widely in different algo codes than give up under a tight timeline; maybe we can make it in the long term.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's okay that we don't require a strict class hierarchy initially, so long as we have proper overloads so that from a user's perspective, they can call auto index = cuvs::neighbors::cagra::merge(...)
and get back a proper object from which they can later call cuvs::neighbors::cagra::search(..., index,..)
I may have missed some prior discussion, but the cagra-specific logical merge seems a little bit artificial for me. |
@achirkin you and I haven't discussed this yet but this feature is critical for certain database architectures like Lucene, which are variants of the log-structured-merge pattern but build indexes immediately after segments (flat files containing vectors) are created, rather than merging the segments together before building the indexes. This causes Lucene to have to first merge many tiny CAGRA indexes together, but eventually it'll end up merging very large indexes together. It is this latter case thart we care about doing a logical merge. It's more efficient to create a single cagra index with many (potentially hundreds) of tiny cagra indexes but when they reach a certain size, it's actually more efficient to logically merge them; meaning we essentially wrap them as if they were shards and broadcast the query to all the shards during search. I agree this is similar in theory to the multi-gpu sharding and perhaps there is some code to be reused there. The next step for the
I do agree with this- it doesn't have to be (and ideally wouldn't be) specifically for CAGRA, though that just happens to be the index we care about today because it unblocks Lucene. |
I totally agree and don't doubt the usefulness of logical merge. |
Hi @achirkin , sorry for the late response to your comments here. I studied the code of SNMG, which is a super useful feature. When I tried to reuse some code in it, I found the caller has to work with locker, nccl, which is unnecessary in the logical merge of CAGRA. I'd like to keep the simple implementation if you agree. Many thanks! cc: @cjnolet |