-
Notifications
You must be signed in to change notification settings - Fork 428
[CUB] GPU-to-GPU DeviceReduce with device resident problem size
#9740
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
Changes from all commits
736d434
3596659
ecd0399
2decb22
9a963e9
af8fedc
663ec1b
b3b6097
af33be0
5c2ef8d
0be8893
80e1354
ff448cf
057a85b
9abe794
6a36769
460ae19
eff714b
1a6e7a7
123c142
52aa029
f824032
4b19824
cd93de7
1d4de90
4808d52
40ee0fc
a2147b2
bf09035
f1a0bca
b88fec9
6e6ffd6
ff45c8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,93 @@ | ||||||
| // SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||||||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
|
|
||||||
| #include <cub/device/device_reduce.cuh> | ||||||
|
|
||||||
| #include <thrust/detail/raw_pointer_cast.h> | ||||||
| #include <thrust/device_vector.h> | ||||||
|
Comment on lines
+6
to
+7
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: Should we aim to use CCCL Runtime in new benchmarks?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should, but @pciolkosz is still exploring how to do that best I think. We can ask claude to refactor eventually. |
||||||
|
|
||||||
| #include <cuda/argument> | ||||||
| #include <cuda/execution.determinism.h> | ||||||
| #include <cuda/execution.require.h> | ||||||
| #include <cuda/std/functional> | ||||||
| #include <cuda/std/utility> | ||||||
|
|
||||||
| #include <nvbench_helper.cuh> | ||||||
|
|
||||||
| #include <nvbench/range.cuh> | ||||||
| #include <nvbench/types.cuh> | ||||||
|
|
||||||
| // %RANGE% TUNE_ITEMS_PER_THREAD ipt 3:24:1 | ||||||
| // %RANGE% TUNE_THREADS_PER_BLOCK tpb 128:1024:32 | ||||||
|
|
||||||
| #if !TUNE_BASE | ||||||
| struct policy_selector_t | ||||||
| { | ||||||
| [[nodiscard]] _CCCL_HOST_DEVICE constexpr auto operator()(cuda::compute_capability) const -> cub::ReducePolicy | ||||||
| { | ||||||
| const auto p = cub::ReducePassPolicy{ | ||||||
| TUNE_THREADS_PER_BLOCK, TUNE_ITEMS_PER_THREAD, 1, cub::BLOCK_REDUCE_RAKING, cub::LOAD_DEFAULT}; | ||||||
| return {p, p}; | ||||||
| } | ||||||
| }; | ||||||
| #endif // !TUNE_BASE | ||||||
|
|
||||||
| template <class T, class OffsetT> | ||||||
| void deterministic_sum(nvbench::state& state, nvbench::type_list<T, OffsetT>) | ||||||
| try | ||||||
| { | ||||||
| using init_value_t = T; | ||||||
|
|
||||||
| if (!cuda::std::in_range<OffsetT>(state.get_int64("Elements{io}"))) | ||||||
| { | ||||||
| state.skip("Skipping: Elements{io} is not representable by OffsetT."); | ||||||
| return; | ||||||
| } | ||||||
| const auto elements = static_cast<OffsetT>(state.get_int64("Elements{io}")); | ||||||
|
|
||||||
| thrust::device_vector<T> in = generate(elements); | ||||||
| thrust::device_vector<T> out(1, thrust::no_init); | ||||||
| thrust::device_vector<OffsetT> device_num_items{elements}; | ||||||
|
|
||||||
| auto d_in = thrust::raw_pointer_cast(in.data()); | ||||||
| auto d_out = thrust::raw_pointer_cast(out.data()); | ||||||
| auto d_num_items = thrust::raw_pointer_cast(device_num_items.data()); | ||||||
|
|
||||||
| // Enable throughput calculations and add "Size" column to results. | ||||||
| state.add_element_count(elements); | ||||||
| state.add_global_memory_reads<T>(elements, "Size"); | ||||||
| state.add_global_memory_writes<T>(1); | ||||||
|
|
||||||
| caching_allocator_t alloc; | ||||||
| state.exec(nvbench::exec_tag::gpu | nvbench::exec_tag::no_batch, [&](nvbench::launch& launch) { | ||||||
| auto env = cub_bench_env( | ||||||
| alloc, | ||||||
| launch, | ||||||
| cuda::execution::require(cuda::execution::determinism::gpu_to_gpu) | ||||||
| #if !TUNE_BASE | ||||||
| , | ||||||
| cuda::execution::tune(policy_selector_t{}) | ||||||
| #endif // !TUNE_BASE | ||||||
| ); | ||||||
| _CCCL_TRY_CUDA_API( | ||||||
| cub::DeviceReduce::Reduce, | ||||||
| "Reduce failed", | ||||||
| d_in, | ||||||
| d_out, | ||||||
| cuda::args::deferred{d_num_items}, | ||||||
| cuda::std::plus<>{}, | ||||||
| init_value_t{}, | ||||||
| env); | ||||||
| }); | ||||||
| } | ||||||
| catch (const std::bad_alloc&) | ||||||
| { | ||||||
| state.skip("Skipping: out of memory."); | ||||||
| } | ||||||
|
|
||||||
| using types = nvbench::type_list<float, double>; | ||||||
| NVBENCH_BENCH_TYPES(deterministic_sum, NVBENCH_TYPE_AXES(types, offset_types)) | ||||||
| .set_name("base") | ||||||
| .set_type_axes_names({"T{ct}", "OffsetT{ct}"}) | ||||||
| // 2^32 exceeds INT32_MAX to cover the code paths for problem sizes that exceed a single 32-bit chunk | ||||||
| .add_int64_power_of_two_axis("Elements{io}", {16, 20, 24, 28, 32}); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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.
I think the license is wrong here
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.
It's correct