Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
ae9bbc7
[cub] Add runtime-sized shared-memory histogram tier
brycelelbach Jul 30, 2026
6ae878e
[cub] Complete SMEM-privatized histogram tuning
brycelelbach Jul 30, 2026
dbe0bdc
[cub] Address histogram SMEM review feedback
brycelelbach Jul 30, 2026
0537743
[cub] Avoid signed overflow in RANGE interpolation
brycelelbach Jul 30, 2026
f64b4d5
[cub] Restore static histogram privatization
brycelelbach Jul 30, 2026
21a5c00
[cub] Keep histogram policy paths synchronized
brycelelbach Jul 30, 2026
e7da7b4
CUB: split RANGE histogram bin selection transforms
brycelelbach Jul 30, 2026
586f684
[cub] Address histogram privatization review feedback
brycelelbach Jul 31, 2026
c81eee3
[cub] Normalize histogram tuning names
brycelelbach Jul 31, 2026
798e0f8
[cub] Raise static histogram SMEM tier to 512 bins
brycelelbach Jul 31, 2026
a474901
[cub] Address histogram CodeRabbit review
brycelelbach Jul 31, 2026
c2e3931
[cub] Align histogram policy and simplify accumulation
brycelelbach Jul 31, 2026
915d124
[cub] Address histogram review feedback
brycelelbach Jul 31, 2026
322db8b
[cub] Simplify privatized histogram storage selection
brycelelbach Aug 1, 2026
5adb7bc
[cub] Clarify histogram dispatch comment
brycelelbach Aug 1, 2026
f552d68
[cub] Align histogram work stealing policy name
brycelelbach Aug 1, 2026
990bd4d
[cub] Remove histogram memory preference
brycelelbach Aug 1, 2026
2b84b74
[cub] Simplify histogram kernel configuration
brycelelbach Aug 1, 2026
37847da
[cub] Structure histogram tuning by kernel tier
brycelelbach Aug 1, 2026
7f558ef
[cub] Preserve SM90 histogram PDL selection
brycelelbach Aug 1, 2026
889b37b
[cub] Honor histogram memory preference in dynamic SMEM
brycelelbach Aug 1, 2026
a36b77d
[cub] Restore histogram memory preference tuning
brycelelbach Aug 2, 2026
dfb169f
[cub] Make histogram tier thresholds tunable
brycelelbach Aug 2, 2026
f37c8da
[cub] Use typed histogram privatization modes
brycelelbach Aug 2, 2026
30c4511
[cub] Address histogram privatization review feedback
brycelelbach Aug 5, 2026
d00fc4d
[cub] Use privatization mode tags consistently
brycelelbach Aug 5, 2026
88f7ecc
[cub] Simplify histogram tuning policy selection
brycelelbach Aug 5, 2026
ab40452
[cub] Collapse histogram tuning into one policy
brycelelbach Aug 5, 2026
47c719c
[cub] Remove the default legacy histogram policy chain
brycelelbach Aug 5, 2026
3cb975e
Revert "[cub] Remove the default legacy histogram policy chain"
brycelelbach Aug 5, 2026
b152967
Revert "[cub] Collapse histogram tuning into one policy"
brycelelbach Aug 5, 2026
8707bff
[cub] Simplify histogram runtime tuning policy
brycelelbach Aug 5, 2026
0050588
[cub] Follow established histogram tuning conventions
brycelelbach Aug 7, 2026
4aa7bad
[cub] Address histogram policy review
brycelelbach Aug 8, 2026
896b53b
[cub] Align histogram changes with current trunk
brycelelbach Aug 11, 2026
da06dec
[cub] Restore tuned static histogram limits
brycelelbach Aug 11, 2026
a20fb20
[cub] Address histogram review feedback
brycelelbach Aug 15, 2026
b4699d6
[cub] Preserve current multi-channel histogram tuning
brycelelbach Aug 15, 2026
260abea
[cub] Preserve legacy histogram policy capacity
brycelelbach Aug 15, 2026
af286f0
[cub] Clarify histogram autotuning policy
brycelelbach Aug 15, 2026
0e65260
Use dynamic SMEM for multi-channel EVEN histograms
brycelelbach Aug 17, 2026
39bd606
Address histogram review naming and policy feedback
brycelelbach Aug 19, 2026
03e1895
[cub] Enable cached RANGE search for tuned GMEM cases
brycelelbach Aug 20, 2026
47e8690
[cub] Respect device dynamic SMEM capacity
brycelelbach Aug 30, 2026
e59377e
[cub] Add an SM120 histogram SMEM budget
brycelelbach Aug 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions c/parallel/src/histogram.cu
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct histogram_kernel_source
}

