Iterative CAGRA-Q - #1810
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
… search - Configurable growth-phase in-build search params (itopk_size, search_width, max_iterations) and internal/smem dtype; itopk auto-forced on the final full-size iteration. - Decouple compression params used during iterative construction from the target index compression. - Add shuffle_dataset option; fix out-of-bounds access from the in-place raft gather by switching to an out-of-place gather.
…around) The shuffle_dataset path used an out-of-place gather into a temporary buffer to work around an illegal memory access in raft's in-place gather overload when n_rows * row_len exceeded 2^31 (32-bit index overflow). That bug is now fixed upstream in raft (NVIDIA/raft#3059, closes #3055), which the cuvs raft pin now includes. Revert to the in-place gather to drop the extra full-size temporary allocation and copy.
8fc10ac to
4f4068a
Compare
|
Hi @irina-resh-nvda, thanks for the contribution! I've added some commits to clean up some small things in this PR:
|
| // {std::optional<bool>{std::nullopt}}, | ||
| // {cuvs::neighbors::MergeStrategy::MERGE_STRATEGY_PHYSICAL, | ||
| // cuvs::neighbors::MergeStrategy::MERGE_STRATEGY_LOGICAL}); | ||
| // inputs.insert(inputs.end(), inputs2.begin(), inputs2.end()); |
There was a problem hiding this comment.
Why has this test been commented out?
There was a problem hiding this comment.
this is a leftover from my testing, i'll fix it
| {16}, // k | ||
| {32}, // degree | ||
| { // graph_build_algo::IVF_PQ, | ||
| // graph_build_algo::NN_DESCENT, |
There was a problem hiding this comment.
Same question: what is the reason for the changes here?
There was a problem hiding this comment.
sorry, testing artefact, will fix
| {true}, | ||
| {false}, | ||
| {0.995}, | ||
| {0.01}, |
There was a problem hiding this comment.
Why has the recall changed to 1%?
| // {std::optional<bool>{std::nullopt}}, | ||
| // {cuvs::neighbors::MergeStrategy::MERGE_STRATEGY_PHYSICAL, | ||
| // cuvs::neighbors::MergeStrategy::MERGE_STRATEGY_LOGICAL}); | ||
| // inputs.insert(inputs.end(), inputs2.begin(), inputs2.end()); |
There was a problem hiding this comment.
Same question: why was this commented out?
| // Create a dataset with 1000 points | ||
| constexpr int64_t n_dataset = 1000; | ||
| // Create a dataset with 10000 points | ||
| constexpr int64_t n_dataset = 10000; |
There was a problem hiding this comment.
What is the reason this test file has been changed to use n_dataset = 10,000?
| dev_ptr, | ||
| n_bytes, | ||
| cudaMemcpyDeviceToHost, | ||
| writeback_stream_)); |
There was a problem hiding this comment.
We should have a raft function that does this already.
// use memcpy instead of raft::copy to avoid strange behavior with HMM/ATS memory
If there is a problem here, we should try to root fix that in raft.
There was a problem hiding this comment.
i think this change is indeed some kind of diff artefact
| host_view_.data_handle() + src_row_offset * host_view_.extent(1), | ||
| n_bytes, | ||
| cudaMemcpyHostToDevice, | ||
| prefetch_stream_)); |
There was a problem hiding this comment.
Same as before: let's try to use the raft copy function.
| cudaPointerAttributes attr; | ||
| RAFT_CUDA_TRY(cudaPointerGetAttributes(&attr, ptr)); | ||
| return attr.hostPointer != nullptr; | ||
| } |
There was a problem hiding this comment.
We should already have utilities somewhere to do check if a pointer is host or device accessible, either within in raft or cuvs.
I can try to find those functions for you.
…build-time random seeds
| * @tparam IdxT The type of the index | ||
| */ | ||
| template <typename T, typename IdxT> | ||
| class batched_device_view_from_host { |
There was a problem hiding this comment.
Can't we use batch_load_iterator for the same purpose?
There was a problem hiding this comment.
It looks like a merge/diff view artifact. I think @mfoerste4 has added this new class earlier in his refactoring and I asked exactly the same question. There was seemingly a good reason for it, but I forgot it :) @mfoerste4 could you please remind?
There was a problem hiding this comment.
Bumping this, if we don't need this utility we can remove a bunch of code from this PR from this file utils.hpp and delete the test_batched_device_view_from_host.cu test file.
There was a problem hiding this comment.
Yes, this seems to be a merge issue. The class and test do not exist on main anymore.
|
the new main merge introduced some crashes, im investigating |
achirkin
left a comment
There was a problem hiding this comment.
Hi, a few suggestions here, mainly about the use of raft resources and helper utilities in cuvs.
| { | ||
| auto stream = raft::resource::get_cuda_stream(res); | ||
|
|
||
| auto dev_knn_graph = raft::make_device_matrix<IdxT, int64_t>(res, curr_query_size, curr_topk); |
There was a problem hiding this comment.
How big the curr_query_size here - is it bounded?
Consider using raft::resource::get_workspace_resource_ref(res) or raft::resource::get_large_workspace_resource_ref(res) depending on the answer to correctly track this as a temporary allocation.
There was a problem hiding this comment.
It's bounded by the dataset size, so i will use get_large_workspace_resource_ref as you suggested
| dev_output_graph = | ||
| raft::make_device_matrix<IdxT, int64_t>(res, curr_query_size, next_graph_degree); |
There was a problem hiding this comment.
The same question about being bounded and using the workspace resource here.
Also, do you allocate it multiple times (i.e. by calling it multiple times)?
- if no: maybe use the return semantics here for clarity (instead of passing the output variable by reference)?
- if yes: it would make sense to first clear the variable, and then assign a new one - to avoid two large arrays being allocated at the same time (increasing the memory footprint of the whole thing). Perhaps, doing this outside of the
search_and_optimizefunction and changing the function to return the new graph would make sense in this case too.
There was a problem hiding this comment.
same N-limited boundedness. Will change to return, and release the old graph before allocating the new one to reduce peak memory use
| * @tparam IdxT The type of the index | ||
| */ | ||
| template <typename T, typename IdxT> | ||
| class batched_device_view_from_host { |
There was a problem hiding this comment.
It looks like a merge/diff view artifact. I think @mfoerste4 has added this new class earlier in his refactoring and I asked exactly the same question. There was seemingly a good reason for it, but I forgot it :) @mfoerste4 could you please remind?
…emporaries in iterative build (~2.7x faster build)
|
It looks like a lot of files were edited to change the copyright header? I think we should revert those. This commit 6ad9234 reverted minor diff in a test file. We should look through the merge conflicts due to Datasets API and resolve them. |
This reverts commit d9c6bfd.
Iterative cagra graph construction using CAGRA-Q search.
This PR improves the iterative CAGRA build method by enabling PQ compression: the dataset is compressed before the iterative search starts, and CAGRA-Q is used to iteratively update the KNN graph.