Krita Source Code Documentation
Loading...
Searching...
No Matches
xsimd_generic.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef KIS_XSIMD_GENERIC_HPP
8#define KIS_XSIMD_GENERIC_HPP
9
11
12#include <array>
13#include <type_traits>
14
15namespace xsimd
16{
17/***********************
18 * Truncate-initialize *
19 ***********************/
20
21template<typename V, typename T, typename A>
22inline batch<T, A> truncate_to_type(xsimd::batch<T, A> const &self) noexcept
23{
25 [](float i) -> float {
26 if (std::numeric_limits<V>::min() > i) {
27 return 0;
28 } else if (std::numeric_limits<V>::max() < i) {
29 return 0;
30 } else {
31 return static_cast<V>(i);
32 }
33 },
34 self);
35}
36
37// Mask to 0 elements of a vector.
38template<typename T, typename A>
39inline auto set_zero(const batch<T, A> &src, const batch_bool<T, A> &mask) noexcept
40{
41 return xsimd::select(mask, xsimd::batch<T, A>(0), src);
42}
43
44// Mask to 1 elements of a vector.
45template<typename T, typename A>
46inline auto set_one(const batch<T, A> &src, const batch_bool<T, A> &mask) noexcept
47{
48 return xsimd::select(mask, xsimd::batch<T, A>(1), src);
49}
50
51/**********************************
52 * Sign-extending unaligned loads *
53 **********************************/
54
55// Load `T::size` values from the array of `T2` elements.
56template<typename T, typename T2>
57inline T load_and_extend(const T2 *src) noexcept
58{
60 [&](size_t i, typename T::value_type) {
61 return static_cast<typename T::value_type>(src[i]);
62 },
63 T{});
64}
65
66/*************************************************
67 * Type-inferred, auto-aligned memory allocation *
68 *************************************************/
69
70// Allocate size bytes of memory aligned to `batch<T, A>::alignment()`.
71template<typename T, typename A>
72inline T *aligned_malloc(size_t size) noexcept
73{
74 using T_v = batch<T, A>;
75
76 return reinterpret_cast<T *>(xsimd::aligned_malloc(size, T_v::arch_type::alignment()));
77}
78
79// Return the maximum of a list of templated values at compile time.
80template<size_t value, size_t... values>
81constexpr typename std::enable_if<sizeof...(values) == 0, size_t>::type max()
82{
83 return value;
84}
85
86// Return the maximum of a list of templated values at compile time.
87template<size_t value, size_t... values>
88constexpr typename std::enable_if<sizeof...(values) != 0, size_t>::type max()
89{
90 return std::max(value, max<values...>());
91}
92
93// Allocate memory for `sz` T items, aligned to the selected architecture's
94// alignment.
95template<typename T, typename A>
96inline T *vector_aligned_malloc(size_t sz) noexcept
97{
98 return static_cast<T *>(xsimd::aligned_malloc(sz * sizeof(T), A::alignment()));
99}
100
101// Free allocated memory, hiding the `const_cast` if necessary.
102template<typename T>
103inline void vector_aligned_free(const T *ptr) noexcept
104{
105 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
106 return xsimd::aligned_free(const_cast<T *>(ptr));
107}
108
109/****************
110 * Interleaving *
111 ****************/
112
113// Return the tuple of interleaved batches `a` and `b`.
114// First element is the low half, second is the upper half.
115template<typename V>
116inline std::pair<V, V> interleave(const V &a, const V &b) noexcept
117{
118 return {xsimd::zip_lo(a, b), xsimd::zip_hi(a, b)};
119}
120
121/**********************
122 * Quadratic function *
123 **********************/
124
125template<typename T, typename A>
126inline batch<T, A> pow2 (batch<T, A> const& self) noexcept
127{
128 return self * self;
129}
130
131#if XSIMD_VERSION_MAJOR <= 10
132
133template <class B, class T, class A>
134inline batch<B, A> bitwise_cast_compat(batch<T, A> const& x) noexcept
135{
136 return bitwise_cast<batch<B, A>>(x);
137}
138
139#else
140
141template <class B, class T, class A>
142inline batch<B, A> bitwise_cast_compat(batch<T, A> const& x) noexcept
143{
144 return bitwise_cast<B>(x);
145}
146
147
148#endif
149
150}; // namespace xsimd
151
152#endif
float value(const T *src, size_t ch)
batch< T, A > apply_with_index_and_value(F &&func, batch< T, A > const &self) noexcept
batch< T, A > apply_with_value(F &&func, batch< T, A > const &self) noexcept
std::pair< V, V > interleave(const V &a, const V &b) noexcept
T * vector_aligned_malloc(size_t sz) noexcept
auto set_one(const batch< T, A > &src, const batch_bool< T, A > &mask) noexcept
batch< T, A > pow2(batch< T, A > const &self) noexcept
auto set_zero(const batch< T, A > &src, const batch_bool< T, A > &mask) noexcept
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()
void vector_aligned_free(const T *ptr) noexcept
T * aligned_malloc(size_t size) noexcept
batch< T, A > truncate_to_type(xsimd::batch< T, A > const &self) noexcept
batch< B, A > bitwise_cast_compat(batch< T, A > const &x) noexcept
T load_and_extend(const T2 *src) noexcept