template <typename PolicyT,
int PRIVATIZED_SMEM_BINS,
typename PrivatizationMode,
typename FirstLevelArrayT,
typename SecondLevelArrayT,
bool IsEven,
Expand Down Expand Up @@ -96,7 +96,7 @@ std::string get_init_kernel_name(int num_active_channels, std::string_view count
}

std::string get_sweep_kernel_name(
int privatized_smem_bins,
std::string_view privatization_mode_t,
int num_channels,
int num_active_channels,
cccl_iterator_t d_samples,
Expand Down Expand Up @@ -147,7 +147,7 @@ std::string get_sweep_kernel_name(
"cub::detail::histogram::DeviceHistogramSweepDeviceInitKernel<{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, "
"{10}, {11}>",
chained_policy_t,
privatized_smem_bins,
privatization_mode_t,
num_channels,
num_active_channels,
samples_iterator_t,
Expand Down Expand Up @@ -324,17 +324,26 @@ static_assert(device_histogram_policy()(detail::current_tuning_cc()) == {4}, "Ho
fflush(stdout);
#endif

// TODO: This is tricky because we need to know the input to set this to a
// value greater than 0 (see dispatch_histogram.cuh), but we don't have this
// information here.
const int privatized_smem_bins =
num_output_levels_val - 1 > cub::detail::histogram::max_privatized_smem_bins ? 0 : 256;

const bool is_byte_sample = d_samples.value_type.size == 1;
const int num_privatized_bins =
is_byte_sample ? cub::detail::histogram::byte_sample_privatized_levels - 1 : num_output_levels_val - 1;
const int counter_size_bytes = static_cast<int>(d_output_histograms.value_type.size);
const auto privatization =
is_evenly_segmented
? cub::detail::histogram::select_privatization_mode_for_counter_size<true, 1>(
active_policy, num_privatized_bins, counter_size_bytes)
: cub::detail::histogram::select_privatization_mode_for_counter_size<false, 1>(
active_policy, num_privatized_bins, counter_size_bytes);
const std::string_view privatization_mode_t =
Comment thread
robobryce marked this conversation as resolved.
privatization == cub::detail::histogram::privatization_mode::static_smem
? "cub::detail::histogram::HistogramPrivatizedStaticSmem"
: privatization == cub::detail::histogram::privatization_mode::dynamic_smem
? "cub::detail::histogram::HistogramPrivatizedDynamicSmem"
: "cub::detail::histogram::HistogramPrivatizedGmem";

std::string init_kernel_name = histogram::get_init_kernel_name(num_active_channels, counter_cpp, offset_cpp);
std::string sweep_kernel_name = histogram::get_sweep_kernel_name(
privatized_smem_bins,
privatization_mode_t,
num_channels,
num_active_channels,
d_samples,
Expand Down Expand Up @@ -574,6 +583,7 @@ CUresult cccl_device_histogram_even_impl(
indirect_arg_t, // LevelT
OffsetT, // OffsetT
cub::detail::histogram::policy_selector, // PolicySelector
void, // PrivatizedCounterT: C Parallel preserves the counter width after type erasure
indirect_arg_t, // SampleT
histogram::histogram_kernel_source, // KernelSource
cub::detail::CudaDriverLauncherFactory // KernelLauncherFactory
Expand Down
3 changes: 1 addition & 2 deletions cub/benchmarks/bench/histogram/even.cu
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// %RANGE% TUNE_THREADS tpb 128:1024:32
// %RANGE% TUNE_RLE_COMPRESS rle 0:1:1
// %RANGE% TUNE_WORK_STEALING ws 0:1:1
// %RANGE% TUNE_MEM_PREFERENCE mem 0:2:1
// %RANGE% TUNE_LOAD ld 0:2:1
// %RANGE% TUNE_LOAD_ALGORITHM_ID laid 0:2:1
// %RANGE% TUNE_VEC_SIZE_POW vec 0:2:1
Expand Down Expand Up @@ -52,7 +51,7 @@ static void even(nvbench::state& state, nvbench::type_list<SampleT, CounterT, Of
launch
#if !TUNE_BASE
,
cuda::execution::tune(bench_policy_selector<key_t, 1, 1>{})
cuda::execution::tune(histogram_tuning_policy_selector<SampleT, CounterT, 1, 1, true>{})
#endif // !TUNE_BASE
);
_CCCL_TRY_CUDA_API(
Expand Down
45 changes: 25 additions & 20 deletions cub/benchmarks/bench/histogram/histogram_common.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@

# define TUNE_VEC_SIZE (1 << TUNE_VEC_SIZE_POW)

# if TUNE_MEM_PREFERENCE == 0
constexpr cub::BlockHistogramMemoryPreference MEM_PREFERENCE = cub::GMEM;
# elif TUNE_MEM_PREFERENCE == 1
constexpr cub::BlockHistogramMemoryPreference MEM_PREFERENCE = cub::SMEM;
# else // TUNE_MEM_PREFERENCE == 2
constexpr cub::BlockHistogramMemoryPreference MEM_PREFERENCE = cub::BLEND;
# endif // TUNE_MEM_PREFERENCE

# if TUNE_LOAD_ALGORITHM_ID == 0
# define TUNE_LOAD_ALGORITHM cub::BLOCK_LOAD_DIRECT
# elif TUNE_LOAD_ALGORITHM_ID == 1
Expand All @@ -35,25 +27,38 @@ constexpr cub::BlockHistogramMemoryPreference MEM_PREFERENCE = cub::BLEND;
# define TUNE_LOAD_ALGORITHM cub::BLOCK_LOAD_STRIPED
# endif // TUNE_LOAD_ALGORITHM_ID

template <typename SampleT, int NUM_CHANNELS, int NUM_ACTIVE_CHANNELS>
struct bench_policy_selector
// Only generated tuning variants instantiate this selector. The `.base` target used for
// production-policy comparisons defines TUNE_BASE=1 and calls DeviceHistogram without a
// tuning environment, so it exercises the shipping selector unchanged.
//
// A generated tuning point supplies one candidate kernel configuration. Apply that same
// candidate to every privatization mode so the tuner measures the candidate independently
// of the runtime bin count selected by the production storage thresholds.
template <typename SampleT, typename CounterT, int NUM_CHANNELS, int NUM_ACTIVE_CHANNELS, bool IS_EVEN>
struct histogram_tuning_policy_selector
{
_CCCL_HOST_DEVICE_API constexpr auto operator()(::cuda::compute_capability) const -> cub::HistogramPolicy
_CCCL_HOST_DEVICE_API constexpr auto operator()(::cuda::compute_capability cc) const -> cub::HistogramPolicy
{
constexpr cub::BlockLoadAlgorithm load_algorithm =
(TUNE_LOAD_ALGORITHM == cub::BLOCK_LOAD_STRIPED)
? (NUM_CHANNELS == 1 ? cub::BLOCK_LOAD_STRIPED : cub::BLOCK_LOAD_DIRECT)
: TUNE_LOAD_ALGORITHM;

return {TUNE_THREADS,
TUNE_ITEMS,
TUNE_VEC_SIZE,
load_algorithm,
TUNE_LOAD_MODIFIER,
TUNE_RLE_COMPRESS,
MEM_PREFERENCE,
TUNE_WORK_STEALING,
2048}; // TODO(bgruber): make tunable
constexpr auto sweep = cub::HistogramPrivatizationPolicy{
TUNE_THREADS,
TUNE_ITEMS,
TUNE_VEC_SIZE,
load_algorithm,
TUNE_LOAD_MODIFIER,
TUNE_RLE_COMPRESS,
TUNE_WORK_STEALING};
auto policy =
cub::detail::histogram::policy_selector_from_types<SampleT, CounterT, NUM_CHANNELS, NUM_ACTIVE_CHANNELS, IS_EVEN>{}(
cc);
policy.gmem = sweep;
policy.static_smem = sweep;
policy.dynamic_smem = sweep;
Comment thread
brycelelbach marked this conversation as resolved.
return policy;
}
};
#endif // !TUNE_BASE
Expand Down
4 changes: 2 additions & 2 deletions cub/benchmarks/bench/histogram/multi/even.cu
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// %RANGE% TUNE_THREADS tpb 128:1024:32
// %RANGE% TUNE_RLE_COMPRESS rle 0:1:1
// %RANGE% TUNE_WORK_STEALING ws 0:1:1
// %RANGE% TUNE_MEM_PREFERENCE mem 0:2:1
// %RANGE% TUNE_LOAD ld 0:2:1
// %RANGE% TUNE_LOAD_ALGORITHM_ID laid 0:2:1
// %RANGE% TUNE_VEC_SIZE_POW vec 0:2:1
Expand Down Expand Up @@ -65,7 +64,8 @@ static void even(nvbench::state& state, nvbench::type_list<SampleT, CounterT, Of
launch
#if !TUNE_BASE
,
cuda::execution::tune(bench_policy_selector<key_t, num_channels, num_active_channels>{})
cuda::execution::tune(
histogram_tuning_policy_selector<SampleT, CounterT, num_channels, num_active_channels, true>{})
#endif // !TUNE_BASE
);
_CCCL_TRY_CUDA_API(
Expand Down
4 changes: 2 additions & 2 deletions cub/benchmarks/bench/histogram/multi/range.cu
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// %RANGE% TUNE_THREADS tpb 128:1024:32
// %RANGE% TUNE_RLE_COMPRESS rle 0:1:1
// %RANGE% TUNE_WORK_STEALING ws 0:1:1
// %RANGE% TUNE_MEM_PREFERENCE mem 0:2:1
// %RANGE% TUNE_LOAD ld 0:2:1
// %RANGE% TUNE_LOAD_ALGORITHM_ID laid 0:2:1
// %RANGE% TUNE_VEC_SIZE_POW vec 0:2:1
Expand Down Expand Up @@ -65,7 +64,8 @@ static void range(nvbench::state& state, nvbench::type_list<SampleT, CounterT, O
launch
#if !TUNE_BASE
,
cuda::execution::tune(bench_policy_selector<key_t, num_channels, num_active_channels>{})
cuda::execution::tune(
histogram_tuning_policy_selector<SampleT, CounterT, num_channels, num_active_channels, false>{})
#endif // !TUNE_BASE
);
_CCCL_TRY_CUDA_API(
Expand Down
3 changes: 1 addition & 2 deletions cub/benchmarks/bench/histogram/range.cu
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// %RANGE% TUNE_THREADS tpb 128:1024:32
// %RANGE% TUNE_RLE_COMPRESS rle 0:1:1
// %RANGE% TUNE_WORK_STEALING ws 0:1:1
// %RANGE% TUNE_MEM_PREFERENCE mem 0:2:1
// %RANGE% TUNE_LOAD ld 0:2:1
// %RANGE% TUNE_LOAD_ALGORITHM_ID laid 0:2:1
// %RANGE% TUNE_VEC_SIZE_POW vec 0:2:1
Expand Down Expand Up @@ -51,7 +50,7 @@ static void range(nvbench::state& state, nvbench::type_list<SampleT, CounterT, O
launch
#if !TUNE_BASE
,
cuda::execution::tune(bench_policy_selector<key_t, 1, 1>{})
cuda::execution::tune(histogram_tuning_policy_selector<SampleT, CounterT, 1, 1, false>{})
#endif // !TUNE_BASE
);
_CCCL_TRY_CUDA_API(
Expand Down
Loading
Loading