CoDiPack  3.1.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
openMPReverseAtomic.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2026 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <type_traits>
38
39#include "../../../expressions/activeType.hpp"
40#include "../../../traits/atomicTraits.hpp"
41#include "../../../traits/gradientTraits.hpp"
42#include "../../../traits/realTraits.hpp"
43#include "../../../traits/tapeTraits.hpp"
44#include "../reverseAtomicInterface.hpp"
45#include "macros.hpp"
46
48namespace codi {
49
61 template<typename T_Type, typename T_Sfinae = void>
62 struct OpenMPReverseAtomicImpl : public ReverseAtomicInterface<T_Type, OpenMPReverseAtomicImpl<T_Type, T_Sfinae>> {
63 public:
64 using Type = T_Type;
65
68 };
69
70#ifndef DOXYGEN_DISABLE
71
72 // Specialization for arithmetic types.
73 template<typename T_Type>
74 struct OpenMPReverseAtomicImpl<T_Type, typename std::enable_if<std::is_arithmetic<T_Type>::value>::type>
76 T_Type, OpenMPReverseAtomicImpl<T_Type, typename std::enable_if<std::is_arithmetic<T_Type>::value>::type>> {
77 public:
78 using Type = T_Type;
79 using Base = ReverseAtomicInterface<
81
82 private:
83 Type value;
84
85 public:
86 CODI_INLINE OpenMPReverseAtomicImpl() : Base(), value() {}
87
88 CODI_INLINE OpenMPReverseAtomicImpl(OpenMPReverseAtomicImpl const& other) : Base(), value(other.value) {}
89
90 CODI_INLINE OpenMPReverseAtomicImpl(Type const& other) : Base(), value(other) {}
91
93 return operator=(other.value);
94 }
95
97 this->value = other;
98 return *this;
99 }
100
102 operator+=(other.value);
103 }
104
105 CODI_INLINE void operator+=(Type const& other) {
106 CODI_OMP_ATOMIC(update)
107 this->value += other;
108 }
109
110 CODI_INLINE operator Type() const {
111 return value;
112 }
113 };
114
115 // Specialization for vector mode, that is, T_Type == Direction<...>. Acts on vector components with individual
116 // atomic operations.
117 template<typename T_Type>
119 : public ReverseAtomicInterface<T_Type,
120 OpenMPReverseAtomicImpl<T_Type, GradientTraits::EnableIfDirection<T_Type>>>,
121 public T_Type {
122 public:
123 using Type = T_Type;
124 using Base =
125 ReverseAtomicInterface<T_Type, OpenMPReverseAtomicImpl<T_Type, GradientTraits::EnableIfDirection<T_Type>>>;
126 using Real = typename Type::Real;
127 using AtomicReal = OpenMPReverseAtomicImpl<Real>;
128
130
131 CODI_INLINE OpenMPReverseAtomicImpl(OpenMPReverseAtomicImpl const& other) : Base(), Type(other) {}
132
133 CODI_INLINE OpenMPReverseAtomicImpl(Type const& other) : Base(), Type(other) {}
134
136 return operator=(static_cast<Type const&>(other));
137 }
138
140 Type::operator=(other);
141 return *this;
142 }
143
145 operator+=(static_cast<Type const&>(other));
146 }
147
148 CODI_INLINE void operator+=(Type const& other) {
149 AtomicReal* atomicVector = reinterpret_cast<AtomicReal*>(this->vector);
150 for (size_t i = 0; i < Type::dim; ++i) {
151 atomicVector[i] += other[i];
152 }
153 }
154
155 CODI_INLINE operator Type() const {
156 return static_cast<Type>(*this);
157 }
158 };
159
160 // Specialization for forward CoDiPack types. Acts on value and gradient with individual atomic operations.
161 template<typename T_Type>
162 struct OpenMPReverseAtomicImpl<T_Type, TapeTraits::EnableIfForwardTape<typename T_Type::Tape>>
163 : public ReverseAtomicInterface<
164 T_Type, OpenMPReverseAtomicImpl<T_Type, TapeTraits::EnableIfForwardTape<typename T_Type::Tape>>>,
165 public T_Type {
166 public:
167 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
168 using Base = ReverseAtomicInterface<
170 using Tape = typename Type::Tape;
171 using Real = typename Type::Real;
172 using Gradient = typename Type::Gradient;
173
175
176 CODI_INLINE OpenMPReverseAtomicImpl(OpenMPReverseAtomicImpl const& other) : Base(), Type(other) {}
177
178 CODI_INLINE OpenMPReverseAtomicImpl(Type const& other) : Base(), Type(other) {}
179
181 return operator=(static_cast<Type const&>(other));
182 }
183
185 Type::operator=(other);
186 return *this;
187 }
188
190 operator+=(static_cast<Type const&>(other));
191 }
192
193 CODI_INLINE void operator+=(Type const& other) {
194 OpenMPReverseAtomicImpl<Real>* atomicValue = reinterpret_cast<OpenMPReverseAtomicImpl<Real>*>(&this->value());
195 OpenMPReverseAtomicImpl<Gradient>* atomicGradient =
196 reinterpret_cast<OpenMPReverseAtomicImpl<Gradient>*>(&this->gradient());
197
198 *atomicValue += other.value();
199 *atomicGradient += other.gradient();
200 }
201
202 CODI_INLINE operator Type() const {
203 return static_cast<Type>(*this);
204 }
205 };
206
207#endif
208
211 template<typename Type>
213
215 template<typename T_Type>
216 struct AtomicTraits::IsAtomic<OpenMPReverseAtomic<T_Type>> : std::true_type {};
217
218#ifndef DOXYGEN_DISABLE
219 // Specialize IsDirection for OpenMPReverseAtomic on directions.
220 template<typename T_Type>
222 typename GradientTraits::EnableIfDirection<T_Type>> : std::true_type {};
223
224 // Specialize IsTotalZero for OpenMPReverseAtomic on arithmetic types.
225 template<typename T_Type>
227 OpenMPReverseAtomicImpl<T_Type, typename std::enable_if<std::is_arithmetic<T_Type>::value>::type>> {
228 public:
229
230 using Type = CODI_DD(
231 CODI_T(OpenMPReverseAtomicImpl<T_Type, typename std::enable_if<std::is_arithmetic<T_Type>::value>::type>),
233
234 static CODI_INLINE bool isTotalZero(Type const& v) {
235 return typename Type::Type() == v;
236 }
237 };
238#endif
239}
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:469
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:97
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition macros.hpp:117
typename GradientImplementation< AdjointVector >::Gradient Gradient
Deduce the entry type from an adjoint vector type, usually identical to the gradient type of a tape.
Definition adjointVectorTraits.hpp:92
Definition gradientTraits.hpp:52
typename TraitsImplementation< Gradient >::Real Real
The base value used in the gradient entries.
Definition gradientTraits.hpp:92
typename std::enable_if< IsDirection< Gradient >::value >::type EnableIfDirection
Enable if wrapper for EnableIfDirection.
Definition gradientTraits.hpp:142
Definition tapeTraits.hpp:63
typename std::enable_if< IsForwardTape< Tape >::value >::type EnableIfForwardTape
Enable if wrapper for IsForwardTape.
Definition tapeTraits.hpp:91
CoDiPack - Code Differentiation Package.
Definition codi.hpp:97
OpenMPReverseAtomicImpl< Type > OpenMPReverseAtomic
Definition openMPReverseAtomic.hpp:212
Indicate whether a type is atomic.
Definition atomicTraits.hpp:51
If the expression inherits from Direction. Is either std::false_type or std::true_type.
Definition gradientTraits.hpp:127
Reverse atomic implementation for OpenMP.
Definition openMPReverseAtomic.hpp:62
T_Type Type
See OpenMPReverseAtomicImpl.
Definition openMPReverseAtomic.hpp:64
Function for checking if the value of the type is completely zero.
Definition realTraits.hpp:106
T_Type Type
See IsTotalZero.
Definition realTraits.hpp:109
static inlinebool isTotalZero(Type const &v)
Checks if the values are completely zero.
Definition realTraits.hpp:112
Provides a data type on which += update operations are performed atomically.
Definition reverseAtomicInterface.hpp:60