7#include "argon/argon_full.hpp"
8#include "argon/argon_half.hpp"
9#include "argon/helpers/argon_for.hpp"
10#include "argon/store.hpp"
11#include "argon/vector.hpp"
12#include "arm_simd/helpers/multivector.hpp"
13#include "arm_simd/helpers/scalar.hpp"
15#ifdef __ARM_FEATURE_MVE
21#ifdef ARGON_PLATFORM_SIMDE
24#define ace [[gnu::always_inline]] constexpr
26#define ace [[gnu::always_inline]] inline
36template <
typename T,
typename V>
38 if constexpr (simd::is_quadword_v<V>) {
39 return Argon<T>{simd::reinterpret<typename Argon<T>::vector_type>(in.vec())};
40 }
else if constexpr (simd::is_doubleword_v<V>) {
41 return ArgonHalf<T>{simd::reinterpret<typename ArgonHalf<T>::vector_type>(in.vec())};
50template <
typename argon_type, simd::is_vector_type V>
51ace argon_type reinterpret(V in) {
52 static_assert(!std::is_same_v<typename argon_type::vector_type, V>);
53 return argon_type{simd::reinterpret<typename argon_type::vector_type>(in)};
61template <
typename ScalarType,
typename ArgonType>
62ace ScalarType bit_cast(ArgonType in) {
63 return in.template As<ScalarType>();
73template <
size_t lane,
size_t str
ide,
typename argon_type>
74ace
static std::array<argon_type, stride> load_to_lane_interleaved(
75 simd::MultiVector_t<typename argon_type::vector_type, stride> multi,
76 typename argon_type::scalar_type
const* ptr) {
77 return argon_type::LoadToLaneInterleaved(multi, ptr);
82template <
size_t lane,
size_t str
ide,
typename argon_type>
83ace
static std::array<argon_type, stride> load_to_lane_interleaved(std::array<argon_type, stride> multi,
84 typename argon_type::scalar_type
const* ptr) {
85 return argon_type::LoadToLaneInterleaved(multi, ptr);
95template <
typename argon_type>
96ace std::array<argon_type, 2> zip(argon_type a, argon_type b) {
107template <
typename argon_type>
108ace std::array<argon_type, 2> unzip(argon_type a, argon_type b) {
109 return a.UnzipWith(b);
120template <
typename argon_type>
121ace std::array<argon_type, 2> transpose(argon_type a, argon_type b) {
122 return a.TransposeWith(b);
125#ifndef ARGON_PLATFORM_MVE
132ace Argon<T> combine(ArgonHalf<T> low, ArgonHalf<T> high) {
133 return simd::combine(low, high);
142ace Argon<T> load(
const T* ptr) {
151ace ArgonHalf<T> load_half(
const T* ptr) {
152 return ArgonHalf<T>::Load(ptr);
166template <
typename BranchType,
typename CondType>
168ace Argon<BranchType> ternary(Argon<CondType> condition, Argon<BranchType> true_value, Argon<BranchType> false_value) {
169 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
170 return condition.
vec() ? true_value.
vec() : false_value.
vec();
172 return condition.
Select(true_value, false_value);
176template <
typename BranchType,
typename CondType>
177 requires(
sizeof(CondType) ==
sizeof(BranchType))
178ace BranchType ternary(CondType condition, BranchType true_value, BranchType false_value) {
179 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
180 return condition ? true_value.vec() : false_value.vec();
187template <
typename ValueType,
typename CondType>
188 requires std::is_arithmetic_v<ValueType> &&
190ace Argon<ValueType> ternary(Argon<CondType> condition, ValueType true_value, ValueType false_value) {
191 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
192 return condition.
vec() ? true_value : false_value;
194 return ternary(condition, Argon<ValueType>{true_value}, Argon<ValueType>{false_value});
198template <
typename CondType,
typename ScalarType>
199 requires std::is_arithmetic_v<ScalarType> && std::is_same_v<CondType, typename Argon<ScalarType>::argon_result_type>
200class CondMonad :
public std::pair<CondType, Argon<ScalarType>> {
204 using PairType = std::pair<CondType, ArgonType>;
205 using PairType::PairType;
207 constexpr CondType condition()
const {
return this->first; }
208 constexpr ArgonType value()
const {
return this->second; }
210 CondMonad else_if_(CondType new_condition, ArgonType new_value)
const {
212 new_condition | condition(),
213 (new_condition & ~condition()).Select(new_value, value()),
217 template <
typename FunctionType>
218 CondMonad else_if_(CondType condition, FunctionType func)
const {
219 return else_if_(condition, func());
222 CondMonad else_if_(CondType condition, ScalarType value)
const {
return else_if_(condition, ArgonType{value}); }
224 ArgonType else_(ArgonType new_value)
const {
return condition().Select(new_value, value()); }
226 template <
typename FunctionType>
227 ArgonType else_(FunctionType func)
const {
228 return else_(func());
231 ArgonType else_(ScalarType value)
const {
return else_(ArgonType{value}); }
234template <
typename ScalarType,
typename CondType>
235 requires std::is_arithmetic_v<ScalarType> && std::is_same_v<CondType, typename Argon<ScalarType>::argon_result_type>
237 return {condition, value};
240template <
typename ScalarType,
typename CondType>
241 requires std::is_arithmetic_v<ScalarType> && std::is_same_v<CondType, typename Argon<ScalarType>::argon_result_type>
243 return {condition, value};
246template <
typename FunctionType,
typename CondType>
247 requires std::is_arithmetic_v<decltype(std::declval<FunctionType>()())> &&
248 std::is_same_v<CondType, decltype(std::declval<FunctionType>()())>
250 return {condition, func()};
Definition argon_full.hpp:24
Represents a SIMD vector with various operations.
Definition vector.hpp:50
constexpr VectorType vec() const
Get the underlying SIMD vector.
Definition vector.hpp:268
static ace argon_type Load(const scalar_type *ptr)
Definition vector.hpp:788
helpers::ArgonFor_t< predicate_type > argon_bool_type
Definition vector.hpp:59
ace argon_type Select(ArgType true_value, ArgType false_value) const
Bitwise select between two vectors, using the current vector as a mask.
Definition vector.hpp:1164
typename ArgonFor< std::remove_cv_t< T > >::type ArgonFor_t
Helper alias to get the Argon type for a given vector type.
Definition argon_for.hpp:45