CCCL (CUDA C++ Core Libraries) provides: - CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk) - Thrust: high-level parallel algorithms (transform_reduce, sort, scan) - libcudacxx: CUDA C++ standard library (atomics, barriers, memory) - cudax: experimental features (memory resources, allocators) - Tuning policies: per-SM hardware-specific algorithm parameters Competition optimization vectors mapped to CCCL: - Output TPS (83% weight): warp_reduce, block_reduce, device_topk - Input TPS (14% weight): device_scan, block_load, prefetch - Cache TPS (3% weight): prefix caching strategy patterns - Memory (0.9 util): pooled/cached/buddy allocators Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only) License: Apache-2.0
1233 lines
47 KiB
Plaintext
1233 lines
47 KiB
Plaintext
// SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#pragma once
|
|
|
|
#include <cub/config.cuh>
|
|
|
|
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
|
# pragma GCC system_header
|
|
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
|
# pragma clang system_header
|
|
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
|
# pragma system_header
|
|
#endif // no system header
|
|
|
|
#include <cub/detail/binary_search_helpers.cuh>
|
|
#include <cub/detail/choose_offset.cuh>
|
|
#include <cub/detail/env_dispatch.cuh>
|
|
#include <cub/device/device_for.cuh>
|
|
#include <cub/device/device_transform.cuh>
|
|
#include <cub/device/dispatch/dispatch_find.cuh>
|
|
#include <cub/device/dispatch/dispatch_find_bound_sorted_values.cuh>
|
|
#include <cub/thread/thread_operators.cuh>
|
|
|
|
#include <cuda/__functional/always_true_false.h>
|
|
#include <cuda/__iterator/zip_iterator.h>
|
|
#include <cuda/__nvtx/nvtx.h>
|
|
|
|
CUB_NAMESPACE_BEGIN
|
|
|
|
//! @rst
|
|
//! Tuning
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The FindIf algorithms that accept an environment can be tuned by passing a custom
|
|
//! :ref:`policy selector <cub-policy-selectors>` that returns a :cpp:struct:`cub::FindIfPolicy`, as shown in the
|
|
//! example below:
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin find-if-policy-selector
|
|
//! :end-before: example-end find-if-policy-selector
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin find-if-tuning
|
|
//! :end-before: example-end find-if-tuning
|
|
//!
|
|
//! The ``LowerBoundSortedValues`` and ``UpperBoundSortedValues`` algorithms that accept an environment can be tuned by
|
|
//! passing a custom :ref:`policy selector <cub-policy-selectors>` that returns a
|
|
//! :cpp:struct:`cub::FindBoundSortedValuesPolicy`, as shown in the example below:
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_bound_sorted_values_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin lower-bound-sorted-values-policy-selector
|
|
//! :end-before: example-end lower-bound-sorted-values-policy-selector
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_bound_sorted_values_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin lower-bound-sorted-values-tuning
|
|
//! :end-before: example-end lower-bound-sorted-values-tuning
|
|
//!
|
|
//! @endrst
|
|
struct DeviceFind
|
|
{
|
|
//! @rst
|
|
//! Finds the first element in the input sequence that satisfies the given predicate.
|
|
//!
|
|
//! - The search terminates at the first element where the predicate evaluates to true.
|
|
//! - The index of the found element is written to ``d_out``.
|
|
//! - If no element satisfies the predicate, ``num_items`` is written to ``d_out``.
|
|
//! - The range ``[d_out, d_out + 1)`` shall not overlap ``[d_in, d_in + num_items)`` in any way.
|
|
//! - @devicestorage
|
|
//!
|
|
//! .. versionadded:: 3.3.0
|
|
//!
|
|
//! Snippet
|
|
//! ==========================================================================
|
|
//!
|
|
//! The code snippet below illustrates the finding of the first element that satisfies the predicate.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin find-if-predicate
|
|
//! :end-before: example-end find-if-predicate
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin device-find-if
|
|
//! :end-before: example-end device-find-if
|
|
//! @endrst
|
|
//!
|
|
//! @tparam InputIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input items @iterator
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! **[inferred]** Random-access output iterator type for writing the result index @iterator
|
|
//!
|
|
//! @tparam ScanOpT
|
|
//! **[inferred]** Unary predicate functor type having member `bool operator()(const T &a)`
|
|
//!
|
|
//! @tparam NumItemsT
|
|
//! **[inferred]** An integral type representing the number of input elements
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_temp_storage
|
|
//! @devicestorage
|
|
//!
|
|
//! @param[in,out] temp_storage_bytes
|
|
//! Reference to size in bytes of `d_temp_storage` allocation
|
|
//!
|
|
//! @param[in] d_in
|
|
//! Random-access iterator to the input sequence of data items
|
|
//!
|
|
//! @param[out] d_out
|
|
//! Random-access iterator to the output location for the index of the found element
|
|
//!
|
|
//! @param[in] scan_op
|
|
//! Unary predicate functor for determining whether an element satisfies the search condition
|
|
//!
|
|
//! @param[in] num_items
|
|
//! Total number of input items (i.e., the length of `d_in`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
template <typename InputIteratorT,
|
|
typename OutputIteratorT,
|
|
typename ScanOpT,
|
|
typename NumItemsT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t FindIf(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
InputIteratorT d_in,
|
|
OutputIteratorT d_out,
|
|
ScanOpT scan_op,
|
|
NumItemsT num_items,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceFind::FindIf");
|
|
|
|
using OffsetT = detail::choose_offset_t<NumItemsT>;
|
|
|
|
using default_policy_selector = detail::find::policy_selector_from_types<detail::it_value_t<InputIteratorT>>;
|
|
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
env,
|
|
[&](auto policy_selector, void* storage, size_t& bytes, cudaStream_t stream) {
|
|
return detail::find::dispatch(
|
|
storage, bytes, d_in, d_out, static_cast<OffsetT>(num_items), scan_op, stream, policy_selector);
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! Overview
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``, performs a binary search in the range
|
|
//! ``[d_range, d_range + range_num_items)``, using ``comp`` as the comparator to find the iterator to the
|
|
//! **first** element of said range which **is not** ordered **before** ``value``.
|
|
//!
|
|
//! - The range ``[d_range, d_range + range_num_items)`` must be sorted consistently with ``comp``.
|
|
//!
|
|
//! .. versionadded:: 3.3.0
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the lower bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin device-lower-bound
|
|
//! :end-before: example-end device-lower-bound
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_temp_storage
|
|
//! @devicestorage
|
|
//!
|
|
//! @param[in,out] temp_storage_bytes
|
|
//! Reference to size in bytes of `d_temp_storage` allocation
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered range to be searched.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the ordered range to be searched.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the range of values to be searched for.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object which returns true if its first argument is ordered before the second in the
|
|
//! [Strict Weak Ordering] of the range to be searched.
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t LowerBound(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceFind::LowerBound");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
|
|
return detail::dispatch_with_env(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
env,
|
|
[&]([[maybe_unused]] auto tuning, void* storage, size_t& bytes, auto stream) {
|
|
if (storage == nullptr)
|
|
{
|
|
bytes = 1;
|
|
return cudaSuccess;
|
|
}
|
|
|
|
return DeviceTransform::__transform_internal(
|
|
::cuda::std::make_tuple(d_values),
|
|
d_output,
|
|
static_cast<ValuesOffsetT>(values_num_items),
|
|
::cuda::always_true{},
|
|
detail::find::make_binary_search_transform_op<detail::find::lower_bound>(
|
|
d_range, static_cast<RangeOffsetT>(range_num_items), comp),
|
|
::cuda::stream_ref{stream});
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! Overview
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``, performs a binary search in the range
|
|
//! ``[d_range, d_range + range_num_items)``,
|
|
//! using ``comp`` as the comparator to find the iterator to the **first** element of said range which **is**
|
|
//! ordered **after** ``value``.
|
|
//!
|
|
//! - The range ``[d_range, d_range + range_num_items)`` must be sorted consistently with ``comp``.
|
|
//!
|
|
//! .. versionadded:: 3.3.0
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the upper bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin device-upper-bound
|
|
//! :end-before: example-end device-upper-bound
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_temp_storage
|
|
//! @devicestorage
|
|
//!
|
|
//! @param[in,out] temp_storage_bytes
|
|
//! Reference to size in bytes of `d_temp_storage` allocation
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered range to be searched.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the ordered range to be searched.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the range of values to be searched for.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object which returns true if its first argument is ordered before the second in the
|
|
//! [Strict Weak Ordering] of the range to be searched.
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t UpperBound(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceFind::UpperBound");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
|
|
return detail::dispatch_with_env(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
env,
|
|
[&]([[maybe_unused]] auto tuning, void* storage, size_t& bytes, auto stream) {
|
|
if (storage == nullptr)
|
|
{
|
|
bytes = 1;
|
|
return cudaSuccess;
|
|
}
|
|
|
|
return DeviceTransform::__transform_internal(
|
|
::cuda::std::make_tuple(d_values),
|
|
d_output,
|
|
static_cast<ValuesOffsetT>(values_num_items),
|
|
::cuda::always_true{},
|
|
detail::find::make_binary_search_transform_op<detail::find::upper_bound>(
|
|
d_range, static_cast<RangeOffsetT>(range_num_items), comp),
|
|
::cuda::stream_ref{stream});
|
|
});
|
|
}
|
|
//! @rst
|
|
//! Finds the first element in the input sequence that satisfies the given predicate.
|
|
//!
|
|
//! - The search terminates at the first element where the predicate evaluates to true.
|
|
//! - The index of the found element is written to ``d_out``.
|
|
//! - If no element satisfies the predicate, ``num_items`` is written to ``d_out``.
|
|
//! - The range ``[d_out, d_out + 1)`` shall not overlap ``[d_in, d_in + num_items)`` in any way.
|
|
//!
|
|
//! .. versionadded:: 3.4.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! This is an environment-based API that allows customization of:
|
|
//!
|
|
//! - Stream: Query via ``cuda::get_stream``
|
|
//! - Memory resource: Query via ``cuda::mr::get_memory_resource``
|
|
//!
|
|
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the finding of the first element that satisfies the predicate.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin find-if-predicate
|
|
//! :end-before: example-end find-if-predicate
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin find-if-env
|
|
//! :end-before: example-end find-if-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam InputIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input items @iterator
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! **[inferred]** Random-access output iterator type for writing the result index @iterator
|
|
//!
|
|
//! @tparam ScanOpT
|
|
//! **[inferred]** Unary predicate functor type having member `bool operator()(const T &a)`
|
|
//!
|
|
//! @tparam NumItemsT
|
|
//! **[inferred]** An integral type representing the number of input elements
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_in
|
|
//! Random-access iterator to the input sequence of data items
|
|
//!
|
|
//! @param[out] d_out
|
|
//! Random-access iterator to the output location for the index of the found element
|
|
//!
|
|
//! @param[in] scan_op
|
|
//! Unary predicate functor for determining whether an element satisfies the search condition
|
|
//!
|
|
//! @param[in] num_items
|
|
//! Total number of input items (i.e., the length of `d_in`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename InputIteratorT,
|
|
typename OutputIteratorT,
|
|
typename ScanOpT,
|
|
typename NumItemsT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION _CCCL_FORCEINLINE static cudaError_t
|
|
FindIf(InputIteratorT d_in, OutputIteratorT d_out, ScanOpT scan_op, NumItemsT num_items, const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceFind::FindIf");
|
|
|
|
using OffsetT = detail::choose_offset_t<NumItemsT>;
|
|
|
|
using default_policy_selector = detail::find::policy_selector_from_types<detail::it_value_t<InputIteratorT>>;
|
|
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
env, [&](auto policy_selector, void* storage, size_t& bytes, cudaStream_t stream) {
|
|
return detail::find::dispatch(
|
|
storage, bytes, d_in, d_out, static_cast<OffsetT>(num_items), scan_op, stream, policy_selector);
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``, performs a binary search in the range
|
|
//! ``[d_range, d_range + range_num_items)``, using ``comp`` as the comparator to find the iterator to the
|
|
//! **first** element of said range which **is not** ordered **before** ``value``.
|
|
//!
|
|
//! .. versionadded:: 3.4.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! This is an environment-based API that allows customization of:
|
|
//!
|
|
//! - Stream: Query via ``cuda::get_stream``
|
|
//! - Memory resource: Query via ``cuda::mr::get_memory_resource``
|
|
//!
|
|
//! - The range ``[d_range, d_range + range_num_items)`` must be sorted consistently with ``comp``.
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the lower bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin lower-bound-env
|
|
//! :end-before: example-end lower-bound-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered range to be searched.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the ordered range to be searched.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the range of values to be searched for.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object which returns true if its first argument is ordered before the second in the
|
|
//! [Strict Weak Ordering] of the range to be searched.
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION _CCCL_FORCEINLINE static cudaError_t LowerBound(
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceFind::LowerBound");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
|
|
return detail::dispatch_with_env(env, [&]([[maybe_unused]] auto tuning, void* storage, size_t& bytes, auto stream) {
|
|
if (storage == nullptr)
|
|
{
|
|
bytes = 1;
|
|
return cudaSuccess;
|
|
}
|
|
|
|
return DeviceTransform::__transform_internal(
|
|
::cuda::std::make_tuple(d_values),
|
|
d_output,
|
|
static_cast<ValuesOffsetT>(values_num_items),
|
|
::cuda::always_true{},
|
|
detail::find::make_binary_search_transform_op<detail::find::lower_bound>(
|
|
d_range, static_cast<RangeOffsetT>(range_num_items), comp),
|
|
::cuda::stream_ref{stream});
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``, performs a binary search in the range
|
|
//! ``[d_range, d_range + range_num_items)``,
|
|
//! using ``comp`` as the comparator to find the iterator to the **first** element of said range which **is**
|
|
//! ordered **after** ``value``.
|
|
//!
|
|
//! .. versionadded:: 3.4.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! This is an environment-based API that allows customization of:
|
|
//!
|
|
//! - Stream: Query via ``cuda::get_stream``
|
|
//! - Memory resource: Query via ``cuda::mr::get_memory_resource``
|
|
//!
|
|
//! - The range ``[d_range, d_range + range_num_items)`` must be sorted consistently with ``comp``.
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the upper bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin upper-bound-env
|
|
//! :end-before: example-end upper-bound-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered range to be searched.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the ordered range to be searched.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the range of values to be searched for.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object which returns true if its first argument is ordered before the second in the
|
|
//! [Strict Weak Ordering] of the range to be searched.
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION _CCCL_FORCEINLINE static cudaError_t UpperBound(
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceFind::UpperBound");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
|
|
return detail::dispatch_with_env(env, [&]([[maybe_unused]] auto tuning, void* storage, size_t& bytes, auto stream) {
|
|
if (storage == nullptr)
|
|
{
|
|
bytes = 1;
|
|
return cudaSuccess;
|
|
}
|
|
|
|
return DeviceTransform::__transform_internal(
|
|
::cuda::std::make_tuple(d_values),
|
|
d_output,
|
|
static_cast<ValuesOffsetT>(values_num_items),
|
|
::cuda::always_true{},
|
|
detail::find::make_binary_search_transform_op<detail::find::upper_bound>(
|
|
d_range, static_cast<RangeOffsetT>(range_num_items), comp),
|
|
::cuda::stream_ref{stream});
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! Overview
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! Accelerated variant of :cpp:func:`LowerBound` that exploits the additional
|
|
//! precondition that ``[d_values, d_values + values_num_items)`` is also
|
|
//! sorted consistently with ``comp``.
|
|
//!
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``,
|
|
//! performs a search in ``[d_range, d_range + range_num_items)`` to find the
|
|
//! iterator to the first element that is **not ordered before** ``value``.
|
|
//!
|
|
//! Because both sequences are sorted, the algorithm uses the Merge-Path
|
|
//! algorithm (Oded et al., IPDPS 2012) to partition the combined traversal
|
|
//! across thread blocks, achieving O(N+M) total device work rather than the
|
|
//! O(M log N) of independent binary searches.
|
|
//!
|
|
//! - Both ``[d_range, d_range + range_num_items)`` **and**
|
|
//! ``[d_values, d_values + values_num_items)`` must be sorted consistently
|
|
//! with ``comp``.
|
|
//! - @devicestorage
|
|
//!
|
|
//! .. versionadded:: 3.5.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a
|
|
//! [Relation] with the value type of ``ValuesIteratorT`` via ``CompareOpT``.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a
|
|
//! [Relation] with the value type of ``RangeIteratorT`` via ``CompareOpT``.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is an integral type representing the number of values to search for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator] whose value type is assignable
|
|
//! from ``RangeIteratorT``'s difference type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering] over the value types of both
|
|
//! iterator types.
|
|
//!
|
|
//! @param[in] d_temp_storage
|
|
//! Device-accessible allocation of temporary storage. When `nullptr`, the
|
|
//! required allocation size is written to `temp_storage_bytes` and no work
|
|
//! is done.
|
|
//!
|
|
//! @param[in,out] temp_storage_bytes
|
|
//! Reference to size in bytes of `d_temp_storage` allocation
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered haystack range.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the haystack range.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the sorted range of needles.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of needle elements.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object (Strict Weak Ordering).
|
|
//!
|
|
//! @param[in] stream
|
|
//! @rst
|
|
//! **[optional]** CUDA stream to launch kernels within. Default is stream\ :sub:`0`.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t LowerBoundSortedValues(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
cudaStream_t stream = nullptr)
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceFind::LowerBoundSortedValues");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
using OffsetT = ::cuda::std::common_type_t<RangeOffsetT, ValuesOffsetT>;
|
|
|
|
return detail::find_bound_sorted_values::dispatch<detail::find_bound_sorted_values::lower_bound_mode>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_range,
|
|
static_cast<OffsetT>(range_num_items),
|
|
d_values,
|
|
static_cast<OffsetT>(values_num_items),
|
|
d_output,
|
|
comp,
|
|
stream);
|
|
}
|
|
|
|
//! @rst
|
|
//! Accelerated variant of :cpp:func:`LowerBound` that exploits the additional
|
|
//! precondition that ``[d_values, d_values + values_num_items)`` is also
|
|
//! sorted consistently with ``comp``.
|
|
//!
|
|
//! .. versionadded:: 3.5.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! This is an environment-based API that allows customization of:
|
|
//!
|
|
//! - Stream: Query via ``cuda::get_stream``
|
|
//! - Memory resource: Query via ``cuda::mr::get_memory_resource``
|
|
//!
|
|
//! - Both ``[d_range, d_range + range_num_items)`` **and**
|
|
//! ``[d_values, d_values + values_num_items)`` must be sorted consistently
|
|
//! with ``comp``.
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the lower bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_bound_sorted_values_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin lower-bound-sorted-values-env
|
|
//! :end-before: example-end lower-bound-sorted-values-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered haystack range.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the haystack range.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the sorted range of needles.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of needle elements.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object (Strict Weak Ordering).
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION _CCCL_FORCEINLINE static cudaError_t LowerBoundSortedValues(
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceFind::LowerBoundSortedValues");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
using OffsetT = ::cuda::std::common_type_t<RangeOffsetT, ValuesOffsetT>;
|
|
|
|
using default_policy_selector =
|
|
detail::find_bound_sorted_values::policy_selector_from_types<detail::it_value_t<RangeIteratorT>,
|
|
detail::it_value_t<ValuesIteratorT>>;
|
|
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
env, [&](auto policy_selector, void* storage, size_t& bytes, auto stream) {
|
|
return detail::find_bound_sorted_values::dispatch<detail::find_bound_sorted_values::lower_bound_mode>(
|
|
storage,
|
|
bytes,
|
|
d_range,
|
|
static_cast<OffsetT>(range_num_items),
|
|
d_values,
|
|
static_cast<OffsetT>(values_num_items),
|
|
d_output,
|
|
comp,
|
|
stream,
|
|
policy_selector);
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! Overview
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! Accelerated variant of :cpp:func:`UpperBound` that exploits the additional
|
|
//! precondition that ``[d_values, d_values + values_num_items)`` is also
|
|
//! sorted consistently with ``comp``.
|
|
//!
|
|
//! For each ``value`` in ``[d_values, d_values + values_num_items)``,
|
|
//! performs a search in ``[d_range, d_range + range_num_items)`` to find the
|
|
//! iterator to the first element that is **ordered after** ``value``.
|
|
//!
|
|
//! Because both sequences are sorted, the algorithm uses the Merge-Path
|
|
//! algorithm (Oded et al., IPDPS 2012) to partition the combined traversal
|
|
//! across thread blocks, achieving O(N+M) total device work rather than the
|
|
//! O(M log N) of independent binary searches.
|
|
//!
|
|
//! - Both ``[d_range, d_range + range_num_items)`` **and**
|
|
//! ``[d_values, d_values + values_num_items)`` must be sorted consistently
|
|
//! with ``comp``.
|
|
//! - @devicestorage
|
|
//!
|
|
//! .. versionadded:: 3.5.0
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a
|
|
//! [Relation] with the value type of ``ValuesIteratorT`` via ``CompareOpT``.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a
|
|
//! [Relation] with the value type of ``RangeIteratorT`` via ``CompareOpT``.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is an integral type representing the number of values to search for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator] whose value type is assignable
|
|
//! from ``RangeIteratorT``'s difference type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering] over the value types of both
|
|
//! iterator types.
|
|
//!
|
|
//! @param[in] d_temp_storage
|
|
//! Device-accessible allocation of temporary storage. When `nullptr`, the
|
|
//! required allocation size is written to `temp_storage_bytes` and no work
|
|
//! is done.
|
|
//!
|
|
//! @param[in,out] temp_storage_bytes
|
|
//! Reference to size in bytes of `d_temp_storage` allocation
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered haystack range.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the haystack range.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the sorted range of needles.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of needle elements.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object (Strict Weak Ordering).
|
|
//!
|
|
//! @param[in] stream
|
|
//! @rst
|
|
//! **[optional]** CUDA stream to launch kernels within. Default is stream\ :sub:`0`.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t UpperBoundSortedValues(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
cudaStream_t stream = nullptr)
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceFind::UpperBoundSortedValues");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
using OffsetT = ::cuda::std::common_type_t<RangeOffsetT, ValuesOffsetT>;
|
|
|
|
return detail::find_bound_sorted_values::dispatch<detail::find_bound_sorted_values::upper_bound_mode>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_range,
|
|
static_cast<OffsetT>(range_num_items),
|
|
d_values,
|
|
static_cast<OffsetT>(values_num_items),
|
|
d_output,
|
|
comp,
|
|
stream);
|
|
}
|
|
|
|
//! @rst
|
|
//! Accelerated variant of :cpp:func:`UpperBound` that exploits the additional
|
|
//! precondition that ``[d_values, d_values + values_num_items)`` is also
|
|
//! sorted consistently with ``comp``.
|
|
//!
|
|
//! .. versionadded:: 3.5.0
|
|
//! First appears in CUDA Toolkit 13.4.
|
|
//!
|
|
//! This is an environment-based API that allows customization of:
|
|
//!
|
|
//! - Stream: Query via ``cuda::get_stream``
|
|
//! - Memory resource: Query via ``cuda::mr::get_memory_resource``
|
|
//!
|
|
//! - Both ``[d_range, d_range + range_num_items)`` **and**
|
|
//! ``[d_values, d_values + values_num_items)`` must be sorted consistently
|
|
//! with ``comp``.
|
|
//!
|
|
//! Snippet
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! The code snippet below illustrates the upper bound search.
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_find_bound_sorted_values_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin upper-bound-sorted-values-env
|
|
//! :end-before: example-end upper-bound-sorted-values-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam RangeIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``ValuesIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam RangeNumItemsT
|
|
//! is an integral type representing the number of elements in the range to be searched.
|
|
//!
|
|
//! @tparam ValuesIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type forms a [Relation] with the value type of
|
|
//! ``RangeIteratorT`` using ``CompareOpT`` as the predicate.
|
|
//!
|
|
//! @tparam ValuesNumItemsT
|
|
//! is a model of integral type representing the number of elements in the range of values to be searched for.
|
|
//!
|
|
//! @tparam OutputIteratorT
|
|
//! is a model of [Random Access Iterator], whose value type is assignable from ``RangeIteratorT``'s difference
|
|
//! type.
|
|
//!
|
|
//! @tparam CompareOpT
|
|
//! is a model of [Strict Weak Ordering], which forms a [Relation] with the value types of ``RangeIteratorT``
|
|
//! and ``ValuesIteratorT``.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., ``cuda::std::execution::env<...>``)
|
|
//!
|
|
//! @param[in] d_range
|
|
//! Iterator to the beginning of the ordered haystack range.
|
|
//!
|
|
//! @param[in] range_num_items
|
|
//! Number of elements in the haystack range.
|
|
//!
|
|
//! @param[in] d_values
|
|
//! Iterator to the beginning of the sorted range of needles.
|
|
//!
|
|
//! @param[in] values_num_items
|
|
//! Number of needle elements.
|
|
//!
|
|
//! @param[out] d_output
|
|
//! Iterator to the beginning of the output range.
|
|
//!
|
|
//! @param[in] comp
|
|
//! Comparison function object (Strict Weak Ordering).
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
//!
|
|
//! [Random Access Iterator]: https://en.cppreference.com/w/cpp/iterator/random_access_iterator
|
|
//! [Strict Weak Ordering]: https://en.cppreference.com/w/cpp/concepts/strict_weak_order
|
|
//! [Relation]: https://en.cppreference.com/w/cpp/concepts/relation
|
|
template <typename RangeIteratorT,
|
|
typename RangeNumItemsT,
|
|
typename ValuesIteratorT,
|
|
typename ValuesNumItemsT,
|
|
typename OutputIteratorT,
|
|
typename CompareOpT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION _CCCL_FORCEINLINE static cudaError_t UpperBoundSortedValues(
|
|
RangeIteratorT d_range,
|
|
RangeNumItemsT range_num_items,
|
|
ValuesIteratorT d_values,
|
|
ValuesNumItemsT values_num_items,
|
|
OutputIteratorT d_output,
|
|
CompareOpT comp,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceFind::UpperBoundSortedValues");
|
|
|
|
using RangeOffsetT = detail::choose_offset_t<RangeNumItemsT>;
|
|
using ValuesOffsetT = detail::choose_offset_t<ValuesNumItemsT>;
|
|
using OffsetT = ::cuda::std::common_type_t<RangeOffsetT, ValuesOffsetT>;
|
|
|
|
using default_policy_selector =
|
|
detail::find_bound_sorted_values::policy_selector_from_types<detail::it_value_t<RangeIteratorT>,
|
|
detail::it_value_t<ValuesIteratorT>>;
|
|
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
env, [&](auto policy_selector, void* storage, size_t& bytes, auto stream) {
|
|
return detail::find_bound_sorted_values::dispatch<detail::find_bound_sorted_values::upper_bound_mode>(
|
|
storage,
|
|
bytes,
|
|
d_range,
|
|
static_cast<OffsetT>(range_num_items),
|
|
d_values,
|
|
static_cast<OffsetT>(values_num_items),
|
|
d_output,
|
|
comp,
|
|
stream,
|
|
policy_selector);
|
|
});
|
|
}
|
|
};
|
|
|
|
CUB_NAMESPACE_END
|