-
Notifications
You must be signed in to change notification settings - Fork 422
[cudax][cuco] Port fixed_capacity_map benchmarks from cuCollections #9748
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
Open
sleeepyjack
wants to merge
7
commits into
NVIDIA:main
Choose a base branch
from
sleeepyjack:cuco-fixed-capacity-map-benchmarks
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
3a65f23
Set fixed_capacity_map CG size default
sleeepyjack 655fe24
Port fixed_capacity_map benchmarks
sleeepyjack 8715a61
Merge remote-tracking branch 'upstream/main' into cuco-fixed-capacity…
sleeepyjack 2ea4d34
Tidy benchmark namespace aliases
sleeepyjack dee3726
Address review comments
sleeepyjack 1e75578
Temporary workaround for #9755
sleeepyjack 0696f69
Merge remote-tracking branch 'upstream/main' into cuco-fixed-capacity…
sleeepyjack File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Part of CUDA Experimental in CUDA C++ Core Libraries, | ||
| // under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cuda/std/cstdint> | ||
|
|
||
| #include <vector> | ||
|
|
||
| #include <nvbench/nvbench.cuh> | ||
| #include <nvbench/range.cuh> | ||
|
|
||
| namespace cuda::experimental::cuco::benchmark::defaults | ||
| { | ||
| //! Key types covered by the default CUCO benchmark type axes. | ||
| using key_type_range = ::nvbench::type_list<::nvbench::int32_t, ::nvbench::int64_t>; | ||
| //! Value types covered by the default CUCO benchmark type axes. | ||
| using value_type_range = ::nvbench::type_list<::nvbench::int32_t, ::nvbench::int64_t>; | ||
|
|
||
| //! Default number of inputs used when sweeping another benchmark axis. | ||
| inline constexpr auto n = ::nvbench::int64_t{100'000'000}; | ||
| //! Default fixed-capacity map target occupancy. | ||
| inline constexpr auto occupancy = 0.5; | ||
| //! Default lookup matching rate for contains-style benchmarks. | ||
| inline constexpr auto matching_rate = 1.0; | ||
| //! Default deterministic seed used by benchmark data generators. | ||
| inline constexpr auto seed = ::cuda::std::uint32_t{42}; | ||
|
|
||
| //! Input-size sweep that remains cacheable for direct comparisons with CUCO benchmarks. | ||
| inline const auto n_range_cache = ::std::vector<::nvbench::int64_t>{8'000, 80'000, 800'000, 8'000'000, 80'000'000}; | ||
| //! Occupancy sweep used by fixed-capacity container benchmarks. | ||
| inline const auto occupancy_range = ::nvbench::range(0.1, 0.9, 0.1); | ||
| //! Average multiplicity sweep for duplicate-key distributions. | ||
| inline const auto multiplicity_range = ::std::vector<::nvbench::int64_t>{1, 2, 4, 8, 16}; | ||
| //! Matching-rate sweep used by contains-style benchmarks. | ||
| inline const auto matching_rate_range = ::nvbench::range(0.1, 1.0, 0.1); | ||
| } // namespace cuda::experimental::cuco::benchmark::defaults |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,283 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Part of CUDA Experimental in CUDA C++ Core Libraries, | ||
| // under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cuda/std/detail/__config> | ||
|
|
||
| #include <thrust/execution_policy.h> | ||
| #include <thrust/random.h> | ||
| #include <thrust/sequence.h> | ||
| #include <thrust/shuffle.h> | ||
| #include <thrust/transform.h> | ||
|
|
||
| #include <cuda/iterator> | ||
| #include <cuda/std/cmath> | ||
| #include <cuda/std/cstddef> | ||
| #include <cuda/std/iterator> | ||
| #include <cuda/std/limits> | ||
| #include <cuda/std/type_traits> | ||
|
|
||
| #include <stdexcept> | ||
|
|
||
| #include "defaults.cuh" | ||
| #include <nvbench/nvbench.cuh> | ||
|
|
||
| namespace cuda::experimental::cuco::benchmark | ||
| { | ||
| namespace distribution | ||
| { | ||
| //! Distribution tag for unique keys generated by shuffling the sequence `[0, N)`. | ||
| struct unique | ||
| {}; | ||
|
|
||
| //! Distribution tag for uniformly sampled keys with controlled average multiplicity. | ||
| struct uniform | ||
| { | ||
| //! Constructs a uniform distribution tag with the requested average key multiplicity. | ||
| //! | ||
| //! @param __multiplicity Average number of generated keys that map to each unique key value. | ||
| //! @throws std::invalid_argument if `__multiplicity` is not positive. | ||
| explicit uniform(::nvbench::int64_t __multiplicity) | ||
| : __value{__multiplicity} | ||
| { | ||
| if (__multiplicity <= 0) | ||
| { | ||
| throw ::std::invalid_argument{"Multiplicity must be greater than 0"}; | ||
| } | ||
| } | ||
|
|
||
| //! Average number of generated keys that map to each unique key value. | ||
| ::nvbench::int64_t __value; | ||
| }; | ||
| } // namespace distribution | ||
|
|
||
| namespace detail | ||
| { | ||
| template <typename _Tp, typename _Dist, typename _Rng> | ||
| struct __generate_uniform_fn | ||
| { | ||
| _CCCL_HOST_DEVICE_API constexpr __generate_uniform_fn( | ||
| ::cuda::std::size_t __num, _Dist __dist, ::cuda::std::size_t __seed) | ||
| : __num{__num} | ||
| , __dist{__dist} | ||
| , __seed{__seed} | ||
| {} | ||
|
|
||
| _CCCL_HOST_DEVICE_API constexpr _Tp operator()(::cuda::std::size_t __idx) const noexcept | ||
| { | ||
| _Rng __rng; | ||
| __rng.seed(__seed + __idx * 1664525ull + 1013904223ull); | ||
|
|
||
| const auto __num_unique_keys_unclamped = static_cast<::cuda::std::size_t>( | ||
| ::cuda::std::ceil(static_cast<double>(__num) / static_cast<double>(__dist.__value))); | ||
| const auto __num_unique_keys = | ||
| __num_unique_keys_unclamped < ::cuda::std::size_t{1} ? ::cuda::std::size_t{1} : __num_unique_keys_unclamped; | ||
| ::thrust::uniform_int_distribution<_Tp> __key_dist{_Tp{0}, static_cast<_Tp>(__num_unique_keys - 1)}; | ||
| return __key_dist(__rng); | ||
| } | ||
|
|
||
| ::cuda::std::size_t __num; | ||
| _Dist __dist; | ||
| ::cuda::std::size_t __seed; | ||
| }; | ||
|
|
||
| template <typename _Tp, typename _Rng> | ||
| struct __dropout_fn | ||
| { | ||
| _CCCL_HOST_DEVICE_API constexpr explicit __dropout_fn(::cuda::std::size_t __num) | ||
| : __num{__num} | ||
| {} | ||
|
|
||
| _CCCL_HOST_DEVICE_API _Tp operator()(::cuda::std::size_t __seed) const noexcept | ||
| { | ||
| _Rng __rng; | ||
| ::thrust::uniform_int_distribution<_Tp> __dist{static_cast<_Tp>(__num), ::cuda::std::numeric_limits<_Tp>::max()}; | ||
| __rng.seed(__seed); | ||
| return __dist(__rng); | ||
| } | ||
|
|
||
| ::cuda::std::size_t __num; | ||
| }; | ||
|
|
||
| template <typename _Rng> | ||
| struct __dropout_pred | ||
| { | ||
| _CCCL_HOST_DEVICE_API constexpr explicit __dropout_pred(double __keep_prob) | ||
| : __keep_prob{__keep_prob} | ||
| {} | ||
|
|
||
| _CCCL_HOST_DEVICE_API bool operator()(::cuda::std::size_t __seed) const noexcept | ||
| { | ||
| _Rng __rng; | ||
| ::thrust::uniform_real_distribution<double> __dist{0.0, 1.0}; | ||
| __rng.seed(__seed); | ||
| return __dist(__rng) > __keep_prob; | ||
| } | ||
|
|
||
| double __keep_prob; | ||
| }; | ||
| } // namespace detail | ||
|
|
||
| //! Random key generator used by CUCO benchmarks. | ||
| //! | ||
| //! The generator defaults to `defaults::seed` to keep benchmark data reproducible across runs. | ||
| //! | ||
| //! @tparam _Rng Pseudo-random number generator type compatible with Thrust random distributions. | ||
| template <typename _Rng = ::thrust::default_random_engine> | ||
| class key_generator | ||
| { | ||
| public: | ||
| //! Constructs a key generator with the given seed. | ||
| //! | ||
| //! @param __seed Seed used to initialize the generator state. | ||
| explicit key_generator(::cuda::std::uint32_t __seed = defaults::seed) | ||
| : __rng{__seed} | ||
| {} | ||
|
|
||
| //! Generates keys according to the given distribution using the default device execution policy. | ||
| //! | ||
| //! @tparam _Dist Distribution tag type. | ||
| //! @tparam _OutputIt Output iterator type whose value type is the generated key type. | ||
| //! @param __dist Distribution tag controlling how keys are generated. | ||
| //! @param __out_begin Beginning of the output key range. | ||
| //! @param __out_end End of the output key range. | ||
| //! @throws std::invalid_argument if `_Dist` is not a supported distribution tag. | ||
| template <typename _Dist, typename _OutputIt> | ||
| void generate(_Dist __dist, _OutputIt __out_begin, _OutputIt __out_end) | ||
| { | ||
| generate(__dist, __out_begin, __out_end, ::thrust::device); | ||
| } | ||
|
|
||
| //! Generates keys according to the given distribution using the provided execution policy. | ||
| //! | ||
| //! @tparam _Dist Distribution tag type. | ||
| //! @tparam _OutputIt Output iterator type whose value type is the generated key type. | ||
| //! @tparam _ExecPolicy Thrust execution policy type. | ||
| //! @param __dist Distribution tag controlling how keys are generated. | ||
| //! @param __out_begin Beginning of the output key range. | ||
| //! @param __out_end End of the output key range. | ||
| //! @param __exec_policy Execution policy used for the underlying Thrust algorithms. | ||
| //! @throws std::invalid_argument if `_Dist` is not a supported distribution tag. | ||
| template <typename _Dist, typename _OutputIt, typename _ExecPolicy> | ||
| void generate(_Dist __dist, _OutputIt __out_begin, _OutputIt __out_end, _ExecPolicy __exec_policy) | ||
| { | ||
| using __value_type = typename ::cuda::std::iterator_traits<_OutputIt>::value_type; | ||
|
|
||
| if constexpr (::cuda::std::is_same_v<_Dist, distribution::unique>) | ||
| { | ||
| ::thrust::sequence(__exec_policy, __out_begin, __out_end, __value_type{0}); | ||
| ::thrust::shuffle(__exec_policy, __out_begin, __out_end, __rng); | ||
| } | ||
| else if constexpr (::cuda::std::is_same_v<_Dist, distribution::uniform>) | ||
| { | ||
| const auto __num_keys = static_cast<::cuda::std::size_t>(::cuda::std::distance(__out_begin, __out_end)); | ||
| const auto __seed = static_cast<::cuda::std::size_t>(__rng()); | ||
|
|
||
| ::thrust::transform( | ||
| __exec_policy, | ||
| ::cuda::counting_iterator<::cuda::std::size_t>{0}, | ||
| ::cuda::counting_iterator<::cuda::std::size_t>{__num_keys}, | ||
| __out_begin, | ||
| detail::__generate_uniform_fn<__value_type, _Dist, _Rng>{__num_keys, __dist, __seed}); | ||
| } | ||
| else | ||
| { | ||
| throw ::std::invalid_argument{"Unexpected distribution type"}; | ||
| } | ||
| } | ||
|
|
||
| //! Drops keys with probability `1 - keep_prob` using the default device execution policy. | ||
| //! | ||
| //! Replaced keys are sampled from `[N, max_key]`, where `N` is the number of keys in the range. | ||
| //! | ||
| //! @tparam _InOutIt Mutable iterator type whose value type is the key type. | ||
| //! @param __begin Beginning of the key range to update in place. | ||
| //! @param __end End of the key range to update in place. | ||
| //! @param __keep_prob Probability of keeping each original key. Must be in `[0, 1]`. | ||
| //! @throws std::invalid_argument if `__keep_prob` is outside `[0, 1]`. | ||
| template <typename _InOutIt> | ||
| void dropout(_InOutIt __begin, _InOutIt __end, double __keep_prob) | ||
| { | ||
| dropout(__begin, __end, __keep_prob, ::thrust::device); | ||
| } | ||
|
|
||
| //! Drops keys with probability `1 - keep_prob` using the provided execution policy. | ||
| //! | ||
| //! Replaced keys are sampled from `[N, max_key]`, where `N` is the number of keys in the range. | ||
| //! | ||
| //! @tparam _InOutIt Mutable iterator type whose value type is the key type. | ||
| //! @tparam _ExecPolicy Thrust execution policy type. | ||
| //! @param __begin Beginning of the key range to update in place. | ||
| //! @param __end End of the key range to update in place. | ||
| //! @param __keep_prob Probability of keeping each original key. Must be in `[0, 1]`. | ||
| //! @param __exec_policy Execution policy used for the underlying Thrust algorithms. | ||
| //! @throws std::invalid_argument if `__keep_prob` is outside `[0, 1]`. | ||
| template <typename _InOutIt, typename _ExecPolicy> | ||
| void dropout(_InOutIt __begin, _InOutIt __end, double __keep_prob, _ExecPolicy __exec_policy) | ||
| { | ||
| using __value_type = typename ::cuda::std::iterator_traits<_InOutIt>::value_type; | ||
|
|
||
| if (__keep_prob < 0.0 || __keep_prob > 1.0) | ||
| { | ||
| throw ::std::invalid_argument{"Probability needs to be between 0 and 1"}; | ||
| } | ||
|
|
||
| if (__keep_prob < 1.0) | ||
| { | ||
| const auto __num_keys = static_cast<::cuda::std::size_t>(::cuda::std::distance(__begin, __end)); | ||
| ::cuda::counting_iterator<::cuda::std::size_t> __seeds{static_cast<::cuda::std::size_t>(__rng())}; | ||
|
|
||
| ::thrust::transform_if( | ||
| __exec_policy, | ||
| __seeds, | ||
| __seeds + __num_keys, | ||
| __begin, | ||
| detail::__dropout_fn<__value_type, _Rng>{__num_keys}, | ||
| detail::__dropout_pred<_Rng>{__keep_prob}); | ||
| } | ||
|
|
||
| ::thrust::shuffle(__exec_policy, __begin, __end, __rng); | ||
| } | ||
|
|
||
| private: | ||
| _Rng __rng; | ||
| }; | ||
|
|
||
| //! Constructs the requested distribution tag from NVBench axis values. | ||
| //! | ||
| //! `distribution::uniform` reads the `Multiplicity` axis from `state`. | ||
| //! | ||
| //! @tparam _Dist Distribution tag type to construct. | ||
| //! @param __state NVBench state containing distribution-specific axis values. | ||
| //! @return Distribution tag initialized from the benchmark state. | ||
| //! @throws std::invalid_argument if `_Dist` is not a supported distribution tag. | ||
| template <typename _Dist> | ||
| _Dist dist_from_state(::nvbench::state const& __state) | ||
| { | ||
| if constexpr (::cuda::std::is_same_v<_Dist, distribution::unique>) | ||
| { | ||
| return _Dist{}; | ||
| } | ||
| else if constexpr (::cuda::std::is_same_v<_Dist, distribution::uniform>) | ||
| { | ||
| return _Dist{__state.get_int64("Multiplicity")}; | ||
| } | ||
| else | ||
| { | ||
| throw ::std::invalid_argument{"Unexpected distribution type"}; | ||
| } | ||
| } | ||
| } // namespace cuda::experimental::cuco::benchmark | ||
|
|
||
| NVBENCH_DECLARE_TYPE_STRINGS( | ||
| ::cuda::experimental::cuco::benchmark::distribution::unique, "UNIQUE", "distribution::unique"); | ||
| NVBENCH_DECLARE_TYPE_STRINGS( | ||
| ::cuda::experimental::cuco::benchmark::distribution::uniform, "UNIFORM", "distribution::uniform"); | ||
Oops, something went wrong.
Oops, something went wrong.
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.
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.
Nit: testing/benchmarks or any non-library code shouldn't be
__ugly