[parallel] Fix hpx::nth_element to correctly support C++20 projections and sentinels#7191
Conversation
…sentinels This PR fixes a regression where hpx::nth_element ignored user-provided projections in its sequential and parallel paths. It also adds full support for sentinels and aligns the algorithm with C++20 Ranges standards.
Up to standards ✅🟢 Issues
|
|
Can one of the admins verify this patch? |
| hpx::execution::seq, first, end, HPX_FORWARD(Compare, comp), | ||
| HPX_FORWARD(Proj, proj)); | ||
| hpx::execution::seq, first, end, | ||
| wrapped_comp_type(comp, proj), hpx::identity_v); |
There was a problem hiding this comment.
What is the rationale of this change?
There was a problem hiding this comment.
I found that the underlying detail::min_element implementation in minmax.hpp actually fails on macOS Clang when a projection changes the value type (it tries to store the result in a variable of the original element type). Using the wrapped comparison here is a necessary workaround to keep the macOS builds green.
There was a problem hiding this comment.
Wouldn't it be better to fix the actual problem instead of adding a workaround here?
There was a problem hiding this comment.
Would you be able to fix this problem (in an independent PR)?
There was a problem hiding this comment.
Thanks for the feedback! I've followed your suggestion and separated the core fix for minmax.hpp into an independent Pull Request. You can find it here: #7208.
On this current branch, I have:
Reverted the changes to minmax.hpp to match master.
Restored the wrapped_comp_type workaround in nth_element.hpp specifically for the min_element call.
This keeps this PR functional and 'Green' in CI while the core fix is being reviewed. Once the independent minmax PR is merged, I will come back here to remove the temporary workaround. Let me know if that works for you!
6391a4f to
e58f6aa
Compare
|
@aneek22112007-tech Please pay attention to the CIs. The clang-format CI raised some issue. |
|
Thanks for the review! I’ve gone ahead and consolidated that comparison wrapper at the top of the function to clean things up. I also switched to std::make_heap as suggested. Fixed the formatting issues too, so CI should be all clear now. |
7e072fa to
5590bc1
Compare
14da59c to
c860663
Compare
This PR fixes a regression where
hpx::nth_elementignored user-provided projections in its sequential and parallel paths. It also adds full support for sentinels and aligns the algorithm with C++20 Ranges standards.Proposed Changes
hpx::nth_element_tto natively accept C++20 sentinels (Sent) and projections (Proj) across both sequential and parallel execution overloads.min_element,sort,make_heap) were being called with raw, un-projected comparators. I have standardized all of these internal calls to cleanly wrap the base comparator withhpx::parallel::util::compare_projected, guaranteeing that custom projections are reliably evaluated before any structural comparisons are made.hpx::parallel::detail::partitionlambda andpivot9selection logic. The parallel lambda now correctly evaluates the projected value directly in the traversal loop. This resolves the compiler errors that would trigger whenever users passed in non-trivial type-transforming projections.nth_element_projection.cppto the unit test suite, aggressively testing both struct-member projections (&S::val) and complex type-transforming projections (e.g. mapping internal strings to sizes) acrossseq,par, andpar_unseqexecution policies.Any background context you want to provide?
While working through the parallel algorithm surfaces, I noticed that
hpx::nth_elementhad an incomplete implementation of the C++20 Ranges specification. Specifically, while the CPO technically accepted custom projections, the projection targets were inadvertently dropped when the work was dispatched to internal loops.This meant that if a user tried to partition a dataset by using a projection that fundamentally altered the type—for example, projecting a list of strings out to their integer lengths—the parallel partitioner would attempt to compare a raw
std::stringdirectly against asize_t, failing entirely at compile time.This PR properly threads the projection directly into the innermost parallel computation lambdas, tightening the CPO layer and effectively hardening
hpx::nth_elementagainst modern C++20 usage patterns to match the rest of the HPX algorithms ecosystem!Checklist
Not all points below apply to all pull requests.