forked from gahansen/Albany
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPHAL_Utilities_Def.hpp
251 lines (236 loc) · 7.44 KB
/
PHAL_Utilities_Def.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
//*****************************************************************//
// Albany 3.0: Copyright 2016 Sandia Corporation //
// This Software is released under the BSD license detailed //
// in the file "license.txt" in the top-level Albany directory //
//*****************************************************************//
#include <Kokkos_DynRankView.hpp>
#include "PHAL_AlbanyTraits.hpp"
#include "PHAL_AlbanyTraits.hpp"
namespace PHAL {
template<typename T>
class MDFieldIterator<T>::PtrT {
typename Ref<T>::type val_;
public:
PtrT (const typename Ref<T>::type& val) : val_(val) {}
typename Ref<T>::type operator* () { return val_; }
// This is why we have to implement a pointer type: operator-> requires a raw
// pointer to end its recursive invocation. val_ holds an object in memory so
// that the pointer remains valid for the duration of it->'s use of it.
typename Ref<T>::type* operator-> () { return &val_; }
};
template<typename T> inline MDFieldIterator<T>::
MDFieldIterator (PHX::MDField<T>& a) : a_(a) {
rank_ = a.rank();
done_ = a.size() == 0;
for (int i = 0; i < rank_; ++i) {
dimsm1_[i] = a.extent(i) - 1;
idxs_[i] = 0;
}
i_ = 0;
}
template<typename T> inline MDFieldIterator<T>&
MDFieldIterator<T>::operator++ () {
for (int i = rank_ - 1; i >= 0; --i)
if (idxs_[i] < dimsm1_[i]) {
++idxs_[i];
for (int j = i+1; j < rank_; ++j) idxs_[j] = 0;
++i_;
return *this;
}
done_ = true;
return *this;
}
template<typename T> inline MDFieldIterator<T>&
MDFieldIterator<T>::operator++ (int) {
MDFieldIterator<T> it(*this);
++(*this);
return *this;
}
template<typename T> inline typename MDFieldIterator<T>::return_type
MDFieldIterator<T>::ref () {
switch (rank_) {
case 1: return a_(idxs_[0]);
case 2: return a_(idxs_[0], idxs_[1]);
case 3: return a_(idxs_[0], idxs_[1], idxs_[2]);
case 4: return a_(idxs_[0], idxs_[1], idxs_[2], idxs_[3]);
case 5: return a_(idxs_[0], idxs_[1], idxs_[2], idxs_[3], idxs_[4]);
default:
TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "not impl'ed");
return a_(0);
}
}
#define dloop(i, dim) for (size_t i = 0; i < a.extent(dim); ++i)
// Runtime MDField.
template<class Functor, typename ScalarT>
void loop (Functor& f, PHX::MDField<ScalarT>& a) {
switch (a.rank()) {
case 1: {
int ctr = 0;
dloop(i, 0) {
f(a(i), ctr);
++ctr;
}
} break;
case 2: {
int ctr = 0;
dloop(i, 0) dloop(j, 1) {
f(a(i,j), ctr);
++ctr;
}
} break;
case 3: {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) {
f(a(i,j,k), ctr);
++ctr;
}
} break;
case 4: {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) dloop(l, 3) {
f(a(i,j,k,l), ctr);
++ctr;
}
} break;
case 5: {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) dloop(l, 3) dloop(m, 4) {
f(a(i,j,k,l,m), ctr);
++ctr;
}
} break;
default:
TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
"dims.size() \notin {1,2,3,4,5}.");
}
}
// Compile-time MDField.
template<class Functor, typename ScalarT>
void loop (Functor& f, const PHX::MDField<ScalarT>& a) {
loop(f, const_cast<PHX::MDField<ScalarT>&>(a));
}
template<class Functor, typename ScalarT, typename T1>
void loop (Functor& f, PHX::MDField<ScalarT, T1>& a) {
int ctr = 0;
dloop(i, 0) {
f(a(i), ctr);
++ctr;
}
}
template<class Functor, typename ScalarT, typename T1>
void loop (Functor& f, const PHX::MDField<ScalarT, T1>& a) {
loop(f, const_cast<const PHX::MDField<ScalarT, T1>&>(a));
}
template<class Functor, typename ScalarT, typename T1, typename T2>
void loop (Functor& f, PHX::MDField<ScalarT, T1, T2>& a) {
int ctr = 0;
dloop(i, 0) dloop(j, 1) {
f(a(i,j), ctr);
++ctr;
}
}
template<class Functor, typename ScalarT, typename T1, typename T2>
void loop (Functor& f, const PHX::MDField<ScalarT, T1, T2>& a) {
loop(f, const_cast<PHX::MDField<ScalarT, T1, T2>&>(a));
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3>
void loop (Functor& f, PHX::MDField<ScalarT, T1, T2, T3>& a) {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) {
f(a(i,j,k), ctr);
++ctr;
}
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3>
void loop (Functor& f, const PHX::MDField<ScalarT, T1, T2, T3>& a) {
loop(f, const_cast<PHX::MDField<ScalarT, T1, T2, T3>&>(a));
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3, typename T4>
void loop (Functor& f, PHX::MDField<ScalarT, T1, T2, T3, T4>& a) {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) dloop(l, 3) {
f(a(i,j,k,l), ctr);
++ctr;
}
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3, typename T4>
void loop (Functor& f, const PHX::MDField<ScalarT, T1, T2, T3, T4>& a) {
loop(f, const_cast<PHX::MDField<ScalarT, T1, T2, T3, T4>&>(a));
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3, typename T4, typename T5>
void loop (Functor& f, PHX::MDField<ScalarT, T1, T2, T3, T4, T5>& a) {
int ctr = 0;
dloop(i, 0) dloop(j, 1) dloop(k, 2) dloop(l, 3) dloop(m, 4) {
f(a(i,j,k,l,m), ctr);
++ctr;
}
}
template<class Functor, typename ScalarT, typename T1, typename T2,
typename T3, typename T4, typename T5>
void loop (Functor& f, const PHX::MDField<ScalarT, T1, T2, T3, T4, T5>& a) {
loop(f, const_cast<PHX::MDField<ScalarT, T1, T2, T3, T4, T5>&>(a));
}
#undef dloop
namespace impl {
template<typename ScalarT, typename T>
struct SetLooper {
typename Ref<const T>::type val;
SetLooper (typename Ref<const T>::type val) : val(val) {}
void operator() (typename Ref<ScalarT>::type a, int) { a = val; }
};
template<typename ScalarT, typename T>
struct ScaleLooper {
typename Ref<const T>::type val;
ScaleLooper (typename Ref<const T>::type val) : val(val) {}
void operator() (typename Ref<ScalarT>::type a, int) { a *= val; }
};
} // namespace impl
//! a(:) = val
template<typename ArrayT, typename T>
void set (ArrayT& a, const T& val) {
impl::SetLooper<typename ArrayT::value_type, T> sl(val);
loop(sl, a);
}
//! a(:) *= val
template<typename ArrayT, typename T>
void scale (ArrayT& a, const T& val) {
impl::ScaleLooper<typename ArrayT::value_type, T> sl(val);
loop(sl, a);
}
template< class T , class ... P >
inline
typename std::enable_if<
!Kokkos::is_dynrankview_fad<Kokkos::DynRankView<T,P...>>::value,
typename Kokkos::DynRankView<T,P...>::non_const_type >::type
create_copy( const std::string& name,
const Kokkos::DynRankView<T,P...> & src )
{
using dst_type = typename Kokkos::DynRankView<T,P...>::non_const_type;
auto layout = Kokkos::Impl::reconstructLayout(src.layout(), src.rank());
return dst_type( name , layout );
}
template< class T , class ... P >
inline
typename std::enable_if<
Kokkos::is_dynrankview_fad<Kokkos::DynRankView<T,P...>>::value,
typename Kokkos::DynRankView<T,P...>::non_const_type >::type
create_copy( const std::string& /* name */,
const Kokkos::DynRankView<T,P...> & src )
{
using Src = Kokkos::DynRankView<T,P...>;
using Dst = typename Kokkos::DynRankView<T,P...>::non_const_type;
auto sm = src.impl_map();
auto sl = sm.layout();
auto fad_rank = src.rank();
sl.dimension[fad_rank] = sm.dimension_scalar();
auto real_rank = fad_rank + 1;
auto ml = Kokkos::Impl::reconstructLayout(sl, real_rank);
auto dst = Dst( src.label(), ml );
return dst;
}
} // namespace PHAL