[libcudacxx] Add parallel cuda::std::minmax_element#9805
Open
edenfunf wants to merge 1 commit into
Open
Conversation
Adds the ExecutionPolicy overload of cuda::std::minmax_element with a CUDA backend, completing the min/max/minmax_element parallel algorithm family (the serial overload already existed). What: - New __pstl_algorithm::__minmax_element dispatch tag. - Serial routing header __pstl/minmax_element.h (mirrors __pstl/min_element.h), returning pair<Iter, Iter> and short-circuiting the empty range. - CUDA backend __pstl/cuda/minmax_element.h. Tie-breaking (why/how): std::minmax_element returns the *first* minimum and the *last* maximum. cub::DeviceReduce::ArgMin/ArgMax both keep the smaller offset on ties, i.e. the first extremum. ArgMin over the forward range yields the first minimum directly; the last maximum is obtained by running ArgMax over the reversed range (the first maximum in reverse order is the last maximum in forward order) and mapping the index back via count - 1 - rev. The two reductions run sequentially on one stream and share a single allocation (one scratch buffer sized to the larger requirement plus both result slots) with a single synchronization. A single-pass fused ArgMinMax would need a custom reduction operator (CUB has no ArgMinMax primitive); the two-reduction form follows the existing multi-launch backends (sort.h, inclusive_scan.h). Tests (pstl_minmax_element.cu): the parallel result is compared positionally against the serial cuda::std::minmax_element reference on identical data, which stays correct under ties (e.g. bfloat16, where adjacent large values round together) across all_types, all four policy configurations, plus empty and single-element ranges. Verified: 512 assertions / 8 test cases pass on RTX 5070 (sm_120, CUDA 13.3); clang-format clean.
Contributor
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (6)
📝 WalkthroughSummary by CodeRabbit
WalkthroughChangesAdds a PSTL execution-policy overload and CUDA backend for Parallel minmax_element
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds the
ExecutionPolicyoverload ofcuda::std::minmax_elementtogether with a CUDA backend, completing themin_element/max_element/minmax_elementparallel algorithm family (the serial overload already existed).Tie-breaking (the subtle part).
std::minmax_elementreturns the first minimum and the last maximum.cub::DeviceReduce::ArgMin/ArgMaxboth keep the smaller offset on ties (i.e. the first extremum). SoArgMinover the forward range yields the first minimum directly, while the last maximum is obtained by runningArgMaxover the reversed range — the first maximum in reverse order is the last maximum in forward order — and mapping the index back viacount - 1 - rev.Allocation/launch. The two reductions run sequentially on one stream and share a single allocation (one scratch buffer sized to the larger requirement plus both result slots) with a single synchronization. A single-pass fused
ArgMinMaxwould require a custom reduction operator since CUB has noArgMinMaxprimitive; the two-reduction form follows the existing multi-launch backends (sort.h,inclusive_scan.h).Tests.
pstl_minmax_element.cucompares the parallel result positionally against the serialcuda::std::minmax_elementreference computed on identical data. This stays correct under ties — e.g.__nv_bfloat16, where adjacent large values round to the same representation, so the last maximum is not at a fixed position — acrossall_types, all four policy configurations (default stream / provided stream / provided memory_resource / both), plus empty and single-element ranges.Verified locally: 512 assertions / 8 test cases pass on RTX 5070 (sm_120, CUDA 13.3);
clang-formatclean.Related: #5160, #5592.
Checklist