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
2574 lines
102 KiB
Plaintext
2574 lines
102 KiB
Plaintext
// SPDX-FileCopyrightText: Copyright (c) 2011, Duane Merrill. All rights reserved.
|
|
// SPDX-FileCopyrightText: Copyright (c) 2011-2022, NVIDIA CORPORATION. All rights reserved.
|
|
// SPDX-License-Identifier: BSD-3
|
|
|
|
//! @file
|
|
//! cub::DeviceHistogram provides device-wide parallel operations for constructing histogram(s) from a sequence of
|
|
//! samples data residing within device-accessible memory.
|
|
|
|
#pragma once
|
|
|
|
#include <cub/config.cuh>
|
|
|
|
#ifndef CCCL_DISABLE_NVRTC_COMPATIBILITY_CHECK
|
|
# if _CCCL_COMPILER(NVRTC)
|
|
# error \
|
|
"Including <cub/device/device_histogram.cuh> is not supported when compiling with NVRTC. Include block-, warp-, or thread-level primitives instead (e.g. <cub/block/block_reduce.cuh>). You can define CCCL_DISABLE_NVRTC_COMPATIBILITY_CHECK to disable this warning."
|
|
# endif // _CCCL_COMPILER(NVRTC)
|
|
#endif // CCCL_DISABLE_NVRTC_COMPATIBILITY_CHECK
|
|
|
|
#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/env_dispatch.cuh>
|
|
#include <cub/device/dispatch/dispatch_histogram.cuh>
|
|
|
|
#include <cuda/__execution/require.h>
|
|
#include <cuda/std/__algorithm/copy.h>
|
|
#include <cuda/std/__type_traits/integral_constant.h>
|
|
#include <cuda/std/__type_traits/remove_const.h>
|
|
#include <cuda/std/array>
|
|
#include <cuda/std/limits>
|
|
|
|
CUB_NAMESPACE_BEGIN
|
|
|
|
//! @rst
|
|
//! DeviceHistogram provides device-wide parallel operations for constructing histogram(s) from a sequence of
|
|
//! samples data residing within device-accessible memory.
|
|
//!
|
|
//! Overview
|
|
//! ++++++++++++++++++++++++++
|
|
//!
|
|
//! A `histogram <http://en.wikipedia.org/wiki/Histogram>`_ counts the number of observations that fall into each
|
|
//! of the disjoint categories (known as *bins*).
|
|
//!
|
|
//! Usage Considerations
|
|
//! ++++++++++++++++++++++++++
|
|
//!
|
|
//! @cdp_class{DeviceHistogram}
|
|
//!
|
|
//! Tuning
|
|
//! +++++++++++++++++++++++++++++++++++++++++++++
|
|
//!
|
|
//! All algorithms in DeviceHistogram that accept an environment can be tuned by passing a custom
|
|
//! :ref:`policy selector <cub-policy-selectors>` that returns a :cpp:struct:`cub::HistogramPolicy`, as shown in the
|
|
//! example below:
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-even-policy-selector
|
|
//! :end-before: example-end histogram-even-policy-selector
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-even-tuning
|
|
//! :end-before: example-end histogram-even-tuning
|
|
//!
|
|
//! @endrst
|
|
struct DeviceHistogram
|
|
{
|
|
//! @name Evenly-segmented bin ranges
|
|
//! @{
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using equal-width bins.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - All bins comprise the same width of sample values: ``(upper_level - lower_level) / (num_levels - 1)``.
|
|
//! - If the common type of ``SampleT`` and ``LevelT`` is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level) * (num_levels - 1) / (upper_level - lower_level)``, round
|
|
//! down to the nearest whole number. To protect against potential overflows, if the product
|
|
//! ``(upper_level - lower_level) * (num_levels - 1)`` exceeds the number representable by an
|
|
//! ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128
|
|
//! bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only
|
|
//! be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - The ranges ``[d_samples, d_samples + num_samples)`` and
|
|
//! ``[d_histogram, d_histogram + num_levels - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT and SampleT must be valid
|
|
//! arithmetic types. The common type must be convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of a six-bin histogram
|
|
//! from a sequence of float samples
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for
|
|
//! // input samples and output histogram
|
|
//! int num_samples; // e.g., 10
|
|
//! float* d_samples; // e.g., [2.2, 6.1, 7.1, 2.9, 3.5, 0.3, 2.9, 2.1, 6.1, 999.5]
|
|
//! int* d_histogram; // e.g., [ -, -, -, -, -, -]
|
|
//! int num_levels; // e.g., 7 (seven level boundaries for six bins)
|
|
//! float lower_level; // e.g., 0.0 (lower sample value boundary of lowest bin)
|
|
//! float upper_level; // e.g., 12.0 (upper sample value boundary of upper bin)
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::HistogramEven(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels,
|
|
//! lower_level, upper_level, num_samples);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::HistogramEven(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels,
|
|
//! lower_level, upper_level, num_samples);
|
|
//!
|
|
//! // d_histogram <-- [1, 5, 0, 3, 0, 0];
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length
|
|
//! `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin.
|
|
//!
|
|
//! @param[in] num_samples
|
|
//! The number of input samples (i.e., the length of `d_samples`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t HistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
LevelT lower_level,
|
|
LevelT upper_level,
|
|
OffsetT num_samples,
|
|
const EnvT& env = {})
|
|
{
|
|
/// The sample value type of the input iterator
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramEven<1, 1>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{lower_level},
|
|
::cuda::std::array{upper_level},
|
|
num_samples,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * num_samples,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using equal-width bins.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be specified using
|
|
//! the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - All bins comprise the same width of sample values: ``(upper_level - lower_level) / (num_levels - 1)``
|
|
//! - If the common type of ``SampleT`` and ``LevelT`` is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level) * (num_levels - 1) / (upper_level - lower_level)``, round
|
|
//! down to the nearest whole number. To protect against potential overflows, if the product
|
|
//! ``(upper_level - lower_level) * (num_levels - 1)`` exceeds the number representable by an
|
|
//! ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128
|
|
//! bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only
|
|
//! be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)`` and
|
|
//! ``row_end = row_begin + num_row_samples``. The ranges
|
|
//! ``[row_begin, row_end)`` and ``[d_histogram, d_histogram + num_levels - 1)``
|
|
//! shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types. The common type must be
|
|
//! convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of a six-bin histogram
|
|
//! from a 2x5 region of interest within a flattened 2x7 array of float samples.
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for
|
|
//! // input samples and output histogram
|
|
//! int num_row_samples; // e.g., 5
|
|
//! int num_rows; // e.g., 2;
|
|
//! size_t row_stride_bytes; // e.g., 7 * sizeof(float)
|
|
//! float* d_samples; // e.g., [2.2, 6.1, 7.1, 2.9, 3.5, -, -,
|
|
//! // 0.3, 2.9, 2.1, 6.1, 999.5, -, -]
|
|
//! int* d_histogram; // e.g., [ -, -, -, -, -, -]
|
|
//! int num_levels; // e.g., 7 (seven level boundaries for six bins)
|
|
//! float lower_level; // e.g., 0.0 (lower sample value boundary of lowest bin)
|
|
//! float upper_level; // e.g., 12.0 (upper sample value boundary of upper bin)
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::HistogramEven(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, lower_level, upper_level,
|
|
//! num_row_samples, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::HistogramEven(
|
|
//! d_temp_storage, temp_storage_bytes, d_samples, d_histogram,
|
|
//! d_samples, d_histogram, num_levels, lower_level, upper_level,
|
|
//! num_row_samples, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // d_histogram <-- [1, 5, 0, 3, 0, 0];
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading
|
|
//! input samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of
|
|
//! length `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin.
|
|
//!
|
|
//! @param[in] num_row_samples
|
|
//! The number of data samples per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in
|
|
//! the region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t HistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
LevelT lower_level,
|
|
LevelT upper_level,
|
|
OffsetT num_row_samples,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
return MultiHistogramEven<1, 1>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{lower_level},
|
|
::cuda::std::array{upper_level},
|
|
num_row_samples,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using
|
|
//! equal-width bins.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The input is a sequence of *pixel* structures, where each pixel comprises
|
|
//! a record of ``NUM_CHANNELS`` consecutive data samples
|
|
//! (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS``
|
|
//! (e.g., only *RGB* histograms from *RGBA* pixel samples).
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - If the common type of sample and level is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level[i]) * (num_levels - 1) / (upper_level[i] - lower_level[i])``, round down
|
|
//! to the nearest whole number. To protect against potential overflows, if, for any channel ``i``, the product
|
|
//! ``(upper_level[i] - lower_level[i]) * (num_levels[i] - 1)`` exceeds the number representable by an ``uint64_t``,
|
|
//! the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128 bits wide, bin computation
|
|
//! will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only be returned if bin
|
|
//! computation would overflow for 128-bit arithmetic.
|
|
//! - For a given channel ``c`` in ``[0, NUM_ACTIVE_CHANNELS)``, the ranges
|
|
//! ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` and
|
|
//! ``[d_histogram[c], d_histogram[c] + num_levels[c] - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types.
|
|
//! The common type must be convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of three 256-bin *RGB* histograms
|
|
//! from a quad-channel sequence of *RGBA* pixels (8 bits per channel per pixel)
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for
|
|
//! // input samples and output histograms
|
|
//! int num_pixels; // e.g., 5
|
|
//! unsigned char* d_samples; // e.g., [(2, 6, 7, 5), (3, 0, 2, 1), (7, 0, 6, 2),
|
|
//! // (0, 6, 7, 5), (3, 0, 2, 6)]
|
|
//! int* d_histogram[3]; // e.g., three device pointers to three device buffers,
|
|
//! // each allocated with 256 integer counters
|
|
//! int num_levels[3]; // e.g., {257, 257, 257};
|
|
//! unsigned int lower_level[3]; // e.g., {0, 0, 0};
|
|
//! unsigned int upper_level[3]; // e.g., {256, 256, 256};
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::MultiHistogramEven<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels,
|
|
//! lower_level, upper_level, num_pixels);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::MultiHistogramEven<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels,
|
|
//! lower_level, upper_level, num_pixels);
|
|
//!
|
|
//! // d_histogram <-- [ [1, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, ..., 0],
|
|
//! // [0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, ..., 0],
|
|
//! // [0, 0, 2, 0, 0, 0, 1, 2, 0, 0, 0, ..., 0] ]
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than
|
|
//! the number of channels being actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading
|
|
//! input samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the multi-channel input sequence of data samples.
|
|
//! The samples from different channels are assumed to be interleaved
|
|
//! (e.g., an array of 32-bit pixels where each pixel consists of four
|
|
//! *RGBA* 8-bit samples).
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! @rst
|
|
//! The pointers to the histogram counter output arrays, one for each active
|
|
//! channel. For channel\ :sub:`i`, the allocation length of
|
|
//! ``d_histogram[i]`` should be `num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! @rst
|
|
//! The number of boundaries (levels) for delineating histogram samples in each active channel.
|
|
//! Implies that the number of bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] num_pixels
|
|
//! The number of multi-channel pixels (i.e., the length of `d_samples / NUM_CHANNELS`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> lower_level,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> upper_level,
|
|
OffsetT num_pixels,
|
|
const EnvT& env = {})
|
|
{
|
|
/// The sample value type of the input iterator
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
|
|
return MultiHistogramEven<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
num_pixels,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * NUM_CHANNELS * num_pixels,
|
|
env);
|
|
}
|
|
|
|
private:
|
|
template <size_t N, typename T>
|
|
_CCCL_HOST_DEVICE static auto to_array(T* ptr)
|
|
{
|
|
::cuda::std::array<::cuda::std::remove_const_t<T>, N> a{};
|
|
::cuda::std::copy(ptr, ptr + N, a.begin());
|
|
return a;
|
|
}
|
|
|
|
public:
|
|
//! Deprecate [Since 3.0]
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CCCL_DEPRECATED_BECAUSE("Prefer the new overload taking cuda::std::arrays") CUB_RUNTIME_FUNCTION static cudaError_t
|
|
MultiHistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram[NUM_ACTIVE_CHANNELS],
|
|
const int num_levels[NUM_ACTIVE_CHANNELS],
|
|
const LevelT lower_level[NUM_ACTIVE_CHANNELS],
|
|
const LevelT upper_level[NUM_ACTIVE_CHANNELS],
|
|
OffsetT num_pixels,
|
|
const EnvT& env = {})
|
|
{
|
|
/// The sample value type of the input iterator
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramEven<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_histogram),
|
|
to_array<NUM_ACTIVE_CHANNELS>(num_levels),
|
|
to_array<NUM_ACTIVE_CHANNELS>(lower_level),
|
|
to_array<NUM_ACTIVE_CHANNELS>(upper_level),
|
|
num_pixels,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of
|
|
//! multi-channel "pixel" data samples using equal-width bins.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The input is a sequence of *pixel* structures, where each pixel
|
|
//! comprises a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., only *RGB*
|
|
//! histograms from *RGBA* pixel samples).
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - If the common type of sample and level is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level[i]) * (num_levels - 1) / (upper_level[i] - lower_level[i])``,
|
|
//! round down to the nearest whole number. To protect against potential overflows, if, for any channel ``i``,
|
|
//! the product ``(upper_level[i] - lower_level[i]) * (num_levels[i] - 1)`` exceeds the number representable by
|
|
//! an ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned.
|
|
//! If the common type is 128 bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue``
|
|
//! will only be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, and sample ``s`` in
|
|
//! ``[0, num_row_pixels)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)``,
|
|
//! ``sample_begin = row_begin + s * NUM_CHANNELS``, and
|
|
//! ``sample_end = sample_begin + NUM_ACTIVE_CHANNELS``. For a given channel ``c`` in
|
|
//! ``[0, NUM_ACTIVE_CHANNELS)``, the ranges
|
|
//! ``[sample_begin, sample_end)`` and
|
|
//! ``[d_histogram[c], d_histogram[c] + num_levels[c] - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types. The common type must be
|
|
//! convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of three 256-bin
|
|
//! *RGB* histograms from a 2x3 region of interest of within a flattened 2x4
|
|
//! array of quad-channel *RGBA* pixels (8 bits per channel per pixel).
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for input
|
|
//! // samples and output histograms
|
|
//! int num_row_pixels; // e.g., 3
|
|
//! int num_rows; // e.g., 2
|
|
//! size_t row_stride_bytes; // e.g., 4 * sizeof(unsigned char) * NUM_CHANNELS
|
|
//! unsigned char* d_samples; // e.g., [(2, 6, 7, 5), (3, 0, 2, 1), (7, 0, 6, 2), (-, -, -, -),
|
|
//! // (0, 6, 7, 5), (3, 0, 2, 6), (1, 1, 1, 1), (-, -, -, -)]
|
|
//! int* d_histogram[3]; // e.g., three device pointers to three device buffers,
|
|
//! // each allocated with 256 integer counters
|
|
//! int num_levels[3]; // e.g., {257, 257, 257};
|
|
//! unsigned int lower_level[3]; // e.g., {0, 0, 0};
|
|
//! unsigned int upper_level[3]; // e.g., {256, 256, 256};
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::MultiHistogramEven<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, lower_level, upper_level,
|
|
//! num_row_pixels, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::MultiHistogramEven<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, lower_level, upper_level,
|
|
//! num_row_pixels, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // d_histogram <-- [ [1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, ..., 0],
|
|
//! // [0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, ..., 0],
|
|
//! // [0, 1, 2, 0, 0, 0, 1, 2, 0, 0, 0, ..., 0] ]
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than
|
|
//! the number of channels being actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input
|
|
//! samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the multi-channel input sequence of data samples. The
|
|
//! samples from different channels are assumed to be interleaved (e.g.,
|
|
//! an array of 32-bit pixels where each pixel consists of four
|
|
//! *RGBA* 8-bit samples).
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! @rst
|
|
//! The pointers to the histogram counter output arrays, one for each
|
|
//! active channel. For channel\ :sub:`i`, the allocation length
|
|
//! of ``d_histogram[i]`` should be ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! @rst
|
|
//! The number of boundaries (levels) for delineating histogram samples in each active channel.
|
|
//! Implies that the number of bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] num_row_pixels
|
|
//! The number of multi-channel pixels per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region of
|
|
//! interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> lower_level,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> upper_level,
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceHistogram::MultiHistogramEven");
|
|
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
::cuda::std::bool_constant<sizeof(SampleT) == 1> is_byte_sample;
|
|
|
|
using default_policy_selector =
|
|
detail::histogram::policy_selector_from_types<SampleT, CounterT, NUM_CHANNELS, NUM_ACTIVE_CHANNELS, true>;
|
|
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, auto stream) -> cudaError_t {
|
|
if constexpr (sizeof(OffsetT) > sizeof(int))
|
|
{
|
|
if ((static_cast<unsigned long long>(num_rows) * row_stride_bytes) < static_cast<unsigned long long>(INT_MAX))
|
|
{
|
|
return detail::histogram::dispatch_even<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
(int) num_row_pixels,
|
|
(int) num_rows,
|
|
(int) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
}
|
|
}
|
|
|
|
return detail::histogram::dispatch_even<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
num_row_pixels,
|
|
num_rows,
|
|
(OffsetT) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
});
|
|
}
|
|
|
|
//! Deprecate [Since 3.0]
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CCCL_DEPRECATED_BECAUSE("Prefer the new overload taking cuda::std::arrays") CUB_RUNTIME_FUNCTION static cudaError_t
|
|
MultiHistogramEven(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram[NUM_ACTIVE_CHANNELS],
|
|
const int num_levels[NUM_ACTIVE_CHANNELS],
|
|
const LevelT lower_level[NUM_ACTIVE_CHANNELS],
|
|
const LevelT upper_level[NUM_ACTIVE_CHANNELS],
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
return MultiHistogramEven<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_histogram),
|
|
to_array<NUM_ACTIVE_CHANNELS>(num_levels),
|
|
to_array<NUM_ACTIVE_CHANNELS>(lower_level),
|
|
to_array<NUM_ACTIVE_CHANNELS>(upper_level),
|
|
num_row_pixels,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
env);
|
|
}
|
|
|
|
//! @}
|
|
//! @name Custom bin ranges
|
|
//! @{
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using the specified bin boundary levels.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - The value range for bin\ :sub:`i` is ``[level[i], level[i+1])``
|
|
//! - The range ``[d_histogram, d_histogram + num_levels - 1)`` shall not
|
|
//! overlap ``[d_samples, d_samples + num_samples)`` nor
|
|
//! ``[d_levels, d_levels + num_levels)`` in any way. The ranges
|
|
//! ``[d_levels, d_levels + num_levels)`` and
|
|
//! ``[d_samples, d_samples + num_samples)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of an six-bin histogram
|
|
//! from a sequence of float samples
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for input
|
|
//! // samples and output histogram
|
|
//! int num_samples; // e.g., 10
|
|
//! float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, 0.3, 2.9, 2.0, 6.1, 999.5]
|
|
//! int* d_histogram; // e.g., [ -, -, -, -, -, -]
|
|
//! int num_levels // e.g., 7 (seven level boundaries for six bins)
|
|
//! float* d_levels; // e.g., [0.0, 2.0, 4.0, 6.0, 8.0, 12.0, 16.0]
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::HistogramRange(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels, num_samples);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::HistogramRange(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels, num_samples);
|
|
//!
|
|
//! // d_histogram <-- [1, 5, 0, 3, 0, 0];
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading
|
|
//! input samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length
|
|
//! `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointer to the array of boundaries (levels). Bin ranges are defined
|
|
//! by consecutive boundary pairings: lower sample value boundaries are
|
|
//! inclusive and upper sample value boundaries are exclusive.
|
|
//!
|
|
//! @param[in] num_samples
|
|
//! The number of data samples per row in the region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t HistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
const LevelT* d_levels,
|
|
OffsetT num_samples,
|
|
const EnvT& env = {})
|
|
{
|
|
/// The sample value type of the input iterator
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramRange<1, 1>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{d_levels},
|
|
num_samples,
|
|
(OffsetT) 1,
|
|
(size_t) (sizeof(SampleT) * num_samples),
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using the specified bin boundary levels.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - The value range for bin\ :sub:`i` is ``[level[i], level[i+1])``
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)`` and
|
|
//! ``row_end = row_begin + num_row_samples``. The range
|
|
//! ``[d_histogram, d_histogram + num_levels - 1)`` shall not overlap
|
|
//! ``[row_begin, row_end)`` nor ``[d_levels, d_levels + num_levels)``.
|
|
//! The ranges ``[d_levels, d_levels + num_levels)`` and ``[row_begin, row_end)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of a six-bin histogram
|
|
//! from a 2x5 region of interest within a flattened 2x7 array of float samples.
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for input samples and
|
|
//! // output histogram
|
|
//! int num_row_samples; // e.g., 5
|
|
//! int num_rows; // e.g., 2;
|
|
//! int row_stride_bytes; // e.g., 7 * sizeof(float)
|
|
//! float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, -, -,
|
|
//! // 0.3, 2.9, 2.0, 6.1, 999.5, -, -]
|
|
//! int* d_histogram; // e.g., [ -, -, -, -, -, -]
|
|
//! int num_levels // e.g., 7 (seven level boundaries for six bins)
|
|
//! float *d_levels; // e.g., [0.0, 2.0, 4.0, 6.0, 8.0, 12.0, 16.0]
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::HistogramRange(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels,
|
|
//! num_row_samples, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::HistogramRange(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels,
|
|
//! num_row_samples, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // d_histogram <-- [1, 5, 0, 3, 0, 0];
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading
|
|
//! input samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length
|
|
//! `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointer to the array of boundaries (levels). Bin ranges are defined
|
|
//! by consecutive boundary pairings: lower sample value boundaries are
|
|
//! inclusive and upper sample value boundaries are exclusive.
|
|
//!
|
|
//! @param[in] num_row_samples
|
|
//! The number of data samples per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region
|
|
//! of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t HistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
const LevelT* d_levels,
|
|
OffsetT num_row_samples,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
return MultiHistogramRange<1, 1>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{d_levels},
|
|
num_row_samples,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples
|
|
//! using the specified bin boundary levels.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The input is a sequence of *pixel* structures, where each pixel
|
|
//! comprises a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., *RGB* histograms from *RGBA* pixel samples).
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - For given channels ``c1`` and ``c2`` in ``[0, NUM_ACTIVE_CHANNELS)``, the
|
|
//! range ``[d_histogram[c1], d_histogram[c1] + num_levels[c1] - 1)`` shall
|
|
//! not overlap ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` nor
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` in any way.
|
|
//! The ranges ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` and
|
|
//! ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of three 4-bin *RGB*
|
|
//! histograms from a quad-channel sequence of *RGBA* pixels
|
|
//! (8 bits per channel per pixel)
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for
|
|
//! // input samples and output histograms
|
|
//! int num_pixels; // e.g., 5
|
|
//! unsigned char *d_samples; // e.g., [(2, 6, 7, 5),(3, 0, 2, 1),(7, 0, 6, 2),
|
|
//! // (0, 6, 7, 5),(3, 0, 2, 6)]
|
|
//! unsigned int *d_histogram[3]; // e.g., [[ -, -, -, -],[ -, -, -, -],[ -, -, -, -]];
|
|
//! int num_levels[3]; // e.g., {5, 5, 5};
|
|
//! unsigned int *d_levels[3]; // e.g., [ [0, 2, 4, 6, 8],
|
|
//! // [0, 2, 4, 6, 8],
|
|
//! // [0, 2, 4, 6, 8] ];
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::MultiHistogramRange<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels, num_pixels);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::MultiHistogramRange<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels, num_pixels);
|
|
//!
|
|
//! // d_histogram <-- [ [1, 3, 0, 1],
|
|
//! // [3, 0, 0, 2],
|
|
//! // [0, 2, 0, 3] ]
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than
|
|
//! the number of channels being actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading
|
|
//! input samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the multi-channel input sequence of data samples.
|
|
//! The samples from different channels are assumed to be interleaved (e.g.,
|
|
//! an array of 32-bit pixels where each pixel consists of four *RGBA*
|
|
//! 8-bit samples).
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! @rst
|
|
//! The pointers to the histogram counter output arrays, one for each active
|
|
//! channel. For channel\ :sub:`i`, the allocation length of
|
|
//! ``d_histogram[i]`` should be ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! @rst
|
|
//! The number of boundaries (levels) for delineating histogram samples in
|
|
//! each active channel. Implies that the number of bins for
|
|
//! channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointers to the arrays of boundaries (levels), one for each active
|
|
//! channel. Bin ranges are defined by consecutive boundary pairings: lower
|
|
//! sample value boundaries are inclusive and upper sample value boundaries
|
|
//! are exclusive.
|
|
//!
|
|
//! @param[in] num_pixels
|
|
//! The number of multi-channel pixels (i.e., the length of `d_samples / NUM_CHANNELS`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<const LevelT*, NUM_ACTIVE_CHANNELS> d_levels,
|
|
OffsetT num_pixels,
|
|
const EnvT& env = {})
|
|
{
|
|
/// The sample value type of the input iterator
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
|
|
return MultiHistogramRange<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
num_pixels,
|
|
(OffsetT) 1,
|
|
(size_t) (sizeof(SampleT) * NUM_CHANNELS * num_pixels),
|
|
env);
|
|
}
|
|
|
|
//! Deprecate [Since 3.0]
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT>
|
|
CCCL_DEPRECATED_BECAUSE("Prefer the new overload taking cuda::std::arrays") CUB_RUNTIME_FUNCTION static cudaError_t
|
|
MultiHistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram[NUM_ACTIVE_CHANNELS],
|
|
const int num_levels[NUM_ACTIVE_CHANNELS],
|
|
const LevelT* const d_levels[NUM_ACTIVE_CHANNELS],
|
|
OffsetT num_pixels,
|
|
cudaStream_t stream = nullptr)
|
|
{
|
|
return MultiHistogramRange<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_histogram),
|
|
to_array<NUM_ACTIVE_CHANNELS>(num_levels),
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_levels),
|
|
num_pixels,
|
|
stream);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using
|
|
//! the specified bin boundary levels.
|
|
//!
|
|
//! .. versionadded:: 2.2.0
|
|
//! First appears in CUDA Toolkit 12.3.
|
|
//!
|
|
//! - The input is a sequence of *pixel* structures, where each pixel comprises
|
|
//! a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., *RGB* histograms from *RGBA* pixel samples).
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, and sample ``s`` in ``[0, num_row_pixels)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)``,
|
|
//! ``sample_begin = row_begin + s * NUM_CHANNELS``, and
|
|
//! ``sample_end = sample_begin + NUM_ACTIVE_CHANNELS``. For given channels
|
|
//! ``c1`` and ``c2`` in ``[0, NUM_ACTIVE_CHANNELS)``, the range
|
|
//! ``[d_histogram[c1], d_histogram[c1] + num_levels[c1] - 1)`` shall not overlap
|
|
//! ``[sample_begin, sample_end)`` nor
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` in any way. The ranges
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` and
|
|
//! ``[sample_begin, sample_end)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! The code snippet below illustrates the computation of three 4-bin *RGB*
|
|
//! histograms from a 2x3 region of interest of within a flattened 2x4 array
|
|
//! of quad-channel *RGBA* pixels (8 bits per channel per pixel).
|
|
//!
|
|
//!
|
|
//! .. code-block:: c++
|
|
//!
|
|
//! #include <cub/cub.cuh> // or equivalently <cub/device/device_histogram.cuh>
|
|
//!
|
|
//! // Declare, allocate, and initialize device-accessible pointers for input
|
|
//! // samples and output histograms
|
|
//! int num_row_pixels; // e.g., 3
|
|
//! int num_rows; // e.g., 2
|
|
//! size_t row_stride_bytes; // e.g., 4 * sizeof(unsigned char) * NUM_CHANNELS
|
|
//! unsigned char* d_samples; // e.g., [(2, 6, 7, 5),(3, 0, 2, 1),(1, 1, 1, 1),(-, -, -, -),
|
|
//! // (7, 0, 6, 2),(0, 6, 7, 5),(3, 0, 2, 6),(-, -, -, -)]
|
|
//! int* d_histogram[3]; // e.g., [[ -, -, -, -],[ -, -, -, -],[ -, -, -, -]];
|
|
//! int num_levels[3]; // e.g., {5, 5, 5};
|
|
//! unsigned int* d_levels[3]; // e.g., [ [0, 2, 4, 6, 8],
|
|
//! // [0, 2, 4, 6, 8],
|
|
//! // [0, 2, 4, 6, 8] ];
|
|
//! ...
|
|
//!
|
|
//! // Determine temporary device storage requirements
|
|
//! void* d_temp_storage = nullptr;
|
|
//! size_t temp_storage_bytes = 0;
|
|
//! cub::DeviceHistogram::MultiHistogramRange<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels, d_levels,
|
|
//! num_row_pixels, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // Allocate temporary storage
|
|
//! cudaMalloc(&d_temp_storage, temp_storage_bytes);
|
|
//!
|
|
//! // Compute histograms
|
|
//! cub::DeviceHistogram::MultiHistogramRange<4, 3>(
|
|
//! d_temp_storage, temp_storage_bytes,
|
|
//! d_samples, d_histogram, num_levels,
|
|
//! d_levels, num_row_pixels, num_rows, row_stride_bytes);
|
|
//!
|
|
//! // d_histogram <-- [ [2, 3, 0, 1],
|
|
//! // [3, 0, 0, 2],
|
|
//! // [1, 2, 0, 3] ]
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than
|
|
//! the number of channels being actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input
|
|
//! samples. @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @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_samples
|
|
//! The pointer to the multi-channel input sequence of data samples. The
|
|
//! samples from different channels are assumed to be interleaved (e.g., an
|
|
//! array of 32-bit pixels where each pixel consists of four
|
|
//! *RGBA* 8-bit samples).
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! @rst
|
|
//! The pointers to the histogram counter output arrays, one for each active
|
|
//! channel. For channel\ :sub:`i`, the allocation length of
|
|
//! ``d_histogram[i]`` should be ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! @rst
|
|
//! The number of boundaries (levels) for delineating histogram samples in
|
|
//! each active channel. Implies that the number of bins for
|
|
//! channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointers to the arrays of boundaries (levels), one for each active
|
|
//! channel. Bin ranges are defined by consecutive boundary pairings: lower
|
|
//! sample value boundaries are inclusive and upper sample value boundaries
|
|
//! are exclusive.
|
|
//!
|
|
//! @param[in] num_row_pixels
|
|
//! The number of multi-channel pixels per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the
|
|
//! region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<const LevelT*, NUM_ACTIVE_CHANNELS> d_levels,
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE_IF(d_temp_storage, "cub::DeviceHistogram::MultiHistogramRange");
|
|
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
::cuda::std::bool_constant<sizeof(SampleT) == 1> is_byte_sample;
|
|
|
|
using default_policy_selector =
|
|
detail::histogram::policy_selector_from_types<SampleT, CounterT, NUM_CHANNELS, NUM_ACTIVE_CHANNELS, false>;
|
|
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, auto stream) -> cudaError_t {
|
|
if constexpr (sizeof(OffsetT) > sizeof(int))
|
|
{
|
|
if ((static_cast<unsigned long long>(num_rows) * row_stride_bytes) < static_cast<unsigned long long>(INT_MAX))
|
|
{
|
|
return detail::histogram::dispatch_range<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
(int) num_row_pixels,
|
|
(int) num_rows,
|
|
(int) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
}
|
|
}
|
|
|
|
return detail::histogram::dispatch_range<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
num_row_pixels,
|
|
num_rows,
|
|
(OffsetT) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
});
|
|
}
|
|
|
|
//! Deprecate [Since 3.0]
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT>
|
|
CCCL_DEPRECATED_BECAUSE("Prefer the new overload taking cuda::std::arrays") CUB_RUNTIME_FUNCTION static cudaError_t
|
|
MultiHistogramRange(
|
|
void* d_temp_storage,
|
|
size_t& temp_storage_bytes,
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram[NUM_ACTIVE_CHANNELS],
|
|
const int num_levels[NUM_ACTIVE_CHANNELS],
|
|
const LevelT* const d_levels[NUM_ACTIVE_CHANNELS],
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
cudaStream_t stream = nullptr)
|
|
{
|
|
return MultiHistogramRange<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_temp_storage,
|
|
temp_storage_bytes,
|
|
d_samples,
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_histogram),
|
|
to_array<NUM_ACTIVE_CHANNELS>(num_levels),
|
|
to_array<NUM_ACTIVE_CHANNELS>(d_levels),
|
|
num_row_pixels,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
stream);
|
|
}
|
|
|
|
//@}
|
|
|
|
//! @name Environment-based overloads
|
|
//! @{
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using equal-width bins.
|
|
//!
|
|
//! .. 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 number of histogram bins is (``num_levels - 1``)
|
|
//! - All bins comprise the same width of sample values: ``(upper_level - lower_level) / (num_levels - 1)``.
|
|
//! - If the common type of ``SampleT`` and ``LevelT`` is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level) * (num_levels - 1) / (upper_level - lower_level)``, round
|
|
//! down to the nearest whole number. To protect against potential overflows, if the product
|
|
//! ``(upper_level - lower_level) * (num_levels - 1)`` exceeds the number representable by an
|
|
//! ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128
|
|
//! bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only
|
|
//! be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - The ranges ``[d_samples, d_samples + num_samples)`` and
|
|
//! ``[d_histogram, d_histogram + num_levels - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT and SampleT must be valid
|
|
//! arithmetic types. The common type must be convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-even-env
|
|
//! :end-before: example-end histogram-even-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin.
|
|
//!
|
|
//! @param[in] num_samples
|
|
//! The number of input samples (i.e., the length of `d_samples`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t HistogramEven(
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
LevelT lower_level,
|
|
LevelT upper_level,
|
|
OffsetT num_samples,
|
|
const EnvT& env = {})
|
|
{
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramEven<1, 1>(
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{lower_level},
|
|
::cuda::std::array{upper_level},
|
|
num_samples,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * num_samples,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a 2D region of data samples using equal-width bins.
|
|
//!
|
|
//! .. 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``
|
|
//!
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be specified using
|
|
//! the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - All bins comprise the same width of sample values: ``(upper_level - lower_level) / (num_levels - 1)``
|
|
//! - If the common type of ``SampleT`` and ``LevelT`` is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level) * (num_levels - 1) / (upper_level - lower_level)``, round
|
|
//! down to the nearest whole number. To protect against potential overflows, if the product
|
|
//! ``(upper_level - lower_level) * (num_levels - 1)`` exceeds the number representable by an
|
|
//! ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128
|
|
//! bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only
|
|
//! be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)`` and
|
|
//! ``row_end = row_begin + num_row_samples``. The ranges
|
|
//! ``[row_begin, row_end)`` and ``[d_histogram, d_histogram + num_levels - 1)``
|
|
//! shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types. The common type must be
|
|
//! convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-even-2d-env
|
|
//! :end-before: example-end histogram-even-2d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin.
|
|
//!
|
|
//! @param[in] num_row_samples
|
|
//! The number of data samples per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t HistogramEven(
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
LevelT lower_level,
|
|
LevelT upper_level,
|
|
OffsetT num_row_samples,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
return MultiHistogramEven<1, 1>(
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{lower_level},
|
|
::cuda::std::array{upper_level},
|
|
num_row_samples,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples
|
|
//! using equal-width bins.
|
|
//!
|
|
//! .. 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 input is a sequence of *pixel* structures, where each pixel comprises
|
|
//! a record of ``NUM_CHANNELS`` consecutive data samples
|
|
//! (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS``
|
|
//! (e.g., only *RGB* histograms from *RGBA* pixel samples).
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - If the common type of sample and level is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level[i]) * (num_levels - 1) / (upper_level[i] - lower_level[i])``, round down
|
|
//! to the nearest whole number. To protect against potential overflows, if, for any channel ``i``, the product
|
|
//! ``(upper_level[i] - lower_level[i]) * (num_levels[i] - 1)`` exceeds the number representable by an ``uint64_t``,
|
|
//! the cuda error ``cudaErrorInvalidValue`` is returned. If the common type is 128 bits wide, bin computation
|
|
//! will use 128-bit arithmetic and ``cudaErrorInvalidValue`` will only be returned if bin
|
|
//! computation would overflow for 128-bit arithmetic.
|
|
//! - For a given channel ``c`` in ``[0, NUM_ACTIVE_CHANNELS)``, the ranges
|
|
//! ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` and
|
|
//! ``[d_histogram[c], d_histogram[c] + num_levels[c] - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types.
|
|
//! The common type must be convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin multi-histogram-even-1d-env
|
|
//! :end-before: example-end multi-histogram-even-1d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than the number of channels being
|
|
//! actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the multi-channel input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! Array of active channel histogram counter output arrays, each of length `num_levels[channel] - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! Array of the number of boundaries (levels) for each active channel.
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! Array of the lower sample value bound (inclusive) for the lowest bin of each active channel.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! Array of the upper sample value bound (exclusive) for the highest bin of each active channel.
|
|
//!
|
|
//! @param[in] num_pixels
|
|
//! The number of multi-channel pixels (i.e., the length of `d_samples / NUM_CHANNELS`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramEven(
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> lower_level,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> upper_level,
|
|
OffsetT num_pixels,
|
|
const EnvT& env = {})
|
|
{
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramEven<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
num_pixels,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * NUM_CHANNELS * num_pixels,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a 2D region of multi-channel "pixel" data samples
|
|
//! using equal-width bins.
|
|
//!
|
|
//! .. 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 input is a sequence of *pixel* structures, where each pixel
|
|
//! comprises a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., only *RGB*
|
|
//! histograms from *RGBA* pixel samples).
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - If the common type of sample and level is of integral type, the bin for a sample is
|
|
//! computed as ``(sample - lower_level[i]) * (num_levels - 1) / (upper_level[i] - lower_level[i])``,
|
|
//! round down to the nearest whole number. To protect against potential overflows, if, for any channel ``i``,
|
|
//! the product ``(upper_level[i] - lower_level[i]) * (num_levels[i] - 1)`` exceeds the number representable by
|
|
//! an ``uint64_t``, the cuda error ``cudaErrorInvalidValue`` is returned.
|
|
//! If the common type is 128 bits wide, bin computation will use 128-bit arithmetic and ``cudaErrorInvalidValue``
|
|
//! will only be returned if bin computation would overflow for 128-bit arithmetic.
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, and sample ``s`` in
|
|
//! ``[0, num_row_pixels)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)``,
|
|
//! ``sample_begin = row_begin + s * NUM_CHANNELS``, and
|
|
//! ``sample_end = sample_begin + NUM_ACTIVE_CHANNELS``. For a given channel ``c`` in
|
|
//! ``[0, NUM_ACTIVE_CHANNELS)``, the ranges
|
|
//! ``[sample_begin, sample_end)`` and
|
|
//! ``[d_histogram[c], d_histogram[c] + num_levels[c] - 1)`` shall not overlap in any way.
|
|
//! - ``cuda::std::common_type<LevelT, SampleT>`` must be valid, and both LevelT
|
|
//! and SampleT must be valid arithmetic types. The common type must be
|
|
//! convertible to ``int`` and trivially copyable.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin multi-histogram-even-2d-env
|
|
//! :end-before: example-end multi-histogram-even-2d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than the number of channels being
|
|
//! actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths,
|
|
//! pointer differences, etc. @offset_size1
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the multi-channel input sequence of data samples. The
|
|
//! samples from different channels are assumed to be interleaved (e.g.,
|
|
//! an array of 32-bit pixels where each pixel consists of four
|
|
//! *RGBA* 8-bit samples).
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! @rst
|
|
//! The pointers to the histogram counter output arrays, one for each
|
|
//! active channel. For channel\ :sub:`i`, the allocation length
|
|
//! of ``d_histogram[i]`` should be ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! @rst
|
|
//! The number of boundaries (levels) for delineating histogram samples in each active channel.
|
|
//! Implies that the number of bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! @endrst
|
|
//!
|
|
//! @param[in] lower_level
|
|
//! The lower sample value bound (inclusive) for the lowest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] upper_level
|
|
//! The upper sample value bound (exclusive) for the highest histogram bin in each active channel.
|
|
//!
|
|
//! @param[in] num_row_pixels
|
|
//! The number of multi-channel pixels per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region of
|
|
//! interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramEven(
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> lower_level,
|
|
::cuda::std::array<LevelT, NUM_ACTIVE_CHANNELS> upper_level,
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceHistogram::MultiHistogramEven");
|
|
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
::cuda::std::bool_constant<sizeof(SampleT) == 1> is_byte_sample;
|
|
|
|
using default_policy_selector =
|
|
detail::histogram::policy_selector_from_types<SampleT, CounterT, NUM_CHANNELS, NUM_ACTIVE_CHANNELS, true>;
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
env, [&](auto policy_selector, void* storage, size_t& bytes, auto stream) -> cudaError_t {
|
|
if constexpr (sizeof(OffsetT) > sizeof(int))
|
|
{
|
|
if ((unsigned long long) (num_rows * row_stride_bytes) < (unsigned long long) INT_MAX)
|
|
{
|
|
return detail::histogram::dispatch_even<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
(int) num_row_pixels,
|
|
(int) num_rows,
|
|
(int) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
}
|
|
}
|
|
|
|
return detail::histogram::dispatch_even<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
lower_level,
|
|
upper_level,
|
|
num_row_pixels,
|
|
num_rows,
|
|
(OffsetT) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
});
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a sequence of data samples using the specified bin boundary levels.
|
|
//!
|
|
//! .. 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 number of histogram bins is (``num_levels - 1``)
|
|
//! - The value range for bin\ :sub:`i` is ``[level[i], level[i+1])``
|
|
//! - The range ``[d_histogram, d_histogram + num_levels - 1)`` shall not
|
|
//! overlap ``[d_samples, d_samples + num_samples)`` nor
|
|
//! ``[d_levels, d_levels + num_levels)`` in any way. The ranges
|
|
//! ``[d_levels, d_levels + num_levels)`` and
|
|
//! ``[d_samples, d_samples + num_samples)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-range-env
|
|
//! :end-before: example-end histogram-range-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointer to the array of boundaries (levels). Bin ranges are defined
|
|
//! by consecutive boundary pairings: lower sample value boundaries are
|
|
//! inclusive and upper sample value boundaries are exclusive.
|
|
//!
|
|
//! @param[in] num_samples
|
|
//! The number of input samples (i.e., the length of `d_samples`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t HistogramRange(
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
const LevelT* d_levels,
|
|
OffsetT num_samples,
|
|
const EnvT& env = {})
|
|
{
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramRange<1, 1>(
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{d_levels},
|
|
num_samples,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * num_samples,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes an intensity histogram from a 2D region of data samples using the specified bin boundary levels.
|
|
//!
|
|
//! .. 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``
|
|
//!
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins is (``num_levels - 1``)
|
|
//! - The value range for bin\ :sub:`i` is ``[level[i], level[i+1])``
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)`` and
|
|
//! ``row_end = row_begin + num_row_samples``. The range
|
|
//! ``[d_histogram, d_histogram + num_levels - 1)`` shall not overlap
|
|
//! ``[row_begin, row_end)`` nor ``[d_levels, d_levels + num_levels)``.
|
|
//! The ranges ``[d_levels, d_levels + num_levels)`` and ``[row_begin, row_end)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin histogram-range-2d-env
|
|
//! :end-before: example-end histogram-range-2d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! The pointer to the histogram counter output array of length `num_levels - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! The number of boundaries (levels) for delineating histogram samples.
|
|
//! Implies that the number of bins is `num_levels - 1`.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! The pointer to the array of boundaries (levels). Bin ranges are defined
|
|
//! by consecutive boundary pairings: lower sample value boundaries are
|
|
//! inclusive and upper sample value boundaries are exclusive.
|
|
//!
|
|
//! @param[in] num_row_samples
|
|
//! The number of data samples per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t HistogramRange(
|
|
SampleIteratorT d_samples,
|
|
CounterT* d_histogram,
|
|
int num_levels,
|
|
const LevelT* d_levels,
|
|
OffsetT num_row_samples,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
return MultiHistogramRange<1, 1>(
|
|
d_samples,
|
|
::cuda::std::array{d_histogram},
|
|
::cuda::std::array{num_levels},
|
|
::cuda::std::array{d_levels},
|
|
num_row_samples,
|
|
num_rows,
|
|
row_stride_bytes,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples
|
|
//! using the specified bin boundary levels.
|
|
//!
|
|
//! .. 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 input is a sequence of *pixel* structures, where each pixel
|
|
//! comprises a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., *RGB* histograms from *RGBA* pixel samples).
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - For given channels ``c1`` and ``c2`` in ``[0, NUM_ACTIVE_CHANNELS)``, the
|
|
//! range ``[d_histogram[c1], d_histogram[c1] + num_levels[c1] - 1)`` shall
|
|
//! not overlap ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` nor
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` in any way.
|
|
//! The ranges ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` and
|
|
//! ``[d_samples, d_samples + NUM_CHANNELS * num_pixels)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin multi-histogram-range-1d-env
|
|
//! :end-before: example-end multi-histogram-range-1d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than the number of channels being
|
|
//! actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the multi-channel input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! Array of active channel histogram counter output arrays, each of length `num_levels[channel] - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! Array of the number of boundaries (levels) for each active channel.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! Array of pointers to the arrays of boundaries (levels) for each active channel.
|
|
//!
|
|
//! @param[in] num_pixels
|
|
//! The number of multi-channel pixels (i.e., the length of `d_samples / NUM_CHANNELS`)
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramRange(
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<const LevelT*, NUM_ACTIVE_CHANNELS> d_levels,
|
|
OffsetT num_pixels,
|
|
const EnvT& env = {})
|
|
{
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
return MultiHistogramRange<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
num_pixels,
|
|
static_cast<OffsetT>(1),
|
|
sizeof(SampleT) * NUM_CHANNELS * num_pixels,
|
|
env);
|
|
}
|
|
|
|
//! @rst
|
|
//! Computes per-channel intensity histograms from a 2D region of multi-channel "pixel" data samples
|
|
//! using the specified bin boundary levels.
|
|
//!
|
|
//! .. 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 input is a sequence of *pixel* structures, where each pixel comprises
|
|
//! a record of ``NUM_CHANNELS`` consecutive data samples (e.g., an *RGBA* pixel).
|
|
//! - ``NUM_CHANNELS`` can be up to 4.
|
|
//! - Of the ``NUM_CHANNELS`` specified, the function will only compute
|
|
//! histograms for the first ``NUM_ACTIVE_CHANNELS`` (e.g., *RGB* histograms from *RGBA* pixel samples).
|
|
//! - A two-dimensional *region of interest* within ``d_samples`` can be
|
|
//! specified using the ``num_row_samples``, ``num_rows``, and ``row_stride_bytes`` parameters.
|
|
//! - The row stride must be a whole multiple of the sample data type
|
|
//! size, i.e., ``(row_stride_bytes % sizeof(SampleT)) == 0``.
|
|
//! - The number of histogram bins for channel\ :sub:`i` is ``num_levels[i] - 1``.
|
|
//! - For channel\ :sub:`i`, the range of values for all histogram bins have the same width:
|
|
//! ``(upper_level[i] - lower_level[i]) / (num_levels[i] - 1)``
|
|
//! - For a given row ``r`` in ``[0, num_rows)``, and sample ``s`` in ``[0, num_row_pixels)``, let
|
|
//! ``row_begin = d_samples + r * row_stride_bytes / sizeof(SampleT)``,
|
|
//! ``sample_begin = row_begin + s * NUM_CHANNELS``, and
|
|
//! ``sample_end = sample_begin + NUM_ACTIVE_CHANNELS``. For given channels
|
|
//! ``c1`` and ``c2`` in ``[0, NUM_ACTIVE_CHANNELS)``, the range
|
|
//! ``[d_histogram[c1], d_histogram[c1] + num_levels[c1] - 1)`` shall not overlap
|
|
//! ``[sample_begin, sample_end)`` nor
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` in any way. The ranges
|
|
//! ``[d_levels[c2], d_levels[c2] + num_levels[c2])`` and
|
|
//! ``[sample_begin, sample_end)`` may overlap.
|
|
//! - @devicestorage
|
|
//!
|
|
//! Snippet
|
|
//! +++++++
|
|
//!
|
|
//! .. literalinclude:: ../../../cub/test/catch2_test_device_histogram_env_api.cu
|
|
//! :language: c++
|
|
//! :dedent:
|
|
//! :start-after: example-begin multi-histogram-range-2d-env
|
|
//! :end-before: example-end multi-histogram-range-2d-env
|
|
//!
|
|
//! @endrst
|
|
//!
|
|
//! @tparam NUM_CHANNELS
|
|
//! Number of channels interleaved in the input data (may be greater than the number of channels being
|
|
//! actively histogrammed)
|
|
//!
|
|
//! @tparam NUM_ACTIVE_CHANNELS
|
|
//! **[inferred]** Number of channels actively being histogrammed
|
|
//!
|
|
//! @tparam SampleIteratorT
|
|
//! **[inferred]** Random-access input iterator type for reading input samples @iterator
|
|
//!
|
|
//! @tparam CounterT
|
|
//! **[inferred]** Integer type for histogram bin counters
|
|
//!
|
|
//! @tparam LevelT
|
|
//! **[inferred]** Type for specifying boundaries (levels)
|
|
//!
|
|
//! @tparam OffsetT
|
|
//! **[inferred]** Signed integer type for sequence offsets, list lengths, pointer differences, etc.
|
|
//!
|
|
//! @tparam EnvT
|
|
//! **[inferred]** Environment type (e.g., `cuda::std::execution::env<...>`)
|
|
//!
|
|
//! @param[in] d_samples
|
|
//! The pointer to the multi-channel input sequence of data samples.
|
|
//!
|
|
//! @param[out] d_histogram
|
|
//! Array of active channel histogram counter output arrays, each of length `num_levels[channel] - 1`.
|
|
//!
|
|
//! @param[in] num_levels
|
|
//! Array of the number of boundaries (levels) for each active channel.
|
|
//!
|
|
//! @param[in] d_levels
|
|
//! Array of pointers to the arrays of boundaries (levels) for each active channel.
|
|
//!
|
|
//! @param[in] num_row_pixels
|
|
//! The number of multi-channel pixels per row in the region of interest
|
|
//!
|
|
//! @param[in] num_rows
|
|
//! The number of rows in the region of interest
|
|
//!
|
|
//! @param[in] row_stride_bytes
|
|
//! The number of bytes between starts of consecutive rows in the region of interest
|
|
//!
|
|
//! @param[in] env
|
|
//! @rst
|
|
//! **[optional]** Execution environment. Default is ``cuda::std::execution::env{}``.
|
|
//! @endrst
|
|
template <int NUM_CHANNELS,
|
|
int NUM_ACTIVE_CHANNELS,
|
|
typename SampleIteratorT,
|
|
typename CounterT,
|
|
typename LevelT,
|
|
typename OffsetT,
|
|
typename EnvT = ::cuda::std::execution::env<>>
|
|
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t MultiHistogramRange(
|
|
SampleIteratorT d_samples,
|
|
::cuda::std::array<CounterT*, NUM_ACTIVE_CHANNELS> d_histogram,
|
|
::cuda::std::array<int, NUM_ACTIVE_CHANNELS> num_levels,
|
|
::cuda::std::array<const LevelT*, NUM_ACTIVE_CHANNELS> d_levels,
|
|
OffsetT num_row_pixels,
|
|
OffsetT num_rows,
|
|
size_t row_stride_bytes,
|
|
const EnvT& env = {})
|
|
{
|
|
_CCCL_NVTX_RANGE_SCOPE("cub::DeviceHistogram::MultiHistogramRange");
|
|
|
|
using SampleT = cub::detail::it_value_t<SampleIteratorT>;
|
|
::cuda::std::bool_constant<sizeof(SampleT) == 1> is_byte_sample;
|
|
|
|
using default_policy_selector =
|
|
detail::histogram::policy_selector_from_types<SampleT, CounterT, NUM_CHANNELS, NUM_ACTIVE_CHANNELS, false>;
|
|
return detail::dispatch_with_env_and_tuning<default_policy_selector>(
|
|
env, [&](auto policy_selector, void* storage, size_t& bytes, auto stream) -> cudaError_t {
|
|
if constexpr (sizeof(OffsetT) > sizeof(int))
|
|
{
|
|
if ((unsigned long long) (num_rows * row_stride_bytes) < (unsigned long long) INT_MAX)
|
|
{
|
|
return detail::histogram::dispatch_range<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
(int) num_row_pixels,
|
|
(int) num_rows,
|
|
(int) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
}
|
|
}
|
|
|
|
return detail::histogram::dispatch_range<NUM_CHANNELS, NUM_ACTIVE_CHANNELS>(
|
|
storage,
|
|
bytes,
|
|
d_samples,
|
|
d_histogram,
|
|
num_levels,
|
|
d_levels,
|
|
num_row_pixels,
|
|
num_rows,
|
|
(OffsetT) (row_stride_bytes / sizeof(SampleT)),
|
|
stream,
|
|
is_byte_sample,
|
|
policy_selector);
|
|
});
|
|
}
|
|
|
|
//@}
|
|
};
|
|
|
|
CUB_NAMESPACE_END
|