CNORXZ
Container with Native Operation Routines and Expressions
Loading...
Searching...
No Matches
for.cc.h
Go to the documentation of this file.
1// -*- C++ -*-
12#ifndef __cxz_for_cc_h__
13#define __cxz_for_cc_h__
14
15#include <omp.h>
16
17#include "for.h"
18
19namespace CNORXZ
20{
21
22 /*=========+
23 | For |
24 +=========*/
25
26 template <SizeT L, class Xpr, class F>
27 constexpr For<L,Xpr,F>::For(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f) :
28 mSize(size),
29 mId(id),
30 mXpr(xpr),
31 mExt(mXpr.rootSteps(mId)),
32 mF(f)
33 {}
34
35 template <SizeT L, class Xpr, class F>
36 template <class PosT>
37 inline decltype(auto) For<L,Xpr,F>::operator()(const PosT& last) const
38 {
39 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
40 for(SizeT i = 0; i != mSize; ++i){
41 const auto pos = last + mExt( UPos(i) );
42 mXpr(pos);
43 }
44 return None {};
45 }
46 else {
47 typedef typename
48 std::remove_reference<decltype(mXpr(last + mExt( UPos(0) )))>::type OutT;
49 auto o = OutT();
50 for(SizeT i = 0; i != mSize; ++i){
51 const auto pos = last + mExt( UPos(i) );
52 mF(o, mXpr(pos));
53 }
54 return o;
55 }
56 }
57
58 template <SizeT L, class Xpr, class F>
59 inline decltype(auto) For<L,Xpr,F>::operator()() const
60 {
61 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
62 for(SizeT i = 0; i != mSize; ++i){
63 const auto pos = mExt( UPos(i) );
64 mXpr(pos);
65 }
66 return None {};
67 }
68 else {
69 typedef typename std::remove_reference<decltype(mXpr(mExt( UPos(0) )))>::type OutT;
70 auto o = OutT();
71 for(SizeT i = 0; i != mSize; ++i){
72 const auto pos = mExt( UPos(i) );
73 mF(o, mXpr(pos));
74 }
75 return o;
76 }
77 }
78
79 template <SizeT L, class Xpr, class F>
80 template <SizeT I>
81 inline decltype(auto) For<L,Xpr,F>::rootSteps(const IndexId<I>& id) const
82 {
83 return mXpr.rootSteps(id);
84 }
85
86 /*======================+
87 | For (non-member) |
88 +======================*/
89
90 template <SizeT L, class Xpr, class F>
91 constexpr decltype(auto) mkFor(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f)
92 {
93 return For<L,Xpr,F>(size, id, xpr, std::forward<F>(f));
94 }
95
96 template <SizeT L, class Xpr>
97 constexpr decltype(auto) mkFor(SizeT size, const IndexId<L>& id, const Xpr& xpr)
98 {
99 return For<L,Xpr>(size, id, xpr, NoF {});
100 }
101
102 /*==========+
103 | SFor |
104 +==========*/
105
106 template <SizeT N, SizeT L, class Xpr, class F>
107 constexpr SFor<N,L,Xpr,F>::SFor(const IndexId<L>& id, const Xpr& xpr, F&& f) :
108 mId(id),
109 mXpr(xpr),
110 mExt(mXpr.rootSteps(mId)),
111 mF(f)
112 {}
113
114 template <SizeT N, SizeT L, class Xpr, class F>
115 template <class PosT>
116 constexpr decltype(auto) SFor<N,L,Xpr,F>::operator()(const PosT& last) const
117 {
118 if constexpr(std::is_same<F,NoF>::value){
119 exec2<0>(last);
120 return None {};
121 }
122 else {
123 return exec<0>(last);
124 }
125 }
126
127 template <SizeT N, SizeT L, class Xpr, class F>
128 constexpr decltype(auto) SFor<N,L,Xpr,F>::operator()() const
129 {
130 if constexpr(std::is_same<F,NoF>::value){
131 exec2<0>();
132 return None {};
133 }
134 else {
135 return exec<0>();
136 }
137 }
138
139 template <SizeT N, SizeT L, class Xpr, class F>
140 template <SizeT I>
141 constexpr decltype(auto) SFor<N,L,Xpr,F>::rootSteps(const IndexId<I>& id) const
142 {
143 return mXpr.rootSteps(id);
144 }
145
146 template <SizeT N, SizeT L, class Xpr, class F>
147 template <SizeT I, class PosT>
148 constexpr decltype(auto) SFor<N,L,Xpr,F>::exec(const PosT& last) const
149 {
150 constexpr SPos<I> i;
151 const auto pos = last + mExt( i );
152 if constexpr(I < N-1){
153 return mF(mXpr(pos),exec<I+1>(last));
154 }
155 else {
156 return mXpr(pos);
157 }
158 }
159
160 template <SizeT N, SizeT L, class Xpr, class F>
161 template <SizeT I>
162 constexpr decltype(auto) SFor<N,L,Xpr,F>::exec() const
163 {
164 constexpr SPos<I> i;
165 const auto pos = mExt( i );
166 if constexpr(I < N-1){
167 return mF(mXpr(pos),exec<I+1>());
168 }
169 else {
170 return mXpr(pos);
171 }
172 }
173
174 template <SizeT N, SizeT L, class Xpr, class F>
175 template <SizeT I, class PosT>
176 inline void SFor<N,L,Xpr,F>::exec2(const PosT& last) const
177 {
178 constexpr SPos<I> i;
179 const auto pos = last + mExt( i );
180 if constexpr(I < N-1){
181 mXpr(pos);
183 }
184 else {
185 mXpr(pos);
186 }
187 return;
188 }
189
190 template <SizeT N, SizeT L, class Xpr, class F>
191 template <SizeT I>
192 inline void SFor<N,L,Xpr,F>::exec2() const
193 {
194 constexpr SPos<I> i;
195 const auto pos = mExt( i );
196 if constexpr(I < N-1){
197 mXpr(pos);
198 exec2<I+1>();
199 }
200 else {
201 mXpr(pos);
202 }
203 return;
204 }
205
206 /*=======================+
207 | SFor (non-member) |
208 +=======================*/
209
210 template <SizeT N, SizeT L, class Xpr, class F>
211 constexpr decltype(auto) mkSFor(const IndexId<L>& id, const Xpr& xpr, F&& f)
212 {
213 return SFor<N,L,Xpr,F>(id, xpr, std::forward<F>(f));
214 }
215
216 template <SizeT N, SizeT L, class Xpr>
217 constexpr decltype(auto) mkSFor(const IndexId<L>& id, const Xpr& xpr)
218 {
219 return SFor<N,L,Xpr>(id, xpr, NoF {});
220 }
221
222 /*==========+
223 | PFor |
224 +==========*/
225
226 template <SizeT L1, SizeT L2, class Xpr, class F>
228 const SizeT* map, const Xpr& xpr, F&& f) :
229 mSize(size),
230 mId1(id1),
231 mId2(id2),
232 mXpr(xpr),
233 mExt1(mXpr.rootSteps(mId1)),
234 mExt2(mXpr.rootSteps(mId2)),
235 mPart(1, map),
236 mF(f)
237 {}
238
239 template <SizeT L1, SizeT L2, class Xpr, class F>
240 template <class PosT>
241 inline decltype(auto) PFor<L1,L2,Xpr,F>::operator()(const PosT& last) const
242 {
243 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
244 for(SizeT i = 0; i != mSize; ++i){
245 const auto pos1 = last + mExt1( UPos(i) );
246 const auto pos2 = pos1 + mExt2( mPart( UPos(i) ) );
247 mXpr(pos2);
248 }
249 return None {};
250 }
251 else {
252 typedef typename
253 std::remove_reference<decltype(mXpr((last + mExt1( UPos(0) )) + mExt2( mPart( UPos(0) ) )))>::type OutT;
254 auto o = OutT();
255 for(SizeT i = 0; i != mSize; ++i){
256 const auto pos1 = last + mExt1( UPos(i) );
257 const auto pos2 = pos1 + mExt2( mPart( UPos(i) ) );
258 mF(o, mXpr(pos2));
259 }
260 return o;
261 }
262 }
263
264 template <SizeT L1, SizeT L2, class Xpr, class F>
265 inline decltype(auto) PFor<L1,L2,Xpr,F>::operator()() const
266 {
267 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
268 for(SizeT i = 0; i != mSize; ++i){
269 const auto pos1 = mExt1( UPos(i) );
270 const auto pos2 = pos1 + mExt2( mPart( UPos(i) ) );
271 mXpr(pos2);
272 }
273 return None {};
274 }
275 else {
276 typedef typename std::remove_reference<decltype(mXpr(mExt1( UPos(0) ) + mExt2( mPart( UPos(0) ) )))>::type OutT;
277 auto o = OutT();
278 for(SizeT i = 0; i != mSize; ++i){
279 const auto pos1 = mExt1( UPos(i) );
280 const auto pos2 = pos1 + mExt2( mPart( UPos(i) ) );
281 mF(o, mXpr(pos2));
282 }
283 return o;
284 }
285 }
286
287 template <SizeT L1, SizeT L2, class Xpr, class F>
288 template <SizeT I>
289 inline decltype(auto) PFor<L1,L2,Xpr,F>::rootSteps(const IndexId<I>& id) const
290 {
291 return mXpr.rootSteps(id);
292 }
293
294 /*=======================+
295 | PFor (non-member) |
296 +=======================*/
297
298 template <SizeT L1, SizeT L2, class Xpr, class F>
299 constexpr decltype(auto) mkPFor(SizeT size, const IndexId<L1>& id1, const IndexId<L2>& id2,
300 const Xpr& xpr, F&& f)
301 {
302 return PFor<L1,L2,Xpr,F>(size, id1, id2, xpr, std::forward<F>(f));
303 }
304
305 template <SizeT L1, SizeT L2, class Xpr, class F>
306 constexpr decltype(auto) mkPFor(SizeT size, const IndexId<L1>& id1, const IndexId<L2>& id2,
307 const Xpr& xpr)
308 {
309 return PFor<L1,L2,Xpr>(size, id1, id2, xpr, NoF {});
310 }
311
312 /*==========+
313 | TFor |
314 +==========*/
315
316 template <SizeT L, class Xpr, class F>
317 constexpr TFor<L,Xpr,F>::TFor(SizeT size, const IndexId<L>& id, const Xpr& xpr, F&& f) :
318 mSize(size),
319 mId(id),
320 mXpr(xpr),
321 mExt(mXpr.rootSteps(mId)),
322 mF(f)
323 {
324 // check for write access!!!
325 /*
326 if constexpr(is_static_pos_type<PosT>::value){
327 static_assert(step.val() != 0, "step has to be non-zero for TPos");
328 }
329 CXZ_ASSERT(step.val() != 0, "step has to be non-zero for TPos");
330 */
331 }
332
333 template <SizeT L, class Xpr, class F>
334 template <class PosT>
335 inline decltype(auto) TFor<L,Xpr,F>::operator()(const PosT& last) const
336 {
337 typedef typename std::remove_reference<decltype(mXpr(last + mExt( UPos(0) )))>::type OutT;
338 int i = 0;
339 const int size = static_cast<int>(mSize);
341 if constexpr(not std::is_same<F,ZeroF>::value){
342 // replace if statement by "does s.th. non-trivial"
343 ov.resize(mSize);
344 }
345#pragma omp parallel private(i)
346 {
347 auto xpr = mXpr;
348#pragma omp for
349 for(i = 0; i < size; i++){
350 const auto pos = last + mExt( UPos(i) );
351 xpr(pos);
352 }
353 }
354 OutT o;
355 if constexpr(not std::is_same<F,ZeroF>::value){
356 // replace if statement by "does s.th. non-trivial"
357 for(SizeT i = 0; i != mSize; ++i){
358 mF(o, ov[i]);
359 }
360 }
361 return o;
362 }
363
364 template <SizeT L, class Xpr, class F>
365 inline decltype(auto) TFor<L,Xpr,F>::operator()() const
366 {
367 typedef typename std::remove_reference<decltype(mXpr(mExt( UPos(0) )))>::type OutT;
368 int i = 0;
369 const int size = static_cast<int>(mSize);
371 if constexpr(not std::is_same<F,ZeroF>::value){
372 // replace if statement by "does s.th. non-trivial"
373 ov.resize(mSize);
374 }
375#pragma omp parallel private(i)
376 {
377 auto xpr = mXpr;
378#pragma omp for
379 for(i = 0; i < size; i++){
380 const auto pos = mExt( UPos(i) );
381 xpr(pos);
382 }
383 }
384 OutT o;
385 if constexpr(not std::is_same<F,ZeroF>::value){
386 // replace if statement by "does s.th. non-trivial"
387 for(SizeT i = 0; i != mSize; ++i){
388 mF(o, ov[i]);
389 }
390 }
391 return o;
392 }
393
394 template <SizeT L, class Xpr, class F>
395 template <SizeT I>
396 inline decltype(auto) TFor<L,Xpr,F>::rootSteps(const IndexId<I>& id) const
397 {
398 return mXpr.rootSteps(id);
399 }
400
401
402 /*==========+
403 | EFor |
404 +==========*/
405
406 template <SizeT N, SizeT L, class Xpr, class F>
407 constexpr EFor<N,L,Xpr,F>::EFor(const IndexId<L>& id, const Xpr& xpr, F&& f) :
408 mId(id),
409 mXpr(xpr),
410 mExt(mXpr.rootSteps(mId)),
411 mF(std::forward<F>(f))
412 {}
413
414 template <SizeT N, SizeT L, class Xpr, class F>
415 template <class PosT>
416 constexpr decltype(auto) EFor<N,L,Xpr,F>::operator()(const PosT& last) const
417 {
418 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
419 const auto pos = mkEPos<N>(last, mExt);
420 mXpr(pos);
421 return None {};
422 }
423 else {
424 typedef typename
425 std::remove_reference<decltype(mXpr(mkEPos<N>(SPos<0>(), mExt)))>::type OutT;
426 auto o = OutT();
427 const auto pos = mkEPos<N>(last, mExt);
428 mF(o, mXpr(pos));
429 return o;
430 }
431 }
432
433 template <SizeT N, SizeT L, class Xpr, class F>
434 constexpr decltype(auto) EFor<N,L,Xpr,F>::operator()() const
435 {
436 if constexpr(std::is_same<typename std::remove_reference<F>::type,NoF>::value){
437 const auto pos = mkEPos<N>(SPos<0>(), mExt);
438 mXpr(pos);
439 return None {};
440 }
441 else {
442 typedef typename
443 std::remove_reference<decltype(mXpr(mkEPos<N>(SPos<0>(), mExt)))>::type OutT;
444 auto o = OutT();
445 const auto pos = mkEPos<N>(SPos<0>(), mExt);
446 mF(o, mXpr(pos));
447 return o;
448 }
449 }
450
451 template <SizeT N, SizeT L, class Xpr, class F>
452 template <SizeT I>
453 constexpr decltype(auto) EFor<N,L,Xpr,F>::rootSteps(const IndexId<I>& id) const
454 {
455 return mXpr.rootSteps(id);
456 }
457}
458
459#endif
constexpr EFor(const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:407
constexpr decltype(auto) rootSteps(const IndexId< I > &id) const
decltype(auto) rootSteps(const IndexId< I > &id) const
Definition for.cc.h:81
constexpr For(SizeT size, const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:27
constexpr PFor(SizeT size, const IndexId< L1 > &id1, const IndexId< L2 > &id2, const SizeT *map, const Xpr &xpr, F &&f)
Definition for.cc.h:227
decltype(auto) rootSteps(const IndexId< I > &id) const
Definition for.cc.h:289
constexpr SFor(const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:107
constexpr decltype(auto) rootSteps(const IndexId< I > &id) const
decltype(auto) rootSteps(const IndexId< I > &id) const
Definition for.cc.h:396
constexpr TFor(SizeT size, const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:317
For expressions declarations.
constexpr decltype(auto) mkPFor(SizeT size, const IndexId< L1 > &id1, const IndexId< L2 > &id2, const Xpr &xpr, F &&f)
Definition for.cc.h:299
constexpr decltype(auto) mkSFor(const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:211
uint64_t SizeT
Definition types.h:38
std::vector< T, Allocator< T > > Vector
Definition types.h:310
decltype(auto) xpr(const Sptr< I > &i)
Sptr< Range > rangeCast(const RangePtr r)
constexpr decltype(auto) mkFor(SizeT size, const IndexId< L > &id, const Xpr &xpr, F &&f)
Definition for.cc.h:91