Documentation a537f1bdf2
Loading...
Searching...
No Matches
vector_expressions.hpp
Go to the documentation of this file.
1/*!
2 * \file vector_expressions.hpp
3 * \brief Expression templates for vector types with coefficient-wise operations.
4 * \author P. Gomes
5 * \version 8.5.0 "Harrier"
6 *
7 * SU2 Project Website: https://su2code.github.io
8 *
9 * The SU2 Project is maintained by the SU2 Foundation
10 * (http://su2foundation.org)
11 *
12 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
13 *
14 * SU2 is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * SU2 is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#pragma once
29
30#include "../basic_types/datatype_structure.hpp"
31#include "../code_config.hpp"
32#include <type_traits>
33#include <algorithm>
34#include <cassert>
35#include <cstdlib>
36#include <cmath>
37#include <cstdint>
38
39namespace VecExpr {
40/// \addtogroup VecExpr
41/// @{
42
43/*!
44 * \brief Base vector expression class.
45 * \ingroup BLAS
46 * \param[in] Derived - The class that inherits from this one to use the expressions.
47 * \param[in] Scalar - Associated scalar type, prevents implicit conversions between exprs.
48 * \note Derived classes must implement operator[], and at least operator= with
49 * expressions (that is when they are evaluated). They must also contain a constexpr
50 * boolean "StoreAsRef", indicating whether to store them by value (false) or by
51 * reference (true), when composing expressions.
52 * Expression classes need to be stored by value to allow nested expressions to
53 * propagate correctly (i.e. if "Scalar" has its own expression templates).
54 * Vector classes should be stored by reference to avoid copies, especially if they
55 * allocate memory dynamically.
56 */
57template <class Derived, class Scalar>
58class CVecExpr {
59 public:
60 /*!
61 * \brief Cast the expression to Derived, usually to allow evaluation via operator[].
62 */
63 SU2_CUDA_HOST_DEVICE FORCEINLINE const Derived& derived() const { return static_cast<const Derived&>(*this); }
64
65 // Allowed from C++14, allows nested expression propagation without
66 // manually calling derived() on the expression being evaluated.
67 // FORCEINLINE auto operator[] (size_t i) const { return derived()[i]; }
68};
69
70/*!
71 * \brief Expression class to broadcast a scalar value. Allows implementing
72 * "vector-scalar" operations re-using "vector-vector" expressions.
73 */
74template <class Scalar>
75class Bcast : public CVecExpr<Bcast<Scalar>, Scalar> {
76 Scalar x;
77
78 public:
79 static constexpr bool StoreAsRef = false;
81 SU2_CUDA_HOST_DEVICE FORCEINLINE const Scalar& operator[](size_t) const { return x; }
82};
83
84/*!
85 * \brief std::decay_t from C++14, used to allow implicit conversions
86 * between scalar types, e.g. "CVecExpr<U,double>" + "int/double/etc.".
87 */
88template <class T>
89using decay_t = typename std::decay<T>::type;
90
91/*! \brief std::remove_reference_t from C++14, removes references from some type. */
92template <class T>
93using remove_reference_t = typename std::remove_reference<T>::type;
94
95/*! \brief Mechanism to conditionally (based on "StoreAsRef") add lvalue reference to a type. */
96template <class T, bool>
100template <class T>
101struct add_lref_if<T, true> {
103};
104template <class T>
108template <class T>
110
111/*--- Namespace from which the math function implementations come. ---*/
112
113#if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)
114namespace math = ::codi;
115#else
116namespace math = ::std;
117#endif
118
119/*--- Macro to simplify auto return type deduction in C++11, operator[] needs
120 * it to allow inner expressions to propagate as the outer is evaluated. ---*/
121
122#define RETURNS(...) \
123 ->decltype(__VA_ARGS__) { return __VA_ARGS__; }
124
125/*--- Macro to create expression classes (EXPR) and overloads (FUN) for unary
126 * functions, based on their coefficient-wise implementation (IMPL). ---*/
127
128#define MAKE_UNARY_FUN(FUN, EXPR, IMPL) \
129 /*!--- Expression class. ---*/ \
130 template <class U, class Scalar> \
131 class EXPR : public CVecExpr<EXPR<U, Scalar>, Scalar> { \
132 store_t<const U> u; \
133 \
134 public: \
135 static constexpr bool StoreAsRef = false; \
136 FORCEINLINE EXPR(const U& u_) : u(u_) {} \
137 SU2_CUDA_HOST_DEVICE FORCEINLINE auto operator[](size_t i) const RETURNS(IMPL(u[i])) \
138 }; \
139 /*!--- Function overload, returns an expression object. ---*/ \
140 template <class U, class S> \
141 FORCEINLINE auto FUN(const CVecExpr<U, S>& u) RETURNS(EXPR<U, S>(u.derived()))
142
143#define sign_impl(x) Scalar(1 - 2 * (x < 0))
144MAKE_UNARY_FUN(operator-, minus_, -)
149#undef sign_impl
150
151#undef MAKE_UNARY_FUN
152
153/*--- Macro to create expressions and overloads for binary functions. ---*/
154
155// clang-format off
156#define MAKE_BINARY_FUN(FUN, EXPR, IMPL) \
157 /*!--- Expression class. ---*/ \
158 template <class U, class V, class Scalar> \
159 class EXPR : public CVecExpr<EXPR<U, V, Scalar>, Scalar> { \
160 store_t<const U> u; \
161 store_t<const V> v; \
162 \
163 public: \
164 static constexpr bool StoreAsRef = false; \
165 FORCEINLINE EXPR(const U& u_, const V& v_) : u(u_), v(v_) {} \
166 SU2_CUDA_HOST_DEVICE FORCEINLINE auto operator[](size_t i) const RETURNS(IMPL(u[i], v[i])) \
167 }; \
168 /*!--- Vector with vector function overload. ---*/ \
169 template <class U, class V, class S> \
170 FORCEINLINE auto FUN(const CVecExpr<U, S>& u, const CVecExpr<V, S>& v) \
171 RETURNS(EXPR<U, V, S>(u.derived(), v.derived())) \
172 /*!--- Vector with scalar function overload. ---*/ \
173 template <class U, class S> \
174 FORCEINLINE auto FUN(const CVecExpr<U, S>& u, decay_t<S> v) RETURNS(EXPR<U, Bcast<S>, S>(u.derived(), Bcast<S>(v))) \
175 /*!--- Scalar with vector function overload. ---*/ \
176 template <class S, class V> \
177 FORCEINLINE auto FUN(decay_t<S> u, const CVecExpr<V, S>& v) RETURNS(EXPR<Bcast<S>, V, S>(Bcast<S>(u), v.derived()))
178// clang-format on
179
180/*--- std::max/min have issues (because they return by reference).
181 * fmin and fmax return by value and thus are fine, but they would force
182 * conversions to double, to avoid that we provide integer overloads.
183 * We use int32/64 instead of int/long to avoid issues with Windows,
184 * where long is 32 bits (instead of 64 bits). ---*/
185
186#define MAKE_FMINMAX_OVERLOADS(TYPE) \
187 FORCEINLINE TYPE fmax(TYPE a, TYPE b) { return a < b ? b : a; } \
188 FORCEINLINE TYPE fmin(TYPE a, TYPE b) { return a < b ? a : b; }
193/*--- Make the float and double versions of fmin/max available in this
194 * namespace to avoid ambiguous overloads. ---*/
195using std::fmax;
196using std::fmin;
197#undef MAKE_FMINMAX_OVERLOADS
198
202
203/*--- sts::plus and co. were tried, the code was horrendous (due to the forced
204 * conversion between different types) and creating functions for these ops
205 * requires a lot of boilerplate (template args, auto return, etc.). ---*/
206
207#define add_impl(a, b) a + b
208#define sub_impl(a, b) a - b
209#define mul_impl(a, b) a* b
210#define div_impl(a, b) a / b
215#undef add_impl
216#undef sub_impl
217#undef mul_impl
218#undef div_impl
219
220/*--- Relational operators need to be cast to the scalar type to allow vectorization.
221 * TO_PASSIVE is used to convert active scalars to passive, which CoDi will then capture
222 * by value in its expressions, and thus dangling references are avoided. No AD info
223 * is lost since these operators are non-differentiable. ---*/
224
225#define TO_PASSIVE(IMPL) SU2_TYPE::Passive<Scalar>::Value(IMPL)
226#define le_impl(a, b) TO_PASSIVE(a <= b)
227#define ge_impl(a, b) TO_PASSIVE(a >= b)
228#define eq_impl(a, b) TO_PASSIVE(a == b)
229#define ne_impl(a, b) TO_PASSIVE(a != b)
230#define lt_impl(a, b) TO_PASSIVE(a < b)
231#define gt_impl(a, b) TO_PASSIVE(a > b)
238#undef TO_PASSIVE
239#undef le_impl
240#undef ge_impl
241#undef eq_impl
242#undef ne_impl
243#undef lt_impl
244#undef gt_impl
245
246#undef MAKE_BINARY_FUN
247
248/// @}
249} // namespace VecExpr
CNewtonIntegration::Scalar Scalar
Definition CNewtonIntegration.cpp:31
Expression class to broadcast a scalar value. Allows implementing "vector-scalar" operations re-using...
Definition vector_expressions.hpp:75
Bcast(const Scalar &x_)
Definition vector_expressions.hpp:80
const Scalar & operator[](size_t) const
Definition vector_expressions.hpp:81
static constexpr bool StoreAsRef
Definition vector_expressions.hpp:79
Base vector expression class.
Definition vector_expressions.hpp:58
const Derived & derived() const
Cast the expression to Derived, usually to allow evaluation via operator[].
Definition vector_expressions.hpp:63
Definition vector_expressions.hpp:145
Definition vector_expressions.hpp:211
Definition vector_expressions.hpp:214
Definition vector_expressions.hpp:234
Definition vector_expressions.hpp:146
Definition vector_expressions.hpp:233
Definition vector_expressions.hpp:237
Definition vector_expressions.hpp:232
Definition vector_expressions.hpp:236
Definition vector_expressions.hpp:199
Definition vector_expressions.hpp:200
Definition vector_expressions.hpp:144
Definition vector_expressions.hpp:213
Definition vector_expressions.hpp:235
Definition vector_expressions.hpp:201
Definition vector_expressions.hpp:148
Definition vector_expressions.hpp:147
Definition vector_expressions.hpp:212
#define SU2_CUDA_HOST_DEVICE
Definition code_config.hpp:57
#define FORCEINLINE
Definition code_config.hpp:44
#define eq_impl(a, b)
Definition vector_expressions.hpp:228
auto sqrt(const CVecExpr< U, S > &u) -> decltype(sqrt_< U, S >(u.derived()))
Definition vector_expressions.hpp:147
typename std::decay< T >::type decay_t
std::decay_t from C++14, used to allow implicit conversions between scalar types, e....
Definition vector_expressions.hpp:89
#define mul_impl(a, b)
Definition vector_expressions.hpp:209
#define ne_impl(a, b)
Definition vector_expressions.hpp:229
#define gt_impl(a, b)
Definition vector_expressions.hpp:231
#define lt_impl(a, b)
Definition vector_expressions.hpp:230
#define MAKE_BINARY_FUN(FUN, EXPR, IMPL)
Definition vector_expressions.hpp:156
typename std::remove_reference< T >::type remove_reference_t
std::remove_reference_t from C++14, removes references from some type.
Definition vector_expressions.hpp:93
auto exp(const CVecExpr< U, S > &u) -> decltype(exp_< U, S >(u.derived()))
Definition vector_expressions.hpp:146
#define div_impl(a, b)
Definition vector_expressions.hpp:210
auto sign(const CVecExpr< U, S > &u) -> decltype(sign_< U, S >(u.derived()))
Definition vector_expressions.hpp:148
#define le_impl(a, b)
Definition vector_expressions.hpp:226
#define sub_impl(a, b)
Definition vector_expressions.hpp:208
auto pow(const CVecExpr< U, S > &u, const CVecExpr< V, S > &v) -> decltype(pow_< U, V, S >(u.derived(), v.derived()))
Definition vector_expressions.hpp:201
typename store_type< T >::type store_t
Definition vector_expressions.hpp:109
#define add_impl(a, b)
Definition vector_expressions.hpp:207
#define ge_impl(a, b)
Definition vector_expressions.hpp:227
auto abs(const CVecExpr< U, S > &u) -> decltype(abs_< U, S >(u.derived()))
Definition vector_expressions.hpp:145
#define MAKE_FMINMAX_OVERLOADS(TYPE)
Definition vector_expressions.hpp:186
#define sign_impl(x)
Definition vector_expressions.hpp:143
#define MAKE_UNARY_FUN(FUN, EXPR, IMPL)
Definition vector_expressions.hpp:128
Definition CSysVector.hpp:104
remove_reference_t< T > & type
Definition vector_expressions.hpp:102
Mechanism to conditionally (based on "StoreAsRef") add lvalue reference to a type.
Definition vector_expressions.hpp:97
remove_reference_t< T > type
Definition vector_expressions.hpp:98
Definition vector_expressions.hpp:105
typename add_lref_if< T, T::StoreAsRef >::type type
Definition vector_expressions.hpp:106