// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved. // SPDX-License-Identifier: Apache-2.0 /*! \file transform_reduce.h * \brief Fused transform / reduction */ #pragma once #include #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 THRUST_NAMESPACE_BEGIN /*! \addtogroup reductions * \{ * \addtogroup transformed_reductions Transformed Reductions * \ingroup reductions * \{ */ /*! \p transform_reduce fuses the \p transform and \p reduce operations. * \p transform_reduce is equivalent to performing a transformation defined by * \p unary_op into a temporary sequence and then performing \p reduce on the * transformed sequence. In most cases, fusing these two operations together is * more efficient, since fewer memory reads and writes are required. * * \p transform_reduce performs a reduction on the transformation of the * sequence [first, last) according to \p unary_op. Specifically, * \p unary_op is applied to each element of the sequence and then the result * is reduced to a single value with \p binary_op using the initial value * \p init. Note that the transformation \p unary_op is not applied to * the initial value \p init. The order of reduction is not specified, * so \p binary_op must be both commutative and associative. * * The algorithm's execution is parallelized as determined by \p exec. * * \param exec The execution policy to use for parallelization. * \param first The beginning of the sequence. * \param last The end of the sequence. * \param unary_op The function to apply to each element of the input sequence. * \param init The result is initialized to this value. * \param binary_op The reduction operation. * \return The result of the transformed reduction. * * \tparam DerivedPolicy The name of the derived execution policy. * \tparam InputIterator is a model of Input * Iterator, and \p InputIterator's \c value_type is convertible to \p UnaryFunction's argument type. * \tparam UnaryFunction The function's return type must be convertible to \c OutputType. * \tparam OutputType is a model of * Assignable, and is convertible to \p * BinaryFunction's first and second argument type. * \tparam BinaryFunction The function's return type must be convertible to \p OutputType. * * The following code snippet demonstrates how to use \p transform_reduce * to compute the maximum value of the absolute value of the elements * of a range using the \p thrust::host execution policy for parallelization: * * \code * #include * #include * #include * * template * struct absolute_value * { * __host__ __device__ T operator()(const T &x) const * { * return x < T(0) ? -x : x; * } * }; * * ... * * int data[6] = {-1, 0, -2, -2, 1, -3}; * int result = thrust::transform_reduce(thrust::host, * data, data + 6, * absolute_value(), * 0, * ::cuda::maximum()); * // result == 3 * \endcode * * \see \c transform * \see \c reduce * * \verbatim embed:rst:leading-asterisk * .. versionadded:: 2.2.0 * \endverbatim */ template _CCCL_HOST_DEVICE OutputType transform_reduce( const thrust::detail::execution_policy_base& exec, InputIterator first, InputIterator last, UnaryFunction unary_op, OutputType init, BinaryFunction binary_op); /*! \p transform_reduce fuses the \p transform and \p reduce operations. * \p transform_reduce is equivalent to performing a transformation defined by * \p unary_op into a temporary sequence and then performing \p reduce on the * transformed sequence. In most cases, fusing these two operations together is * more efficient, since fewer memory reads and writes are required. * * \p transform_reduce performs a reduction on the transformation of the * sequence [first, last) according to \p unary_op. Specifically, * \p unary_op is applied to each element of the sequence and then the result * is reduced to a single value with \p binary_op using the initial value * \p init. Note that the transformation \p unary_op is not applied to * the initial value \p init. The order of reduction is not specified, * so \p binary_op must be both commutative and associative. * * \param first The beginning of the sequence. * \param last The end of the sequence. * \param unary_op The function to apply to each element of the input sequence. * \param init The result is initialized to this value. * \param binary_op The reduction operation. * \return The result of the transformed reduction. * * \tparam InputIterator is a model of Input * Iterator, and \p InputIterator's \c value_type is convertible to \p UnaryFunction's argument type. * \tparam UnaryFunction The function's return type must be convertible to \c OutputType. * \tparam OutputType is a model of * Assignable, and is convertible to \p * BinaryFunction's first and second argument type. * \tparam BinaryFunction The function's return type must be convertible to \p OutputType. * * The following code snippet demonstrates how to use \p transform_reduce * to compute the maximum value of the absolute value of the elements * of a range. * * \code * #include * #include * * template * struct absolute_value * { * __host__ __device__ T operator()(const T &x) const * { * return x < T(0) ? -x : x; * } * }; * * ... * * int data[6] = {-1, 0, -2, -2, 1, -3}; * int result = thrust::transform_reduce(data, data + 6, * absolute_value(), * 0, * ::cuda::maximum()); * // result == 3 * \endcode * * \see \c transform * \see \c reduce * * \verbatim embed:rst:leading-asterisk * .. versionadded:: 2.2.0 * \endverbatim */ template OutputType transform_reduce( InputIterator first, InputIterator last, UnaryFunction unary_op, OutputType init, BinaryFunction binary_op); /*! \} // end transformed_reductions * \} // end reductions */ THRUST_NAMESPACE_END #include