-
Notifications
You must be signed in to change notification settings - Fork 80
enhance(pyramid): support dynamically adjusting size of subindex search parameters #1508
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
base: main
Are you sure you want to change the base?
Conversation
Summary of ChangesHello @inabao, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Pyramid indexing algorithm by introducing dynamic adjustment capabilities for search parameters, particularly Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Code Review
This pull request enhances the pyramid index by dynamically adjusting search parameters for sub-indexes, which is a valuable improvement for performance tuning. The core logic involves a new function get_suitable_ef_search to adapt the ef value based on the sub-index size. The changes are generally well-implemented, but I've identified a critical compilation error in resource_object_pool.h that needs to be addressed. Additionally, I've suggested refactoring some magic numbers into named constants for better code clarity and improving the documentation in an example file.
src/utils/resource_object_pool.h
Outdated
| auto ptr = std::make_shared<T>(args...); | ||
| auto value = ptr->MemoryUsage(); | ||
| memory_usage_.fetch_add(value, std::memory_order_relaxed); | ||
| pool->fetch_add(value, std::memory_order_relaxed); |
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.
There seems to be a typo here. The ResourceObjectPool class does not have a fetch_add method. You probably meant to access the memory_usage_ member of the pool object. This will cause a compilation error.
| pool->fetch_add(value, std::memory_order_relaxed); | |
| pool->memory_usage_.fetch_add(value, std::memory_order_relaxed); |
examples/cpp/107_index_pyramid.cpp
Outdated
| // - "base_quantization_type": the base quantization codes | ||
| // - "precise_quantization_type": the precise quantization codes | ||
| // - "index_min_size": The minimum size required to build the index | ||
| // - "support_duplicate": support for duplicate data in the index |
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.
The comments for the new pyramid parameters are a bit inconsistent and could be more descriptive. For example, "the base quantization codes" could be clarified as "The quantization type for base vectors." Also, please ensure consistent capitalization at the beginning of each comment line for better readability.
| // - "base_quantization_type": the base quantization codes | |
| // - "precise_quantization_type": the precise quantization codes | |
| // - "index_min_size": The minimum size required to build the index | |
| // - "support_duplicate": support for duplicate data in the index | |
| // - "base_quantization_type": The quantization type for base vectors. | |
| // - "precise_quantization_type": The quantization type for precise vectors, used for reordering. | |
| // - "index_min_size": The minimum number of vectors required to build a sub-index. | |
| // - "support_duplicate": Support for duplicate data in the index. |
| get_suitable_ef_search(int64_t topk, int64_t data_num) { | ||
| if (data_num < 1'000) { | ||
| return std::max(static_cast<uint64_t>(1.5F * topk), 50UL); | ||
| } | ||
| if (data_num < 100'000) { | ||
| return std::max(static_cast<uint64_t>(2.0F * topk), 100UL); | ||
| } | ||
| if (data_num < 1'000'000) { | ||
| return std::max(static_cast<uint64_t>(3.0F * topk), 200UL); | ||
| } | ||
| return std::max(static_cast<uint64_t>(4.0F * topk), 400UL); | ||
| } |
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.
The function get_suitable_ef_search uses several magic numbers for data size thresholds, multipliers, and minimum ef values. To improve readability and maintainability, it's better to define these as named constants.
get_suitable_ef_search(int64_t topk, int64_t data_num) {
constexpr int64_t kDataNumThreshold1 = 1'000;
constexpr int64_t kDataNumThreshold2 = 100'000;
constexpr int64_t kDataNumThreshold3 = 1'000'000;
constexpr float kMultiplier1 = 1.5F;
constexpr float kMultiplier2 = 2.0F;
constexpr float kMultiplier3 = 3.0F;
constexpr float kMultiplier4 = 4.0F;
constexpr uint64_t kMinEf1 = 50UL;
constexpr uint64_t kMinEf2 = 100UL;
constexpr uint64_t kMinEf3 = 200UL;
constexpr uint64_t kMinEf4 = 400UL;
if (data_num < kDataNumThreshold1) {
return std::max(static_cast<uint64_t>(kMultiplier1 * topk), kMinEf1);
}
if (data_num < kDataNumThreshold2) {
return std::max(static_cast<uint64_t>(kMultiplier2 * topk), kMinEf2);
}
if (data_num < kDataNumThreshold3) {
return std::max(static_cast<uint64_t>(kMultiplier3 * topk), kMinEf3);
}
return std::max(static_cast<uint64_t>(kMultiplier4 * topk), kMinEf4);
}
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (73.68%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. @@ Coverage Diff @@
## main #1508 +/- ##
==========================================
+ Coverage 91.13% 91.49% +0.36%
==========================================
Files 327 327
Lines 19146 19163 +17
==========================================
+ Hits 17449 17534 +85
+ Misses 1697 1629 -68
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
| get_suitable_ef_search(int64_t topk, int64_t data_num) { | ||
| auto topk_float = static_cast<float>(topk); | ||
| if (data_num < 1'000) { | ||
| return std::max(static_cast<uint64_t>(1.5F * topk_float), 50UL); |
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.
mark the magic number and add "LL" at end
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.
cannot do it
| auto range_result = | ||
| index->RangeSearch(query, threshold, search_param, dataset->filter_function_); | ||
| REQUIRE(range_result.value()->GetDim() >= topk - 1); | ||
| if (range_result.value()->GetDim() < topk - 1) { |
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.
why change REQUIRE to WARN
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.
Prevent this process from blocking the CI pipeline
74ac4e5 to
361a7e4
Compare
wxyucs
left a comment
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.
lgtm
LHT129
left a comment
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.
LGTM
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
Signed-off-by: jinjiabao.jjb <[email protected]>
361a7e4 to
5804ea2
Compare
| // add one point | ||
| if (node->status_ == IndexNode::Status::NO_INDEX) { | ||
| node->Init(); | ||
| Vector<InnerIdType>(allocator_).swap(node->ids_); |
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.
use swap bacause need shrink memory ?
| std::min(modified_param.ef, | ||
| get_suitable_ef_search(search_param.topk, node->graph_->TotalCount())); | ||
| } | ||
| modified_param.topk = static_cast<int64_t>(modified_param.ef); |
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.
too much type convert ...
| InnerSearchParam modified_param = search_param; | ||
| modified_param.ep = node->entry_point_; | ||
| if (node->level_ != 0 && search_param.search_mode == KNN_SEARCH) { | ||
| modified_param.ef = |
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.
We can force disable the auto opitmize ef search future ?
No description provided.