C++ · Elementwise and Reductions

Elementwise and Reductions

#include <numkong/each.hpp>#include <numkong/reduce.hpp>#include <numkong/trigonometry.hpp>#include <numkong/tensor.hpp>#include <numkong/types.hpp> 8.0.0-rc.1 · b1f866ab

API

Types

moments_resultResult of moments(): Σxᵢ and Σxᵢ².
tensor.hpp:2325 ↗
template <typename sum_type_,
          typename sumsq_type_>
struct moments_result

Fields

sumsum_type_
sumsqsumsq_type_
minmax_resultResult of minmax(): min/max values with their indices.
tensor.hpp:2332 ↗
template <typename minmax_value_type_>
struct minmax_result

Fields

min_valueminmax_value_type_
min_indexstd::size_t
max_valueminmax_value_type_
max_indexstd::size_t

Functions

addElementwise addition: cᵢ = aᵢ + bᵢ
each.hpp:31 ↗
template <numeric_dtype in_type_>
status_t add(
    in_type_ const *a,
    in_type_ const *b,
    std::size_t d,
    in_type_ *c,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_, mutable_vector_of<in_type_> output_type_>
status_t add(
    a_type_ const & a,
    b_type_ const & b,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise cᵢ = aᵢ + bᵢ over runs of equal dimensions; unexpected_dimensions_k when they differ or any run is strided or ends mid-value.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t add(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise addition: each output is the sum of the two operands.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> add(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    allocator_type_ alloc = {}) noexcept;

Allocating elementwise add: the result is the sum of the two operands; fails like the allocating blend.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t add(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise add scalar: output[i] = input[i] + scalar.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> add(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    allocator_type_ alloc = {}) noexcept;

Allocating add scalar; fails like the allocating scale.

Parameters

ainFirst input vector
binSecond input vector
dinNumber of dimensions in input vectors
coutOutput vector
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
scaleElementwise scale: cᵢ = α × aᵢ + β
each.hpp:89 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t scale(
    in_type_ const *a,
    std::size_t d,
    typename in_type_::scale_t const *alpha,
    typename in_type_::scale_t const *beta,
    in_type_ *c,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> a_type_, mutable_vector_of<in_type_> output_type_>
requires (!requires(a_type_ const &tensor) { tensor.rank(); })
status_t scale(
    a_type_ const & a,
    typename in_type_::scale_t alpha,
    typename in_type_::scale_t beta,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise cᵢ = α × aᵢ + β, failing like the concept add.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t scale(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    tensor_span<value_type_, max_rank_> output) noexcept;

Scale: output[i] = α × input[i] + β.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> scale(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    allocator_type_ alloc = {}) noexcept;

Allocating scale: result[i] = α × input[i] + β; empty for an empty input, or the allocation's or the kernel's failure.

Parameters

ainInput vector
dinNumber of dimensions in input vector
alphainScale coefficient
betainShift coefficient
coutOutput vector
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
blendBlend: cᵢ = α × aᵢ + β × bᵢ
each.hpp:174 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t blend(
    in_type_ const *a,
    in_type_ const *b,
    std::size_t d,
    typename in_type_::scale_t const *alpha,
    typename in_type_::scale_t const *beta,
    in_type_ *c,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_, mutable_vector_of<in_type_> output_type_>
requires (!requires(a_type_ const &tensor) { tensor.rank(); })
status_t blend(
    a_type_ const & a,
    b_type_ const & b,
    typename in_type_::scale_t alpha,
    typename in_type_::scale_t beta,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise cᵢ = α × aᵢ + β × bᵢ, failing like the concept add.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t blend(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    tensor_span<value_type_, max_rank_> output) noexcept;

Blend: each output is α times the left operand plus β times the right operand.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> blend(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    allocator_type_ alloc = {}) noexcept;

Allocating blend: each result is α times the left operand plus β times the right operand; unexpected_dimensions_k when the operands disagree, empty for empty ones, or the allocation's or the kernel's failure.

Parameters

ainFirst input vector
binSecond input vector
dinNumber of dimensions in input vectors
alphainWeight coefficient of a
betainWeight coefficient of b
coutOutput vector
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
fmaElementwise FMA: outᵢ = α × aᵢ × bᵢ + β × cᵢ
each.hpp:261 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t fma(
    in_type_ const *a,
    in_type_ const *b,
    in_type_ const *c,
    std::size_t d,
    typename in_type_::scale_t const *alpha,
    typename in_type_::scale_t const *beta,
    in_type_ *out,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_, vector_of<in_type_> c_type_, mutable_vector_of<in_type_> output_type_>
requires (!requires(a_type_ const &tensor) { tensor.rank(); })
status_t fma(
    a_type_ const & a,
    b_type_ const & b,
    c_type_ const & c,
    typename in_type_::scale_t alpha,
    typename in_type_::scale_t beta,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise outᵢ = α × aᵢ × bᵢ + β × cᵢ, failing like the concept add.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t fma(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    tensor_view<value_type_, max_rank_> addend,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    tensor_span<value_type_, max_rank_> output) noexcept;

FMA: each output is α times the product of both operands plus β times the addend.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> fma(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    tensor_view<value_type_, max_rank_> addend,
    typename value_type_::scale_t alpha,
    typename value_type_::scale_t beta,
    allocator_type_ alloc = {}) noexcept;

Allocating FMA: each result is α times the product of both operands plus β times the addend; fails like the allocating blend.

Parameters

ainFirst input vector
binSecond input vector
cinThird input vector
dinNumber of dimensions in input vectors
alphainCoefficient of the product
betainCoefficient of c
outoutOutput vector
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
swigluFused SwiGLU: yᵢ = silu(gateᵢ · gate_scale) · upᵢ · output_scale.
each.hpp:353 ↗
template <numeric_dtype in_type_>
status_t swiglu(
    in_type_ const *gate,
    in_type_ const *up,
    in_type_ *y,
    std::size_t rows,
    std::size_t columns,
    std::size_t gate_stride,
    std::size_t up_stride,
    std::size_t y_stride,
    f32_t gate_scale = 1.0f,
    f32_t output_scale = 1.0f,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype value_type_>
status_t swiglu(
    matrix_view<value_type_> gate,
    matrix_view<value_type_> up,
    matrix_span<value_type_> output,
    f32_t gate_scale = 1.0f,
    f32_t output_scale = 1.0f) noexcept;

Fused SwiGLU over [rows,columns] matrices into a matching output span — up empty means SiLU; unexpected_dimensions_k when the shapes disagree.

template <numeric_dtype value_type_, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, 2>> swiglu(
    matrix_view<value_type_> gate,
    matrix_view<value_type_> up,
    f32_t gate_scale = 1.0f,
    f32_t output_scale = 1.0f,
    allocator_type_ alloc = {}) noexcept;

Allocating SwiGLU returning a fresh matrix — up empty means SiLU; empty for an empty gate, or the allocation's or the kernel's failure.

With a null up this reduces to plain SiLU.

Parameters

gateinGate input, shape [rows,columns]
upinUp input, same shape as gate; nullptr collapses to plain SiLU
youtOutput, same shape and dtype as gate; may alias gate
rowsinLogical row count
columnsinLogical column count
gate_strideinRow stride of gate in bytes
up_strideinRow stride of up in bytes
y_strideinRow stride of y in bytes
gate_scaleinScalar applied to each loaded gate element, the E4M3 descale or 1.0
output_scaleinScalar applied to each result before it is stored
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
rmsnormGrouped RMSNorm: yᵢ = xᵢ · rsqrt(mean(x²) + epsilon) · gammaᵢ
each.hpp:413 ↗
template <numeric_dtype in_type_>
status_t rmsnorm(
    in_type_ const *x,
    f32_t const *gamma,
    in_type_ *y,
    std::size_t rows,
    std::size_t groups,
    std::size_t columns,
    std::size_t x_stride,
    std::size_t y_stride,
    f32_t epsilon,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype value_type_>
status_t rmsnorm(
    matrix_view<value_type_> input,
    vector_view<f32_t> gamma,
    matrix_span<value_type_> output,
    std::size_t groups,
    f32_t epsilon) noexcept;

Grouped RMSNorm over a matrix of rows rows, groups groups and columns columns, into a matching output span; unexpected_dimensions_k when the shapes, the groups or gamma disagree with each other.

template <numeric_dtype value_type_, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, 2>> rmsnorm(
    matrix_view<value_type_> input,
    vector_view<f32_t> gamma,
    std::size_t groups,
    f32_t epsilon,
    allocator_type_ alloc = {}) noexcept;

Allocating grouped RMSNorm returning a fresh matrix, empty for an empty input, or the allocation's or the kernel's failure.

Each row holds groups independent columns-vectors, normalized separately.

Parameters

xinInput matrix, shaped [rows,groups,columns], each group packed contiguously
gammainPer-column gain, length columns, shared by groups; nullptr is unit scale.
youtOutput matrix, same shape and dtype as x; may alias x
rowsinLogical row count
groupsinLogical group count
columnsinLogical column count
x_strideinRow (outer) stride of x in bytes
y_strideinRow (outer) stride of y in bytes
epsiloninVariance epsilon added before the reciprocal square root
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
subElementwise subtraction: each output is the left operand minus the right operand.
each.hpp:765 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t sub(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    tensor_span<value_type_, max_rank_> output) noexcept;
template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> sub(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    allocator_type_ alloc = {}) noexcept;

Allocating elementwise sub; fails like the allocating blend.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t sub(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise sub scalar: output[i] = input[i] − scalar.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> sub(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    allocator_type_ alloc = {}) noexcept;

Allocating sub scalar; fails like the allocating scale.

mulElementwise multiplication: each output is the product of the two operands.
each.hpp:815 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t mul(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    tensor_span<value_type_, max_rank_> output) noexcept;
template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> mul(
    tensor_view<value_type_, max_rank_> lhs,
    tensor_view<value_type_, max_rank_> rhs,
    allocator_type_ alloc = {}) noexcept;

Allocating elementwise multiply; fails like the allocating blend.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t mul(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise multiply by scalar: output[i] = input[i] × scalar.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> mul(
    tensor_view<value_type_, max_rank_> input,
    typename value_type_::scale_t scalar,
    allocator_type_ alloc = {}) noexcept;

Allocating multiply by scalar; fails like the allocating scale.

reduce_momentsComputes sum and sum of squares in a single pass: sum = Σ dataᵢ, sumsq = Σ dataᵢ².
reduce.hpp:38 ↗
template <numeric_dtype in_type_, numeric_dtype sum_type_ = typename in_type_::reduce_moments_sum_t, numeric_dtype sumsq_type_ = typename in_type_::reduce_moments_sumsq_t>
status_t reduce_moments(
    in_type_ const *data,
    std::size_t count,
    std::size_t stride,
    sum_type_ *sum,
    sumsq_type_ *sumsq,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, numeric_dtype sum_type_ = typename in_type_::reduce_moments_sum_t, numeric_dtype sumsq_type_ = typename in_type_::reduce_moments_sumsq_t, vector_of<in_type_> input_type_>
expected<moments_result<sum_type_, sumsq_type_>> reduce_moments(
    input_type_ const & input,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Σxᵢ and Σxᵢ² over one run of in_type_; unexpected_dimensions_k for a strided run or one ending mid-value.

Parameters

datainInput array.
countinCounts dimensions, a multiple of the values per byte.
strideinStride between elements in bytes, sizeof(in_type_) for contiguous.
sumoutOutput sum.
sumsqoutOutput sum of squares.
capabilitiesinCapabilities to pick from, or zero for the C++ template.
streaminNull on the CPU, or the stream of the device capabilities describes.
reduce_minmaxFind minimum and maximum elements with their indices in a single pass.
reduce.hpp:152 ↗
template <numeric_dtype in_type_, numeric_dtype minmax_type_ = typename in_type_::reduce_minmax_value_t>
status_t reduce_minmax(
    in_type_ const *data,
    std::size_t count,
    std::size_t stride,
    minmax_type_ *min_value,
    std::size_t *min_index,
    minmax_type_ *max_value,
    std::size_t *max_index,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, numeric_dtype minmax_type_ = typename in_type_::reduce_minmax_value_t, vector_of<in_type_> input_type_>
expected<minmax_result<minmax_type_>> reduce_minmax(
    input_type_ const & input,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Minimum and maximum, with their indices, over one run of in_type_; unexpected_dimensions_k for a strided run or one ending mid-value, and NUMKONG_SIZE_MAX indices when every value is NaN, which no minimum or maximum can index.

Parameters

datainInput array
countinCounts dimensions, a multiple of the values per byte.
strideinStride between elements in bytes (use sizeof(in_type_) for contiguous)
min_valueoutOutput minimum value
min_indexoutOutput index of minimum value, NUMKONG_SIZE_MAX if every value is NaN
max_valueoutOutput maximum value
max_indexoutOutput index of maximum value, NUMKONG_SIZE_MAX if every value is NaN
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
momentsCompute Σxᵢ and Σxᵢ² in a single pass.
reduce.hpp:527 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
moments_result<typename value_type_::reduce_moments_sum_t, typename value_type_::reduce_moments_sumsq_t> moments(
    tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
moments_result<typename value_type_::reduce_moments_sum_t, typename value_type_::reduce_moments_sumsq_t> moments(
    vector_view<value_type_> input) noexcept;

Compute Σxᵢ and Σxᵢ² over a vector view, strided ones included.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<typename value_type_::reduce_moments_sum_t>>
expected<moments_result<tensor<typename value_type_::reduce_moments_sum_t, allocator_type_, max_rank_>, tensor<typename value_type_::reduce_moments_sumsq_t, typename std::allocator_traits<allocator_type_>::template rebind_alloc<typename value_type_::reduce_moments_sumsq_t>, max_rank_>>> moments(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Moments along an axis, Σxᵢ and Σxᵢ² per slice; fails like the axis sum.

Returns zeroed result for empty tensors.

minmaxFind min and max values with their flat indices.
reduce.hpp:566 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
minmax_result<typename value_type_::reduce_minmax_value_t> minmax(
    tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
minmax_result<typename value_type_::reduce_minmax_value_t> minmax(
    vector_view<value_type_> input) noexcept;

Find min and max values with their indices over a vector view, strided ones included.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<typename value_type_::reduce_minmax_value_t>>
expected<minmax_result<tensor<typename value_type_::reduce_minmax_value_t, allocator_type_, max_rank_>>> minmax(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Min and max along an axis; fails like the axis sum.

sumΣ of all elements.
reduce.hpp:615 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
value_type_::reduce_moments_sum_t sum(
    tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
value_type_::reduce_moments_sum_t sum(
    vector_view<value_type_> input) noexcept;

Σ of all elements in a vector view.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<typename value_type_::reduce_moments_sum_t>>
expected<tensor<typename value_type_::reduce_moments_sum_t, allocator_type_, max_rank_>> sum(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Σ along a single axis; empty for an empty input, unexpected_dimensions_k for an axis past the rank, misaligned_k for an unsupported layout, or the allocation's failure.

minFind the minimum element value.
reduce.hpp:621 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
value_type_::reduce_minmax_value_t min(
    tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
value_type_::reduce_minmax_value_t min(
    vector_view<value_type_> input) noexcept;

Find the minimum element value in a vector view.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<typename value_type_::reduce_minmax_value_t>>
expected<tensor<typename value_type_::reduce_minmax_value_t, allocator_type_, max_rank_>> min(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Min along an axis; fails like the axis minmax.

maxFind the maximum element value.
reduce.hpp:627 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
value_type_::reduce_minmax_value_t max(
    tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
value_type_::reduce_minmax_value_t max(
    vector_view<value_type_> input) noexcept;

Find the maximum element value in a vector view.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<typename value_type_::reduce_minmax_value_t>>
expected<tensor<typename value_type_::reduce_minmax_value_t, allocator_type_, max_rank_>> max(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Max along an axis; fails like the axis minmax.

argminIndex of the minimum element, flat.
reduce.hpp:633 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
std::size_t argmin(tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
std::size_t argmin(vector_view<value_type_> input) noexcept;

Index of the minimum element in a vector view.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<std::size_t>>
expected<tensor<std::size_t, allocator_type_, max_rank_>> argmin(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Argmin along an axis; fails like the axis sum, and with missing_kernel_k for sub-byte inputs.

argmaxIndex of the maximum element, flat.
reduce.hpp:639 ↗
template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
std::size_t argmax(tensor_view<value_type_, max_rank_> input) noexcept;
template <numeric_dtype value_type_>
std::size_t argmax(vector_view<value_type_> input) noexcept;

Index of the maximum element in a vector view.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<std::size_t>>
expected<tensor<std::size_t, allocator_type_, max_rank_>> argmax(
    tensor_view<value_type_, max_rank_> input,
    std::size_t axis,
    keep_dims_t keep_dims = collapse_dims_k,
    allocator_type_ alloc = {}) noexcept;

Argmax along an axis; fails like argmin.

popcountPopulation count of a packed bit tensor.
reduce.hpp:735 ↗
template <std::size_t max_rank_ = 8>
u64_t popcount(tensor_view<u1x8_t, max_rank_> input) noexcept;
u64_t popcount(vector_view<u1x8_t> input) noexcept;

Population count over a 1D bit-vector view.

Wraps nk_reduce_moments_u1_best via sum; returns 0 for empty inputs.

any_setTrue if any bit of the packed bit tensor is set.
reduce.hpp:742 ↗
template <std::size_t max_rank_ = 8>
bool any_set(tensor_view<u1x8_t, max_rank_> input) noexcept;
bool any_set(vector_view<u1x8_t> input) noexcept;

True if any bit of the 1D bit-vector view is set.

Suffixed _set to avoid colliding with the all_t and all slice marker in vector.hpp.

none_setTrue if no bit of the packed bit tensor is set.
reduce.hpp:748 ↗
template <std::size_t max_rank_ = 8>
bool none_set(tensor_view<u1x8_t, max_rank_> input) noexcept;
bool none_set(vector_view<u1x8_t> input) noexcept;

True if no bit of the 1D bit-vector view is set.

all_setTrue if every bit of the packed bit tensor is set.
reduce.hpp:754 ↗
template <std::size_t max_rank_ = 8>
bool all_set(tensor_view<u1x8_t, max_rank_> input) noexcept;
bool all_set(vector_view<u1x8_t> input) noexcept;

True if every bit of the 1D bit-vector view is set.

sinArray sine: outᵢ = sin(inᵢ).
trigonometry.hpp:31 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t sin(
    in_type_ const *in,
    std::size_t n,
    in_type_ *out,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> input_type_, mutable_vector_of<in_type_> output_type_>
status_t sin(
    input_type_ const & input,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise sin of one run into another of equal dimensions; unexpected_dimensions_k when they differ or either run is strided or ends mid-value.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t sin(
    tensor_view<value_type_, max_rank_> input,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise sin into pre-allocated output.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> sin(
    tensor_view<value_type_, max_rank_> input,
    allocator_type_ alloc = {}) noexcept;

Allocating sin; empty for an empty input, or the allocation's or the kernel's failure.

Parameters

ininInput array
ninNumber of elements
outoutOutput array
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
cosArray cosine: outᵢ = cos(inᵢ).
trigonometry.hpp:59 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t cos(
    in_type_ const *in,
    std::size_t n,
    in_type_ *out,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> input_type_, mutable_vector_of<in_type_> output_type_>
status_t cos(
    input_type_ const & input,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise cos of one run into another, failing like the concept sin.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t cos(
    tensor_view<value_type_, max_rank_> input,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise cos into pre-allocated output.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> cos(
    tensor_view<value_type_, max_rank_> input,
    allocator_type_ alloc = {}) noexcept;

Allocating cos; empty for an empty input, or the allocation's or the kernel's failure.

Parameters

ininInput array
ninNumber of elements
outoutOutput array
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
atanArray arctangent: outᵢ = arctan(inᵢ).
trigonometry.hpp:87 ↗
template <numeric_dtype in_type_, numeric_dtype precision_type_ = in_type_>
status_t atan(
    in_type_ const *in,
    std::size_t n,
    in_type_ *out,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
template <numeric_dtype in_type_, vector_of<in_type_> input_type_, mutable_vector_of<in_type_> output_type_>
status_t atan(
    input_type_ const & input,
    output_type_ && output,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;

Elementwise atan of one run into another, failing like the concept sin.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8>
status_t atan(
    tensor_view<value_type_, max_rank_> input,
    tensor_span<value_type_, max_rank_> output) noexcept;

Elementwise atan into pre-allocated output.

template <numeric_dtype value_type_, std::size_t max_rank_ = 8, typename allocator_type_ = aligned_allocator<value_type_>>
expected<tensor<value_type_, allocator_type_, max_rank_>> atan(
    tensor_view<value_type_, max_rank_> input,
    allocator_type_ alloc = {}) noexcept;

Allocating atan; empty for an empty input, or the allocation's or the kernel's failure.

Parameters

ininInput array
ninNumber of elements
outoutOutput array
capabilitiesinCapabilities to pick from, or zero for the C++ template
streaminNull on the CPU, or the stream of the device capabilities describes
fmaFMA helper template for baseline dot-product implementations.
types.hpp:6987 ↗
template <typename in_type_, typename accumulator_type_>
requires (dimensions_per_value<in_type_>() == 1)
accumulator_type_ fma(
    in_type_ a,
    in_type_ b,
    accumulator_type_ acc) noexcept;
template <typename accumulator_type_>
accumulator_type_ fma(
    i4x2_t a,
    i4x2_t b,
    accumulator_type_ acc) noexcept;

FMA specialization for i4x2_t, signed 4-bit packed pairs.

template <typename accumulator_type_>
accumulator_type_ fma(
    u4x2_t a,
    u4x2_t b,
    accumulator_type_ acc) noexcept;

FMA specialization for u4x2_t, unsigned 4-bit packed pairs.

template <typename accumulator_type_>
accumulator_type_ fma(
    e2m1x2_t a,
    e2m1x2_t b,
    accumulator_type_ acc) noexcept;

FMA specialization for e2m1x2_t, FP4 packed pairs; both nibble products are exact in f32.

template <typename accumulator_type_>
accumulator_type_ fma(
    u1x8_t a,
    u1x8_t b,
    accumulator_type_ acc) noexcept;

FMA specialization for u1x8_t, 8 packed bits.

Counts matching set bits, popcount of AND.