11#ifndef EIGEN_REDUCTIONS_CLANG_H
12#define EIGEN_REDUCTIONS_CLANG_H
15#include "../../InternalHeaderCheck.h"
24#if EIGEN_HAS_BUILTIN(__builtin_reduce_min) && EIGEN_HAS_BUILTIN(__builtin_reduce_max)
25#define EIGEN_CLANG_PACKET_REDUX_MINMAX_INT(PACKET_TYPE) \
27 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_min(const PACKET_TYPE& a) { \
28 return __builtin_reduce_min(a); \
31 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_max(const PACKET_TYPE& a) { \
32 return __builtin_reduce_max(a); \
35EIGEN_CLANG_PACKET_REDUX_MINMAX_INT(PacketXi)
36EIGEN_CLANG_PACKET_REDUX_MINMAX_INT(PacketXl)
37#undef EIGEN_CLANG_PACKET_REDUX_MINMAX_INT
40#if EIGEN_HAS_BUILTIN(__builtin_reduce_or)
43#define EIGEN_CLANG_PACKET_REDUX_ANY(PACKET_TYPE) \
45 EIGEN_STRONG_INLINE bool predux_any(const PACKET_TYPE& a) { \
46 return __builtin_reduce_or(reinterpret_cast<detail::signed_vector_t<PACKET_TYPE>>(a) != 0) != 0; \
49EIGEN_CLANG_PACKET_REDUX_ANY(PacketXf)
50EIGEN_CLANG_PACKET_REDUX_ANY(PacketXd)
51EIGEN_CLANG_PACKET_REDUX_ANY(PacketXi)
52EIGEN_CLANG_PACKET_REDUX_ANY(PacketXl)
53#undef EIGEN_CLANG_PACKET_REDUX_ANY
56#if EIGEN_HAS_BUILTIN(__builtin_reduce_add) && EIGEN_HAS_BUILTIN(__builtin_reduce_mul)
57#define EIGEN_CLANG_PACKET_REDUX_INT(PACKET_TYPE) \
59 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux<PACKET_TYPE>(const PACKET_TYPE& a) { \
60 return __builtin_reduce_add(a); \
63 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_mul<PACKET_TYPE>(const PACKET_TYPE& a) { \
64 return __builtin_reduce_mul(a); \
68EIGEN_CLANG_PACKET_REDUX_INT(PacketXi)
69EIGEN_CLANG_PACKET_REDUX_INT(PacketXl)
70#undef EIGEN_CLANG_PACKET_REDUX_INT
73#if EIGEN_HAS_BUILTIN(__builtin_shufflevector)
85struct halving_reduce {
86 template <
typename VectorT,
typename Op, std::size_t... Is>
87 static EIGEN_STRONG_INLINE scalar_pair_t<VectorT> fold(
const VectorT& a, Op op, std::index_sequence<Is...>) {
88 return halving_reduce<N / 2>::run(
89 op(__builtin_shufflevector(a, a, Is...), __builtin_shufflevector(a, a, (
sizeof...(Is) + Is)...)), op);
92 template <
typename VectorT,
typename Op>
93 static EIGEN_STRONG_INLINE scalar_pair_t<VectorT> run(
const VectorT& a, Op op) {
94 return fold(a, op, std::make_index_sequence<N / 2>{});
99struct halving_reduce<2> {
100 template <
typename VectorT,
typename Op>
101 static EIGEN_STRONG_INLINE scalar_pair_t<VectorT> run(
const VectorT& a, Op ) {
106template <
typename VectorT>
107EIGEN_STRONG_INLINE scalar_pair_t<VectorT> reduce_add_pairs(
const VectorT& a) {
108 return halving_reduce<vector_elements<VectorT>()>::run(a, [](
const auto& x,
const auto& y) {
return x + y; });
113template <
typename VectorT,
typename Op>
114EIGEN_STRONG_INLINE scalar_type_of_vector_t<VectorT> tree_reduce(
const VectorT& a, Op op) {
115 const scalar_pair_t<VectorT> even_odd = halving_reduce<vector_elements<VectorT>()>::run(a, op);
116 return op(even_odd.first, even_odd.second);
123struct complex_predux_mul {
124 template <
typename RealScalar>
125 static EIGEN_STRONG_INLINE std::complex<RealScalar> run(
const complex_packet_wrapper<RealScalar, N>& a) {
126 using HalfPacket = complex_packet_wrapper<RealScalar, N / 2>;
127 return complex_predux_mul<N / 2>::run(complex_pmul_impl(HalfPacket(lower_half(a.v)), HalfPacket(upper_half(a.v)),
128 complex_real_indices<HalfPacket>{}));
133struct complex_predux_mul<2> {
134 template <
typename RealScalar>
135 static EIGEN_STRONG_INLINE std::complex<RealScalar> run(
const complex_packet_wrapper<RealScalar, 2>& a) {
141struct complex_predux_mul<1> {
142 template <
typename RealScalar>
143 static EIGEN_STRONG_INLINE std::complex<RealScalar> run(
const complex_packet_wrapper<RealScalar, 1>& a) {
153#define EIGEN_CLANG_PACKET_REDUX_FLOAT(PACKET_TYPE) \
155 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux<PACKET_TYPE>(const PACKET_TYPE& a) { \
156 return detail::tree_reduce(a, [](const auto& x, const auto& y) { return x + y; }); \
159 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_mul<PACKET_TYPE>(const PACKET_TYPE& a) { \
160 return detail::tree_reduce(a, [](const auto& x, const auto& y) { return x * y; }); \
163EIGEN_CLANG_PACKET_REDUX_FLOAT(PacketXf)
164EIGEN_CLANG_PACKET_REDUX_FLOAT(PacketXd)
165#undef EIGEN_CLANG_PACKET_REDUX_FLOAT
170#define EIGEN_CLANG_PACKET_REDUX_MINMAX_FLOAT(PACKET_TYPE) \
172 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_min(const PACKET_TYPE& a) { \
173 return detail::tree_reduce(a, detail::pmin_op()); \
176 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_max(const PACKET_TYPE& a) { \
177 return detail::tree_reduce(a, detail::pmax_op()); \
180 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_min<PropagateNumbers, PACKET_TYPE>( \
181 const PACKET_TYPE& a) { \
182 return detail::tree_reduce(a, detail::pmin_num_op()); \
185 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_max<PropagateNumbers, PACKET_TYPE>( \
186 const PACKET_TYPE& a) { \
187 return detail::tree_reduce(a, detail::pmax_num_op()); \
190 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_min<PropagateNaN, PACKET_TYPE>(const PACKET_TYPE& a) { \
191 return detail::tree_reduce(a, detail::pmin_nan_op()); \
194 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_max<PropagateNaN, PACKET_TYPE>(const PACKET_TYPE& a) { \
195 return detail::tree_reduce(a, detail::pmax_nan_op()); \
198EIGEN_CLANG_PACKET_REDUX_MINMAX_FLOAT(PacketXf)
199EIGEN_CLANG_PACKET_REDUX_MINMAX_FLOAT(PacketXd)
200#undef EIGEN_CLANG_PACKET_REDUX_MINMAX_FLOAT
205#define EIGEN_CLANG_COMPLEX_REDUX(PACKET_TYPE) \
207 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux<PACKET_TYPE>(const PACKET_TYPE& a) { \
208 const auto re_im = detail::reduce_add_pairs(a.v); \
209 return unpacket_traits<PACKET_TYPE>::type(re_im.first, re_im.second); \
212 EIGEN_STRONG_INLINE unpacket_traits<PACKET_TYPE>::type predux_mul<PACKET_TYPE>(const PACKET_TYPE& a) { \
213 return detail::complex_predux_mul<unpacket_traits<PACKET_TYPE>::size>::run(a); \
216EIGEN_CLANG_COMPLEX_REDUX(PacketXcf)
217EIGEN_CLANG_COMPLEX_REDUX(PacketXcd)
218#undef EIGEN_CLANG_COMPLEX_REDUX