Add algorithm and benchmark for filtered range search - #1228
Add algorithm and benchmark for filtered range search#1228Magdalen Dobson Manohar (magdalendobson) wants to merge 68 commits into
Conversation
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
While working on #1228, I noticed that there were some issues with our current implementation of range search and its testing. The main issue with testing is that there were no tests ensuring the `max_results` parameter was respected. I have added two tests that ensure this now. The main code had several issues with how `max_results` was handled: 1. The `max_results` parameter was allowed to be less than the initial L_search. This is a conceptual issue because the user expects `max_results` to stop the search from continuing for too long, and the compute used in the initial search will always be controlled by `initial_search_l`. 2. A `max_results` check was not enforced before deciding to continue to the second round search. This meant that if the max results was reached via the initial search, it might not be respected. 3. The second round search was not terminated when `max_results` was reached, meaning it would continue to perform unnecessary work. This PR fixes these issues by adding additional checks of `max_results` at the correct points in the code. --------- Co-authored-by: Magdalen Manohar <mmanohar@microsoft.com>
fff67b6 to
e30697f
Compare
While working on microsoft#1228, I noticed that there were some issues with our current implementation of range search and its testing. The main issue with testing is that there were no tests ensuring the `max_results` parameter was respected. I have added two tests that ensure this now. The main code had several issues with how `max_results` was handled: 1. The `max_results` parameter was allowed to be less than the initial L_search. This is a conceptual issue because the user expects `max_results` to stop the search from continuing for too long, and the compute used in the initial search will always be controlled by `initial_search_l`. 2. A `max_results` check was not enforced before deciding to continue to the second round search. This meant that if the max results was reached via the initial search, it might not be respected. 3. The second round search was not terminated when `max_results` was reached, meaning it would continue to perform unnecessary work. This PR fixes these issues by adding additional checks of `max_results` at the correct points in the code. --------- Co-authored-by: Magdalen Manohar <mmanohar@microsoft.com>
Mark Hildebrand (hildebrandmw)
left a comment
There was a problem hiding this comment.
Thanks Magdalen, appreciate the work on this iteration!
Mark Hildebrand (hildebrandmw)
left a comment
There was a problem hiding this comment.
Thanks Magdalen, just a few small comments. After this PR lands, need a serious garbage collection pass on algorithm implementations. The sharing of scratch space and general code organization has reached a point where we need to reevaluate the design. This reevaluation is not actionable for this PR.
| beam_width: Option<usize>, | ||
| starting_l: NonZeroUsize, | ||
| /// Beam width. | ||
| beam_width: NonZeroUsize, |
There was a problem hiding this comment.
One thing for the larger range search cleanup: it would be nice to have a central summary of what all these parameters are expected to do algorithmically.
| // using an always-true filter, because the filtered // | ||
| // initial search returns every predicate-satisfying // | ||
| // point it finds as opposed to only those in // | ||
| // `scratch.best`. // |
There was a problem hiding this comment.
Please avoid referring to specific variable names when describing behavior. If the variable name changes, this will go out of date.
| let description = "Test of `max_results` that sets `initial_l_search` \ | ||
| below `max_results` so that a second round of search is triggered. Note that \ | ||
| the result set size is expected to be below `max_results` due to filtering \ | ||
| out start points during `post_process`."; |
There was a problem hiding this comment.
Should we increase the internal max_results in case start points are filtered?
| /// a reviewer may need to either understand why this test is checked in or to validate | ||
| /// any changes that occur in the checked-in file. | ||
| pub(super) description: String, | ||
| pub(super) grid_size: usize, |
There was a problem hiding this comment.
Can we include grid_dim as well?
|
|
||
| InternalSearchStats { | ||
| cmps: cmps + range_stats.cmps, | ||
| hops: hops + range_stats.hops, |
There was a problem hiding this comment.
Is there some double counting? As far as I can tell, there is no reset of the variables in scratch, so they contain history from the first call to inline_filter_search_internal.
This PR adds an algorithm for filtered range search to the DiskANN repository. Details of the algorithm, along with the experiments supporting it, are at this Wiki page.
This PR:
diskann, along with integration tests.diskann-benchmark, along with an integration test.test_data.Some enhancements/fixes to range search along the way:
test_datafor yfcc.