From 57bb25fa30b6d1af17c9d26eafa61850dcd62c2a Mon Sep 17 00:00:00 2001 From: Yunsong Wang Date: Sun, 19 Jul 2026 06:57:00 +0000 Subject: [PATCH 1/4] Reduce compute_global_memory_aggs_null build time --- cpp/CMakeLists.txt | 6 + .../detail/aggregation/device_aggregators.cuh | 20 +- .../hash/compute_global_memory_aggs.hpp | 4 +- .../hash/compute_global_memory_aggs_null.cu | 31 ++- .../hash/compute_global_memory_aggs_null.hpp | 40 ++++ .../compute_global_memory_aggs_null_dense.cu | 74 ++++++ ...lobal_memory_aggs_null_dense_dictionary.cu | 21 ++ ...l_memory_aggs_null_dense_non_dictionary.cu | 21 ++ ...ompute_global_memory_aggs_null_kernels.cuh | 71 ++++++ ...ompute_global_memory_aggs_null_kernels.hpp | 52 ++++ .../compute_global_memory_aggs_null_sparse.cu | 66 ++++++ ...obal_memory_aggs_null_sparse_dictionary.cu | 22 ++ ..._memory_aggs_null_sparse_non_dictionary.cu | 22 ++ cpp/src/groupby/hash/single_pass_functors.cuh | 223 ++++++++++++++++-- 14 files changed, 644 insertions(+), 29 deletions(-) create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null.hpp create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_dense.cu create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_dictionary.cu create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_non_dictionary.cu create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.cuh create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.hpp create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse.cu create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_dictionary.cu create mode 100644 cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_non_dictionary.cu diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 0899c3cec002..9dc520061d5c 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -662,6 +662,12 @@ add_library( src/groupby/groupby.cu src/groupby/hash/compute_global_memory_aggs.cu src/groupby/hash/compute_global_memory_aggs_null.cu + src/groupby/hash/compute_global_memory_aggs_null_dense.cu + src/groupby/hash/compute_global_memory_aggs_null_dense_dictionary.cu + src/groupby/hash/compute_global_memory_aggs_null_dense_non_dictionary.cu + src/groupby/hash/compute_global_memory_aggs_null_sparse.cu + src/groupby/hash/compute_global_memory_aggs_null_sparse_dictionary.cu + src/groupby/hash/compute_global_memory_aggs_null_sparse_non_dictionary.cu src/groupby/hash/compute_groupby.cu src/groupby/hash/compute_mapping_indices.cu src/groupby/hash/compute_mapping_indices_null.cu diff --git a/cpp/include/cudf/detail/aggregation/device_aggregators.cuh b/cpp/include/cudf/detail/aggregation/device_aggregators.cuh index 3e919f76ccaf..a12ecdf50224 100644 --- a/cpp/include/cudf/detail/aggregation/device_aggregators.cuh +++ b/cpp/include/cudf/detail/aggregation/device_aggregators.cuh @@ -166,9 +166,11 @@ struct update_target_element { * SFINAE is used to prevent recursion for dictionary type. Dictionary keys cannot be a * dictionary. * + * @tparam k Aggregation to perform */ +template struct update_target_from_dictionary { - template + template __device__ void operator()(mutable_column_device_view target, size_type target_index, column_device_view source, @@ -177,7 +179,7 @@ struct update_target_from_dictionary { { update_target_element{}(target, target_index, source, source_index); } - template + template __device__ void operator()(mutable_column_device_view, size_type, column_device_view, @@ -207,14 +209,12 @@ struct update_target_element { column_device_view source, size_type source_index) const noexcept { - dispatch_type_and_aggregation( - source.child(cudf::dictionary_column_view::keys_column_index).type(), - k, - update_target_from_dictionary{}, - target, - target_index, - source.child(cudf::dictionary_column_view::keys_column_index), - static_cast(source.element(source_index))); + type_dispatcher(source.child(cudf::dictionary_column_view::keys_column_index).type(), + update_target_from_dictionary{}, + target, + target_index, + source.child(cudf::dictionary_column_view::keys_column_index), + static_cast(source.element(source_index))); } }; diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs.hpp b/cpp/src/groupby/hash/compute_global_memory_aggs.hpp index ef9d730d7118..1990d0cc2d99 100644 --- a/cpp/src/groupby/hash/compute_global_memory_aggs.hpp +++ b/cpp/src/groupby/hash/compute_global_memory_aggs.hpp @@ -5,11 +5,13 @@ #pragma once #include -#include +#include +#include #include #include #include +#include #include #include diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null.cu index d50c7d302710..209c0a0ce4f9 100644 --- a/cpp/src/groupby/hash/compute_global_memory_aggs_null.cu +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null.cu @@ -3,13 +3,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "compute_global_memory_aggs.cuh" +#include "compute_global_memory_aggs.hpp" +#include "compute_global_memory_aggs_null.hpp" +#include "helpers.cuh" +#include +#include #include +#include namespace cudf::groupby::detail::hash { -template std::pair, rmm::device_uvector> +template <> +std::pair, rmm::device_uvector> compute_global_memory_aggs(bitmask_type const* row_bitmask, table_view const& values, nullable_global_set_t const& key_set, @@ -17,6 +23,25 @@ compute_global_memory_aggs(bitmask_type const* row_bitmas device_span d_agg_kinds, std::span is_agg_intermediate, rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr); + rmm::device_async_resource_ref mr) +{ + return h_agg_kinds.size() > GROUPBY_DENSE_OUTPUT_THRESHOLD + ? compute_global_memory_aggs_null_dense(row_bitmask, + values, + key_set, + h_agg_kinds, + d_agg_kinds, + is_agg_intermediate, + stream, + mr) + : compute_global_memory_aggs_null_sparse(row_bitmask, + values, + key_set, + h_agg_kinds, + d_agg_kinds, + is_agg_intermediate, + stream, + mr); +} } // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null.hpp b/cpp/src/groupby/hash/compute_global_memory_aggs_null.hpp new file mode 100644 index 000000000000..11d93da5a034 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null.hpp @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "compute_global_memory_aggs.hpp" +#include "helpers.cuh" + +#include +#include +#include +#include + +namespace cudf::groupby::detail::hash { + +std::pair, rmm::device_uvector> +compute_global_memory_aggs_null_dense( + bitmask_type const* row_bitmask, + table_view const& values, + nullable_global_set_t const& key_set, + host_span h_agg_kinds, + device_span d_agg_kinds, + std::span is_agg_intermediate, + rmm::cuda_stream_view stream, + rmm::device_async_resource_ref mr); + +std::pair, rmm::device_uvector> +compute_global_memory_aggs_null_sparse( + bitmask_type const* row_bitmask, + table_view const& values, + nullable_global_set_t const& key_set, + host_span h_agg_kinds, + device_span d_agg_kinds, + std::span is_agg_intermediate, + rmm::cuda_stream_view stream, + rmm::device_async_resource_ref mr); + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense.cu new file mode 100644 index 000000000000..cf2f9a37b165 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense.cu @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs.cuh" +#include "compute_global_memory_aggs_null.hpp" +#include "compute_global_memory_aggs_null_kernels.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace cudf::groupby::detail::hash { + +std::pair, rmm::device_uvector> +compute_global_memory_aggs_null_dense(bitmask_type const* row_bitmask, + table_view const& values, + nullable_global_set_t const& key_set, + host_span h_agg_kinds, + device_span d_agg_kinds, + std::span is_agg_intermediate, + rmm::cuda_stream_view stream, + rmm::device_async_resource_ref mr) +{ + auto const num_rows = values.num_rows(); + auto [unique_keys, target_indices] = [&] { + auto matching_keys = + compute_matching_keys(row_bitmask, key_set.ref(cuco::op::insert_and_find), num_rows, stream); + auto unique_keys = extract_populated_keys(key_set, num_rows, stream, mr); + auto key_transform_map = compute_key_transform_map( + num_rows, unique_keys, stream, cudf::get_current_device_resource_ref()); + auto target_indices = compute_target_indices( + matching_keys, key_transform_map, stream, cudf::get_current_device_resource_ref()); + return std::pair{std::move(unique_keys), std::move(target_indices)}; + }(); + + auto const d_values = table_device_view::create(values, stream); + auto agg_results = create_results_table(static_cast(unique_keys.size()), + values, + h_agg_kinds, + is_agg_intermediate, + stream, + mr); + auto d_results = mutable_table_device_view::create(*agg_results, stream); + auto const num_items = num_rows * static_cast(h_agg_kinds.size()); + + auto const has_dictionary = std::any_of( + values.begin(), values.end(), [](column_view const& col) { return is_dictionary(col.type()); }); + auto const has_non_dictionary = + std::any_of(values.begin(), values.end(), [](column_view const& col) { + return not is_dictionary(col.type()); + }); + + if (has_non_dictionary) { + launch_null_dense_non_dictionary( + target_indices.data(), d_agg_kinds.data(), *d_values, *d_results, num_items, stream); + } + if (has_dictionary) { + launch_null_dense_dictionary( + target_indices.data(), d_agg_kinds.data(), *d_values, *d_results, num_items, stream); + } + + return {std::move(agg_results), std::move(unique_keys)}; +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_dictionary.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_dictionary.cu new file mode 100644 index 000000000000..bf151c48d8de --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_dictionary.cu @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs_null_kernels.cuh" + +namespace cudf::groupby::detail::hash { + +void launch_null_dense_dictionary(size_type const* target_indices, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + int64_t num_items, + rmm::cuda_stream_view stream) +{ + launch_null_dense_filtered( + target_indices, aggs, input_values, output_values, num_items, stream); +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_non_dictionary.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_non_dictionary.cu new file mode 100644 index 000000000000..7649cd2ef839 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_dense_non_dictionary.cu @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs_null_kernels.cuh" + +namespace cudf::groupby::detail::hash { + +void launch_null_dense_non_dictionary(size_type const* target_indices, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + int64_t num_items, + rmm::cuda_stream_view stream) +{ + launch_null_dense_filtered( + target_indices, aggs, input_values, output_values, num_items, stream); +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.cuh b/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.cuh new file mode 100644 index 000000000000..b036d46dc407 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.cuh @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "compute_global_memory_aggs_null_kernels.hpp" +#include "single_pass_functors.cuh" + +#include +#include + +#include + +namespace cudf::groupby::detail::hash { + +template +CUDF_KERNEL void filtered_single_pass_aggs_kernel(Index num_items, Function fn) +{ + auto const idx = static_cast(cudf::detail::grid_1d::global_thread_id()); + if (idx < num_items) { fn(idx); } +} + +template +void launch_filtered_single_pass_aggs(Index num_items, Function fn, rmm::cuda_stream_view stream) +{ + if (num_items == 0) { return; } + + // Match the launch geometry used by the original Thrust kernel. A smaller block size causes a + // significant runtime regression in the hash table operations. + constexpr auto block_size = 256; + cudf::detail::grid_1d config{num_items, block_size}; + filtered_single_pass_aggs_kernel<<>>(num_items, fn); + CUDF_CUDA_TRY(cudaGetLastError()); +} + +template +void launch_null_sparse_filtered(nullable_insert_and_find_ref set_ref, + bitmask_type const* row_bitmask, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + size_type num_rows, + rmm::cuda_stream_view stream) +{ + launch_filtered_single_pass_aggs( + num_rows, + compute_filtered_single_pass_aggs_sparse_output_fn{ + set_ref, row_bitmask, aggs, input_values, output_values}, + stream); +} + +template +void launch_null_dense_filtered(size_type const* target_indices, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + int64_t num_items, + rmm::cuda_stream_view stream) +{ + launch_filtered_single_pass_aggs(num_items, + compute_filtered_single_pass_aggs_dense_output_fn{ + target_indices, aggs, input_values, output_values}, + stream); +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.hpp b/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.hpp new file mode 100644 index 000000000000..8b4eb0dca9d2 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_kernels.hpp @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "helpers.cuh" + +#include +#include +#include + +#include + +#include + +namespace cudf::groupby::detail::hash { + +using nullable_insert_and_find_ref = nullable_hash_set_ref_t; + +void launch_null_sparse_non_dictionary(nullable_insert_and_find_ref set_ref, + bitmask_type const* row_bitmask, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + size_type num_rows, + rmm::cuda_stream_view stream); + +void launch_null_sparse_dictionary(nullable_insert_and_find_ref set_ref, + bitmask_type const* row_bitmask, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + size_type num_rows, + rmm::cuda_stream_view stream); + +void launch_null_dense_non_dictionary(size_type const* target_indices, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + int64_t num_items, + rmm::cuda_stream_view stream); + +void launch_null_dense_dictionary(size_type const* target_indices, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + int64_t num_items, + rmm::cuda_stream_view stream); + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse.cu new file mode 100644 index 000000000000..e80579a27b1e --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse.cu @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs_null.hpp" +#include "compute_global_memory_aggs_null_kernels.hpp" +#include "output_utils.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace cudf::groupby::detail::hash { + +std::pair, rmm::device_uvector> +compute_global_memory_aggs_null_sparse(bitmask_type const* row_bitmask, + table_view const& values, + nullable_global_set_t const& key_set, + host_span h_agg_kinds, + device_span d_agg_kinds, + std::span is_agg_intermediate, + rmm::cuda_stream_view stream, + rmm::device_async_resource_ref mr) +{ + auto const num_rows = values.num_rows(); + auto const d_values = table_device_view::create(values, stream); + auto agg_results = + create_results_table(num_rows, values, h_agg_kinds, is_agg_intermediate, stream, mr); + auto d_results = mutable_table_device_view::create(*agg_results, stream); + + auto const has_dictionary = std::any_of( + values.begin(), values.end(), [](column_view const& col) { return is_dictionary(col.type()); }); + auto const has_non_dictionary = + std::any_of(values.begin(), values.end(), [](column_view const& col) { + return not is_dictionary(col.type()); + }); + auto const set_ref = key_set.ref(cuco::op::insert_and_find); + + if (has_non_dictionary) { + launch_null_sparse_non_dictionary( + set_ref, row_bitmask, d_agg_kinds.data(), *d_values, *d_results, num_rows, stream); + } + if (has_dictionary) { + launch_null_sparse_dictionary( + set_ref, row_bitmask, d_agg_kinds.data(), *d_values, *d_results, num_rows, stream); + } + + auto unique_keys = extract_populated_keys(key_set, num_rows, stream, mr); + auto dense_results = cudf::detail::gather(agg_results->view(), + unique_keys, + out_of_bounds_policy::DONT_CHECK, + cudf::negative_index_policy::NOT_ALLOWED, + stream, + mr); + return {std::move(dense_results), std::move(unique_keys)}; +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_dictionary.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_dictionary.cu new file mode 100644 index 000000000000..d9289a099a1c --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_dictionary.cu @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs_null_kernels.cuh" + +namespace cudf::groupby::detail::hash { + +void launch_null_sparse_dictionary(nullable_insert_and_find_ref set_ref, + bitmask_type const* row_bitmask, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + size_type num_rows, + rmm::cuda_stream_view stream) +{ + launch_null_sparse_filtered( + set_ref, row_bitmask, aggs, input_values, output_values, num_rows, stream); +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_non_dictionary.cu b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_non_dictionary.cu new file mode 100644 index 000000000000..a06f056075d2 --- /dev/null +++ b/cpp/src/groupby/hash/compute_global_memory_aggs_null_sparse_non_dictionary.cu @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "compute_global_memory_aggs_null_kernels.cuh" + +namespace cudf::groupby::detail::hash { + +void launch_null_sparse_non_dictionary(nullable_insert_and_find_ref set_ref, + bitmask_type const* row_bitmask, + aggregation::Kind const* aggs, + table_device_view const& input_values, + mutable_table_device_view const& output_values, + size_type num_rows, + rmm::cuda_stream_view stream) +{ + launch_null_sparse_filtered( + set_ref, row_bitmask, aggs, input_values, output_values, num_rows, stream); +} + +} // namespace cudf::groupby::detail::hash diff --git a/cpp/src/groupby/hash/single_pass_functors.cuh b/cpp/src/groupby/hash/single_pass_functors.cuh index 165b7fa2bc41..c22cef57a4cc 100644 --- a/cpp/src/groupby/hash/single_pass_functors.cuh +++ b/cpp/src/groupby/hash/single_pass_functors.cuh @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ #pragma once @@ -9,10 +9,115 @@ #include #include #include +#include +#include +#include +#include #include +#include +#include + +#include namespace cudf::groupby::detail::hash { + +// Compound hash aggregations are decomposed into these simple aggregations before these kernels +// are launched. +template +__device__ auto dispatch_single_pass_aggregation(cudf::aggregation::Kind kind, F&& f, Ts&&... args) +{ + switch (kind) { + case cudf::aggregation::SUM: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::SUM_OVERFLOW: + return f.template operator()( + cuda::std::forward(args)...); + case cudf::aggregation::PRODUCT: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::MIN: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::MAX: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::COUNT_VALID: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::COUNT_ALL: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::SUM_OF_SQUARES: + return f.template operator()( + cuda::std::forward(args)...); + case cudf::aggregation::ARGMAX: + return f.template operator()(cuda::std::forward(args)...); + case cudf::aggregation::ARGMIN: + return f.template operator()(cuda::std::forward(args)...); + default: CUDF_UNREACHABLE("Unsupported single-pass aggregation."); + } +} + +struct unsupported_hash_value_type {}; + +template +struct dispatch_hash_value_type { + // Nested value columns are rejected by can_use_hash_groupby before these kernels are launched. + using type = cuda::std::conditional_t>; +}; + +template +struct dispatch_non_dictionary_hash_value_type { + using type = cuda::std::conditional_t>; +}; + +template +struct dispatch_dictionary_hash_value_type { + using type = cuda::std::conditional_t, + unsupported_hash_value_type>; +}; + +template +struct dispatch_single_pass_aggregation_fn { + template + __device__ auto operator()(F&& f, Ts&&... args) const + { + return f.template operator()(cuda::std::forward(args)...); + } +}; + +struct dispatch_single_pass_source_fn { + template + __device__ auto operator()(cudf::aggregation::Kind kind, F&& f, Ts&&... args) const + { + if constexpr (cuda::std::is_same_v) { + CUDF_UNREACHABLE("Unsupported hash groupby value type."); + } else { + return dispatch_single_pass_aggregation(kind, + dispatch_single_pass_aggregation_fn{}, + cuda::std::forward(f), + cuda::std::forward(args)...); + } + } +}; + +template