Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
TensorMeta.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_TENSOR_TENSOR_META_H
12#define EIGEN_TENSOR_TENSOR_META_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
19template <bool cond>
20struct Cond {};
21
22template <typename T1, typename T2>
23constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const T1& choose(Cond<true>, const T1& first, const T2&) {
24 return first;
25}
26
27template <typename T1, typename T2>
28constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const T2& choose(Cond<false>, const T1&, const T2& second) {
29 return second;
30}
31
32template <size_t n>
33struct max_n_1 {
34 static constexpr size_t size = n;
35};
36template <>
37struct max_n_1<0> {
38 static constexpr size_t size = 1;
39};
40
41template <typename T>
42EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE constexpr T divup(const T x, const T y) {
43 return Eigen::numext::div_ceil(x, y);
44}
45
46// Default packet types
47template <typename Scalar, typename Device>
48struct PacketType : internal::packet_traits<Scalar> {
49 typedef typename internal::packet_traits<Scalar>::type type;
50};
51
52// For CUDA packet types when using a GpuDevice
53#if defined(EIGEN_USE_GPU) && defined(EIGEN_GPU_COMPILE_PHASE)
54
55typedef ulonglong2 Packet4h2;
56template <>
57struct PacketType<half, GpuDevice> {
58 typedef Packet4h2 type;
59 static constexpr int size = 8;
60 enum {
61 HasAdd = 1,
62 HasSub = 1,
63 HasMul = 1,
64 HasNegate = 1,
65 HasAbs = 1,
66 HasArg = 0,
67 HasAbs2 = 0,
68 HasMin = 1,
69 HasMax = 1,
70 HasConj = 0,
71 HasSetLinear = 0,
72 HasBlend = 0,
73
74 HasDiv = 1,
75 HasSqrt = 1,
76 HasRsqrt = 1,
77 HasExp = 1,
78 HasExpm1 = 0,
79 HasLog = 1,
80 HasLog1p = 0,
81 HasLog10 = 0,
82 HasPow = 1,
83 };
84};
85#endif
86
87#if defined(EIGEN_USE_SYCL)
88
89namespace TensorSycl {
90namespace internal {
91
92template <typename Index, Index A, Index B>
93struct PlusOp {
94 static constexpr Index Value = A + B;
95};
96
97template <typename Index, Index A, Index B>
98struct DivOp {
99 static constexpr Index Value = A / B;
100};
101
102template <typename Index, Index start, Index end, Index step, template <class Indx, Indx...> class StepOp>
103struct static_for {
104 template <typename UnaryOperator>
105 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void loop(UnaryOperator op) {
106 op(start);
107 static_for<Index, StepOp<Index, start, step>::Value, end, step, StepOp>::loop(op);
108 }
109};
110template <typename Index, Index end, Index step, template <class Indx, Indx...> class StepOp>
111struct static_for<Index, end, end, step, StepOp> {
112 template <typename UnaryOperator>
113 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void loop(UnaryOperator) {}
114};
115
116template <typename OutScalar, typename Device, bool Vectorizable>
117struct Vectorise {
118 static constexpr int PacketSize = 1;
119 typedef OutScalar PacketReturnType;
120};
121
122template <typename OutScalar, typename Device>
123struct Vectorise<OutScalar, Device, true> {
124 static constexpr int PacketSize = Eigen::PacketType<OutScalar, Device>::size;
125 typedef typename Eigen::PacketType<OutScalar, Device>::type PacketReturnType;
126};
127
128static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Index roundUp(Index x, Index y) { return ((((x) + (y)-1) / (y)) * (y)); }
129
130} // namespace internal
131} // namespace TensorSycl
132
133template <>
134struct PacketType<half, SyclDevice> {
135 typedef half type;
136 static constexpr int size = 1;
137 enum {
138 HasAdd = 0,
139 HasSub = 0,
140 HasMul = 0,
141 HasNegate = 0,
142 HasAbs = 0,
143 HasArg = 0,
144 HasAbs2 = 0,
145 HasMin = 0,
146 HasMax = 0,
147 HasConj = 0,
148 HasSetLinear = 0,
149 HasBlend = 0
150 };
151};
152template <typename Scalar>
153struct PacketType<Scalar, SyclDevice> : internal::default_packet_traits {
154 typedef Scalar type;
155 typedef Scalar half;
156 enum {
157 Vectorizable = 0,
158 size = 1,
159 AlignedOnScalar = 0,
160 };
161 enum {
162 HasAdd = 0,
163 HasSub = 0,
164 HasMul = 0,
165 HasNegate = 0,
166 HasAbs = 0,
167 HasAbs2 = 0,
168 HasMin = 0,
169 HasMax = 0,
170 HasConj = 0,
171 HasSetLinear = 0
172 };
173};
174
175template <typename Scalar>
176struct PacketType<Scalar, const SyclDevice> : PacketType<Scalar, SyclDevice> {};
177
178#ifndef EIGEN_DONT_VECTORIZE_SYCL
179#define PACKET_TYPE(CVQual, Type, val, lengths, DEV) \
180 template <> \
181 struct PacketType<CVQual Type, DEV> : internal::sycl_packet_traits<val, lengths> { \
182 typedef typename internal::packet_traits<Type>::type type; \
183 typedef typename internal::packet_traits<Type>::half half; \
184 };
185
186PACKET_TYPE(const, float, 1, 4, SyclDevice)
187PACKET_TYPE(, float, 1, 4, SyclDevice)
188PACKET_TYPE(const, float, 1, 4, const SyclDevice)
189PACKET_TYPE(, float, 1, 4, const SyclDevice)
190
191PACKET_TYPE(const, double, 0, 2, SyclDevice)
192PACKET_TYPE(, double, 0, 2, SyclDevice)
193PACKET_TYPE(const, double, 0, 2, const SyclDevice)
194PACKET_TYPE(, double, 0, 2, const SyclDevice)
195#undef PACKET_TYPE
196
197template <>
198struct PacketType<half, const SyclDevice> : PacketType<half, SyclDevice> {};
199template <>
200struct PacketType<const half, const SyclDevice> : PacketType<half, SyclDevice> {};
201#endif
202#endif
203
204// Pair mimics std::pair but works on e.g. nvcc.
205template <typename U, typename V>
206struct Pair {
207 public:
208 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
209
210 U first{};
211 V second{};
212
213 typedef U first_type;
214 typedef V second_type;
215
216 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Pair() = default;
217
218 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Pair(const U& f, const V& s) : first(f), second(s) {}
219
220 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(Pair& rhs) {
221 using numext::swap;
222 swap(first, rhs.first);
223 swap(second, rhs.second);
224 }
225};
226
227template <typename U, typename V>
228constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator==(const Pair<U, V>& x, const Pair<U, V>& y) {
229 return x.first == y.first && x.second == y.second;
230}
231
232template <typename U, typename V>
233constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator!=(const Pair<U, V>& x, const Pair<U, V>& y) {
234 return !(x == y);
235}
236
237// Can't use std::pairs on cuda devices
238template <typename Idx>
239struct IndexPair {
240 constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair() = default;
241 constexpr EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE IndexPair(Idx f, Idx s) : first(f), second(s) {}
242
243 EIGEN_DEVICE_FUNC void set(IndexPair<Idx> val) {
244 first = val.first;
245 second = val.second;
246 }
247
248 Idx first = Idx(0);
249 Idx second = Idx(0);
250};
251
252namespace internal {
253
254template <typename IndexType, typename Index, Index First, Index... Is>
255constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array<Index, 1 + sizeof...(Is)> customIndices2Array(
256 IndexType& idx, std::integer_sequence<Index, First, Is...>) {
257 return {static_cast<Index>(idx[First]), static_cast<Index>(idx[Is])...};
258}
259template <typename IndexType, typename Index>
260constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array<Index, 0> customIndices2Array(IndexType&,
261 std::integer_sequence<Index>) {
262 return array<Index, 0>();
263}
264
266template <typename Index, std::size_t NumIndices, typename IndexType>
267constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array<Index, NumIndices> customIndices2Array(IndexType& idx) {
268 return customIndices2Array(idx, std::make_integer_sequence<Index, NumIndices>{});
269}
270
278template <typename Index, typename T,
279 std::enable_if_t<std::is_integral<T>::value && std::is_integral<Index>::value, bool> = true>
280constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool index_fits(T index) {
281 return static_cast<T>(static_cast<Index>(index)) == index &&
282 (numext::signbit(static_cast<Index>(index)) == Index(0)) == (numext::signbit(index) == T(0));
283}
284
285template <typename Index, typename T,
286 std::enable_if_t<!(std::is_integral<T>::value && std::is_integral<Index>::value), bool> = true>
287constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool index_fits(const T&) {
288 return true;
289}
290
292template <typename Index, typename... IndexTypes>
293constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool indices_fit(IndexTypes... indices) {
294 return all(index_fits<Index>(indices)...);
295}
296
297} // namespace internal
298
299} // namespace Eigen
300
301#endif // EIGEN_TENSOR_TENSOR_META_H
Namespace containing all symbols from the Eigen library.