OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Assign.hpp
Go to the documentation of this file.
1/***************************************************************************
2 *
3 * The IPPL Framework
4 *
5 ***************************************************************************/
6
8//
9// This file contains the versions of assign() that work with expressions
10// on the RHS. They do not handle general communications, and require
11// sufficient guard cells to cover any stencil-like access.
12//
14
15// include files
16#include "Field/Assign.h"
17#include "Field/AssignDefs.h"
18#include "Field/BareField.h"
21#include "Field/LField.h"
22#include "Message/Communicate.h"
23#include "Message/Message.h"
24#include "Utility/PAssert.h"
25#include "Utility/IpplInfo.h"
26#include "Utility/IpplStats.h"
27
29
30#include <map>
31#include <vector>
32#include <functional>
33#include <utility>
34#include <iostream>
35#include <typeinfo>
36
38//
39// TryCompressLhs.
40//
41// Encodes the logic for whether to compress or uncompress the
42// left hand side given information about the expression.
43//
45
46template<class T, unsigned Dim, class A, class Op>
47bool
48TryCompressLHS(LField<T,Dim>& lf, A& rhs, Op op, const NDIndex<Dim>& domain)
49{
50
51 // just skip this if we can
53 return(false);
54
55 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
56 // defined.
57 ASSIGNMSG(Inform msg("TryCompressLHS", INFORM_ALL_NODES));
58 ASSIGNMSG(msg << "Checking for compressibility of LField with domain = ");
59 ASSIGNMSG(msg << lf.getOwned() << " over assignment domain = " << domain);
60 ASSIGNMSG(msg << endl);
61
62 // If the right hand side is compressed and we are looking at
63 // the whole domain for the lhs, we have a chance of
64 // being able to compress the left hand side.
65 // Then if it is simple assign or if the lhs is already compressed
66 // we can do a compressed assign.
67 bool c1 = for_each(rhs,IsCompressed(),PETE_AndCombiner());
68 bool c2 = domain.containsAllPoints(lf.getOwned());
70 bool c4 = lf.IsCompressed();
71 bool compress = c1 && c2 && ( c3 || c4 );
72
73 ASSIGNMSG(msg << " RHS IsCompressed() = " << c1 << endl);
74 ASSIGNMSG(msg << " LHS IsCompressed() = " << c4 << endl);
75 ASSIGNMSG(msg << "domain.contains(lhs) = " << c2 << endl);
76 ASSIGNMSG(msg << " IsAssign = " << c3 << endl);
77 ASSIGNMSG(msg << " result = " << compress << endl);
78
79 // If we decide it can be compressed, do it, otherwise undo it.
80 if (compress)
81 {
82 // We can compress this, so compress it down using first element
83 // as the compression value.
84 ASSIGNMSG(msg << "Yes we CAN compress, so do so now ... ");
85 lf.Compress();
86 ASSIGNMSG(msg << "now, compressed value = " << *lf.begin() << endl);
87 return true;
88 }
89
90 // We can't compress the LHS. Check if both sides are compressed already
91 // and have the same value, and we're doing assignment (that is, check
92 // if we're trying to assign the same value to a portion of an already
93 // compressed region). Note that if this is true, we know that the op
94 // is for assignment.
95 if (c1 && c3 && c4)
96 {
97 T tmpval{};
98 PETE_apply(op, tmpval, for_each(rhs, EvalFunctor_0()));
99 if (*lf.begin() == tmpval)
100 {
101 // Both sides are compressed, and we're doing assignment, but the
102 // domains don't fully intersect. We can still deal with this as
103 // a compressed entity if the LHS compressed value equals the RHS
104 // compressed value.
105 ASSIGNMSG(msg << "LHS and RHS are compressed, doing assign, and ");
106 ASSIGNMSG(msg << *lf.begin() << " == " <<tmpval<<", so result = 1");
107 ASSIGNMSG(msg << endl);
108 return true;
109 }
110 }
111
112 // OK we need to uncompress the LHS, but we might not need to keep the data.
113 // If we are doing assignment, or are not going to use all of the
114 // LHS domain, we will need to copy the compressed value into the
115 // uncompressed storage. Otherwise, we know we'll just reset all the
116 // values during the upcoming assignment, so it is a waste to do it
117 // now. If the arguments is true, then copy in the compressed value,
118 // if it is false then allocate storage but do not do anything more
119 // now to initialize it.
120 ASSIGNMSG(msg << "No we cannot compress, so make sure we're ");
121 ASSIGNMSG(msg << "uncompressed. Fill domain? " << !(c3&&c2) << endl);
122 lf.Uncompress( !(c3 && c2) );
123 return false;
124}
125
126
128//
129// A class with an interface like BrickIterator
130// that applies the parens operator to some expression of type Expr.
131// It passes most operations to the 'Child' item, but retrieves values
132// by applying operator() to the Child or the Child's returned values.
133// This is used by the version of assign that lets you assign values
134// to just one component of a Field on the LHS.
135//
137
138template<class Expr>
139class ParensIterator : public Expr
140{
141public:
142 typedef typename Expr::PETE_Return_t PETE_Return_t;
143
144 ParensIterator( const Expr& e ) : Expr(e) {}
146 {
147 return (*Expr::Child)(Expr::Value.Arg);
148 }
149 PETE_Return_t& offset(int i) const
150 {
151 return Expr::Child.offset(i)(Expr::Value.Arg);
152 }
153 PETE_Return_t& offset(int i, int j) const
154 {
155 return Expr::Child.offset(i,j)(Expr::Value.Arg);
156 }
157 PETE_Return_t& offset(int i, int j, int k) const
158 {
159 return Expr::Child.offset(i,j,k)(Expr::Value.Arg);
160 }
161
163 {
164 return (*Expr::Child)(Expr::Value.Arg);
165 }
167 {
168 return Expr::Child.offset(i)(Expr::Value.Arg);
169 }
170 PETE_Return_t& offset(int i, int j)
171 {
172 return Expr::Child.offset(i,j)(Expr::Value.Arg);
173 }
174 PETE_Return_t& offset(int i, int j, int k)
175 {
176 return Expr::Child.offset(i,j,k)(Expr::Value.Arg);
177 }
179 {
180 return Expr::Child.unit_offset(i)(Expr::Value.Arg);
181 }
183 {
184 return Expr::Child.unit_offset(i,j)(Expr::Value.Arg);
185 }
186 PETE_Return_t& unit_offset(int i, int j, int k)
187 {
188 return Expr::Child.unit_offset(i,j,k)(Expr::Value.Arg);
189 }
190
191 void step(unsigned d)
192 {
193 Expr::Child.step(d);
194 }
195 void rewind(unsigned d)
196 {
197 Expr::Child.rewind(d);
198 }
199 int size(unsigned d) const
200 {
201 return Expr::Child.size(d);
202 }
203 int done(unsigned d) const
204 {
205 return Expr::Child.done(d);
206 }
207 int Stride(int d) const
208 {
209 return Expr::Child.Stride(d);
210 }
211};
212
213
215//
216// IndexedBareField = expression assignment.
217//
218// This is the specialization with ExprTag<true>, meaning the RHS
219// is an expression, not just a simple IndexedBareField. This version
220// only works if the LHS and RHS terms all agree in their parallel
221// layout within guard-cell tolerances. If they do not, it is
222// an error and IPPL will report it and die.
223// Since this is for IndexedBareField, extra checks are done to
224// make sure you only process the relevant domain, and that you keep
225// track of how you are indexing the values (using plugbase).
226//
228
229template<class T1, unsigned Dim, class RHS, class OP>
230void
232 bool fillGC)
233{
235 const_cast<IndexedBareField<T1,Dim,Dim>&>(aa);
236
237 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
238 // defined.
239 ASSIGNMSG(Inform msg("assign IBF(t)", INFORM_ALL_NODES));
240 ASSIGNMSG(msg << "Computing assignment to IBF[" << aa.getDomain());
241 ASSIGNMSG(msg << "] ..." << endl);
242
243 // First check to see if any of the terms on the rhs
244 // are the field on the lhs. If so we'll have to make temporaries.
245 int lhs_id = a.getBareField().get_Id();
246 typename RHS::Wrapped& bb = b.PETE_unwrap();
247 bool both_sides = for_each(bb,SameFieldID(lhs_id),PETE_OrCombiner());
248
249 // Fill guard cells if necessary
250 ASSIGNMSG(msg << "Checking whether to fill GC's on RHS ..." << endl);
251 for_each(bb, FillGCIfNecessary(a.getBareField()), PETE_NullCombiner());
252
253 // Begin and end iterators for the local fields in the left hand side.
254 typename BareField<T1,Dim>::iterator_if la = a.getBareField().begin_if();
255 typename BareField<T1,Dim>::iterator_if aend = a.getBareField().end_if();
256
257 // Set the dirty flag indicating this field should have guard cells
258 // filled next time if we are doing deferred GC fills, since
259 // we will be modifying at least one LField of this BareField.
260 // We need to set this here so that our compression checks on each
261 // LField take the dirty flag setting into account.
262 a.getBareField().setDirtyFlag();
263
264 // Loop over all the local fields of the left hand side.
265
266 int lfcount=0;
267 bool needFinalCompressCheck = false;
268 while (la != aend)
269 {
270 // The pointer to the current lhs local field.
271 LField<T1,Dim> *lf = (*la).second.get();
272
273 // If it is on the rhs somewhere, make a copy of it.
274 if ( both_sides ) {
275 lf = new LField<T1,Dim>( *lf );
276 ASSIGNMSG(msg << "For lf " << lfcount << ": making lfield copy.");
277 ASSIGNMSG(msg << endl);
278 }
279
280 // Find the local domain.
281 // Intersect with the indexes used to see how much we will actually use.
282 NDIndex<Dim> local_domain = a.getDomain().intersect( lf->getOwned() );
283
284 // If there is something there...
285 if ( ! local_domain.empty() )
286 {
287 // Some typedefs to make the lines shorter...
288 // types for the left hand side, right hand side and
289 // the whole expression.
290 typedef typename LField<T1,Dim>::iterator LHS;
292
293 // First look and see if the arrays are sufficiently aligned
294 // to do this in one shot.
295 // We do this by trying to do a plugBase and seeing if it worked.
296
297 ASSIGNMSG(msg << "For lf " << lfcount << ": plugbase on ");
298 ASSIGNMSG(msg << local_domain << endl);
299 if ( for_each(bb,PlugBase<Dim>( local_domain ), PETE_AndCombiner()) )
300 {
301 ASSIGNMSG(msg << "For lf " << lfcount << " with owned domain ");
302 ASSIGNMSG(msg << lf->getOwned() << " assigned intersection ");
303 ASSIGNMSG(msg << local_domain << " : ");
304
305 if (a.getBareField().compressible() &&
306 TryCompressLHS(*lf,bb,op,local_domain) ) {
307 // Compressed assign.
308 ASSIGNMSG(msg << "compressed assign, changing ");
309 ASSIGNMSG(msg << *(lf->begin()));
310
311 // Just apply the operator to the single compressed value
312 // on the LHS. If we're here, we know the RHS is compressed
313 // so we can just evaluate it at its first position.
314 PETE_apply(op, *(lf->begin()), for_each(bb,EvalFunctor_0()));
315 ASSIGNMSG(msg << " to " << *(lf->begin()) << endl);
316 } else {
317 // Loop assign.
318 ASSIGNMSG(msg << "loop assign." << endl);
319
320 // Create the expression object.
321 ExprT expr(lf->begin(local_domain), bb);
322 expr.apply();
323
324 // Try to compress this LField since we did an uncompressed
325 // assignment, if the user has requested this kind of
326 // check right after computation on the LField. If this
327 // is not selected, then we'll need to do some end-of-loop
328 // compression checks.
330 ASSIGNMSG(msg << "For lf " << lfcount);
331 ASSIGNMSG(msg << ": doing extra post-compute ");
332 ASSIGNMSG(msg << "compression check ..." << endl);
333 lf->TryCompress(a.getBareField().isDirty());
334 } else {
335 needFinalCompressCheck = true;
336 }
337 }
338 }
339 else
340 {
341 ERRORMSG("All Fields in an expression must be aligned. ");
342 ERRORMSG("(Do you have enough guard cells?)" << endl);
343 ERRORMSG("This error occurred while evaluating an expression ");
344 ERRORMSG("for an LField with domain " << lf->getOwned() << endl);
345 Ippl::abort();
346 }
347 }
348
349 // If we had to make a copy of the current LField,
350 // swap the pointers and delete the old memory.
351 if ( both_sides )
352 {
353 ASSIGNMSG(msg << "For lf " << lfcount << ": swapping lfield data.");
354 ASSIGNMSG(msg << endl);
355 ASSIGNMSG(msg << "For lf " << lfcount << ": at beg, lfield=" << *lf);
356 ASSIGNMSG(msg << endl);
357 (*la).second->swapData( *lf );
358 delete lf;
359 ASSIGNMSG(msg << "For lf " << lfcount << ": at end, lfield=");
360 ASSIGNMSG(msg << *((*la).second) << endl);
361 }
362
363 ++la;
364 ++lfcount;
365 }
366
367
368 // If we are not deferring guard cell fills, and we need to do this
369 // now, fill the guard cells. This will also apply any boundary
370 // conditions after the guards have been updated.
371 if (fillGC) {
372 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
373
374 a.getBareField().fillGuardCellsIfNotDirty();
375
376 }
377
378 // Try to compress the result.
379 if (fillGC && needFinalCompressCheck) {
380 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
381 a.getBareField().Compress(); // tjw added fillGC 12/16/1997
382 }
383
384 //INCIPPLSTAT(incExpressions);
385 //INCIPPLSTAT(incIBFEqualsExpression);
386}
387
388
390//
391// ParensExpression = expression assignment.
392//
393// A version of assign() that handles assignment to just a component of
394// a Field that has been selected via operator(). This version
395// only works if the LHS and RHS terms all agree in their parallel
396// layout within guard-cell tolerances. If they do not, it is
397// an error and IPPL will report it and die. The item having operator()
398// applied can be a BareField or an IndexedBareField.
399//
401
402template<class A, class RHS, class OP, class Tag, class TP>
403void
404assign(PETE_TUTree<OpParens<TP>,A> lhs, RHS wrhs, OP op, Tag,
405 bool fillGC)
406{
407
408 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
409 // defined.
410 ASSIGNMSG(Inform msg("assign Parens", INFORM_ALL_NODES));
411 ASSIGNMSG(msg << "Computing assignment to IBF[" << lhs.Child.getDomain());
412 ASSIGNMSG(msg << "](" << lhs.Value.Arg << ") ..." << endl);
413
414 enum { Dim = A::Dim_u };
415 typedef typename A::return_type T1;
416
417 typedef typename Expressionize<RHS>::type::Wrapped RHS_Wrapped;
419 RHS_Wrapped & rhs = expr.PETE_unwrap();
420
421 // Get a reference to the BareField on the left hand side, and the
422 // total domain we are modifying.
423 BareField<T1,Dim>& bare = lhs.Child.getBareField();
424 const NDIndex<Dim> &total_domain = lhs.Child.getDomain();
425
426 // Fill guard cells if necessary
427 ASSIGNMSG(msg << "Checking whether to fill GC's on RHS ..." << endl);
429
430 // Begin and end iterators for the local fields in the left hand side.
431 typename BareField<T1,Dim>::iterator_if la = bare.begin_if();
432 typename BareField<T1,Dim>::iterator_if aend = bare.end_if();
433
434 // Set the dirty flag indicating this field should have guard cells
435 // filled next time if we are doing deferred GC fills.
436 // We need to set this here so that our compression checks on each
437 // LField take the dirty flag setting into account.
438 bare.setDirtyFlag();
439
440 // Loop over all the local fields of the left hand side.
441
442 bool needFinalCompressCheck = false;
443 while (la != aend)
444 {
445 // The pointer to the current lhs local field, and the owned domain.
446 LField<T1,Dim> *lf = (*la).second.get();
447 const NDIndex<Dim> &lo = lf->getOwned();
448
449 // Find the local domain.
450 // Intersect with the indexes used to see how much we will actually use.
451 NDIndex<Dim> local_domain = total_domain.intersect(lo);
452
453 // If there is something there...
454 if (!local_domain.empty())
455 {
456 // Some typedefs to make the lines shorter...
457 // types for the left hand side, right hand side and
458 // the whole expression.
459 typedef typename LField<T1,Dim>::iterator LA;
460 typedef PETE_TUTree<OpParens<TP>,LA> LHS;
461 typedef BrickExpression<Dim,ParensIterator<LHS>,RHS_Wrapped,OP>
462 ExprT;
463
464 // First look and see if the arrays are sufficiently aligned
465 // to do this in one shot.
466 // We do this by trying to do a plugBase and seeing if it worked.
467 ASSIGNMSG(msg << "For lf " << lo << ": plugbase on ");
468 ASSIGNMSG(msg << local_domain << endl);
469 if (for_each(rhs, PlugBase<Dim>(local_domain), PETE_AndCombiner()))
470 {
471 // Check and see if the lhs is already compressed, and if so,
472 // if the RHS is compressed as well. If so, then we can
473 // just do a compressed assign to modify the Nth element
474 // of the compressed value.
475 bool c1 = for_each(rhs, IsCompressed(), PETE_AndCombiner());
476 bool c2 = local_domain.containsAllPoints(lo);
477 bool c3 = lf->IsCompressed();
478 if (bare.compressible() && c1 && c2 && c3) {
479 // We can do a compressed assign, and we know the LHS is
480 // already compressed. So we can just assign to the first
481 // value, which will modify the selected element of that
482 // value.
483 ASSIGNMSG(msg << "Compressed assign on ");
484 ASSIGNMSG(msg << local_domain << ", changing "<< *lf->begin());
485 const ParensIterator<LHS> ilhs = LHS(lhs.Value, lf->begin());
486 PETE_apply(op, *ilhs, for_each(rhs, EvalFunctor_0()));
487 ASSIGNMSG(msg << " to " << *lf->begin() << endl);
488
489 } else {
490 ASSIGNMSG(msg << "Loop assign on " << local_domain << endl);
491
492 // We must uncompress, and since we will only be writing
493 // to a portion of each element, we must definitely fill
494 // the domain with the compressed value if it is currently
495 // compressed.
496 lf->Uncompress();
497
498 // Build an object that will carry out the expression.
499 const ParensIterator<LHS> ilhs =
500 LHS(lhs.Value, lf->begin(local_domain));
501 ExprT expr2(ilhs, rhs, op);
502 expr2.apply();
503
504 // Try to compress this LField right after we've modified it,
505 // if the user wants us to do this now.
507 ASSIGNMSG(msg << "Doing extra post-compute ");
508 ASSIGNMSG(msg << "compression check ..." << endl);
509 lf->TryCompress(bare.isDirty());
510 } else {
511 needFinalCompressCheck = true;
512 }
513 }
514 }
515 else
516 {
517 ERRORMSG("All Fields in an expression must be aligned. ");
518 ERRORMSG("(Do you have enough guard cells?)" << endl);
519 ERRORMSG("This error occurred while evaluating an expression ");
520 ERRORMSG("for an LField with domain ");
521 ERRORMSG((*la).second->getOwned() << endl);
522 Ippl::abort();
523 }
524 }
525 ++la;
526 }
527
528
529 // Fill the guard cells on the left hand side, if we are deferring
530 // this operation until the next time it is needed.
531 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
532 if (fillGC) {
533
535
536 }
537
538 // Compress the LHS.
539 if (fillGC && needFinalCompressCheck) {
540 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
541 bare.Compress();
542 }
543
544 //INCIPPLSTAT(incExpressions);
545 //INCIPPLSTAT(incParensEqualsExpression);
546}
547
548
550//
551// BareField = expression assignment.
552//
553// This is the specialization with ExprTag<true>, meaning the RHS
554// is an expression, not just a simple BareField. This version
555// only works if the LHS and RHS terms all agree in their parallel
556// layout within guard-cell tolerances. If they do not, it is
557// an error and IPPL will report it and die.
558// Since this is for BareField, the entire domain of the LHS is
559// used to index the RHS. The RHS terms cannot be IndexedBareFields,
560// they must be BareFields as well (or other simpler items).
561//
563
564template<class T1, unsigned Dim, class RHS, class OP>
565void
566assign(const BareField<T1,Dim>& ca, RHS b, OP op, ExprTag<true>)
567{
568
569 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
570 // defined.
571 ASSIGNMSG(Inform msg("assign BF(t)", INFORM_ALL_NODES));
572 ASSIGNMSG(msg << "Computing assignment to BF[" << ca.getDomain());
573 ASSIGNMSG(msg << "] ..." << endl);
574
575 // cast away const here for lhs ... unfortunate but necessary.
576 // Also get the item wrapped within the PETE expression.
577 BareField<T1,Dim>& a = const_cast<BareField<T1,Dim>&>(ca);
578 typename RHS::Wrapped& bb = b.PETE_unwrap();
579
580 // Create iterators over the LHS's LFields.
581 typedef typename LField<T1,Dim>::iterator It;
583 typename BareField<T1,Dim>::iterator_if la = a.begin_if();
584 typename BareField<T1,Dim>::iterator_if aend = a.end_if();
585
586 // Set the dirty flag indicating this field should have guard cells
587 // filled next time if we are doing deferred GC fills.
588 // We need to set this here so that our compression checks on each
589 // LField take the dirty flag setting into account.
590 a.setDirtyFlag();
591
592 // Loop over the LHS LFields, and assign from RHS LFields
593
594 int lfcount = 0;
595 bool needFinalCompressCheck = false;
596 while (la != aend)
597 {
598 // Get the current LHS and set up the RHS to point to the beginning
599 // of its current LField. This second step is done in lieu of doing
600 // a "plugbase", since it is faster and we know we're dealing with
601 // a whole BareField here, not an indexed BareField.
602 LField<T1,Dim>& lf = *(*la).second;
604
605 ASSIGNMSG(msg << "For lf " << lfcount << " with domain ");
606 ASSIGNMSG(msg << lf.getOwned() << " : ");
607
608 // Check to see if we can compress here. If so, we can avoid a lot
609 // of work.
610 if (a.compressible() && TryCompressLHS(lf, bb, op, a.getDomain())) {
611 ASSIGNMSG(msg << "compressed assign, changing " << *lf.begin());
612 PETE_apply(op,*lf.begin(),for_each(bb,EvalFunctor_0()));
613 ASSIGNMSG(msg << " to " << *lf.begin() << endl);
614 } else {
615 ASSIGNMSG(msg << "loop assign." << endl);
616
617 // Create the expression object.
618 ExprT expr(lf.begin(),bb,op);
619 expr.apply();
620
621 // Try to compress this LField since we did an uncompressed
622 // assignment, if the user has requested this kind of
623 // check right after computation on the LField. If this kind
624 // of request has not been made, then we'll need to do a compression
625 // check at the end.
627 ASSIGNMSG(msg << "For lf " << lfcount);
628 ASSIGNMSG(msg << ": doing extra post-compute ");
629 ASSIGNMSG(msg << "compression check ..." << endl);
630 lf.TryCompress(a.isDirty());
631 } else {
632 needFinalCompressCheck = true;
633 }
634 }
635
636 ++la;
638 ++lfcount;
639 }
640
641
642 // Fill the guard cells on the left hand side, if we are deferring
643 // this operation until the next time it is needed.
644 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
645
646 a.fillGuardCellsIfNotDirty();
647
648
649 // Compress the LHS, if necessary
650 if (needFinalCompressCheck) {
651 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
652 a.Compress();
653 }
654
655 // Compress the LHS.
656 //INCIPPLSTAT(incExpressions);
657 //INCIPPLSTAT(incBFEqualsExpression);
658}
const unsigned Dim
#define ASSIGNMSG(x)
Definition: Assign.h:28
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
Definition: AssignDefs.h:30
void assign(const IndexedBareField< T1, Dim, Dim > &aa, RHS b, OP op, ExprTag< true >, bool fillGC)
Definition: Assign.hpp:231
bool TryCompressLHS(LField< T, Dim > &lf, A &rhs, Op op, const NDIndex< Dim > &domain)
Definition: Assign.hpp:48
FillGCIfNecessaryTag< D, T1 > FillGCIfNecessary(const BareField< T1, D > &bf)
Definition: AssignTags.h:126
void PETE_apply(const OpPeriodic< T > &, T &a, const T &b)
Definition: BCond.hpp:353
PETE_Combiner< bool, OpOr > PETE_OrCombiner
Definition: PETE.h:468
PETE_Combiner< bool, OpAnd > PETE_AndCombiner
Definition: PETE.h:467
std::complex< double > a
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define INFORM_ALL_NODES
Definition: Inform.h:39
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
constexpr double e
The value of.
Definition: Physics.h:39
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
bool containsAllPoints(const NDIndex< Dim > &b) const
bool empty() const
void setDirtyFlag()
Definition: BareField.h:117
void fillGuardCellsIfNotDirty() const
Definition: BareField.h:122
bool isDirty() const
Definition: BareField.h:116
const NDIndex< Dim > & getDomain() const
Definition: BareField.h:152
iterator_if begin_if()
Definition: BareField.h:100
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
void Compress() const
Definition: BareField.hpp:991
bool compressible() const
Definition: BareField.h:191
iterator_if end_if()
Definition: BareField.h:101
Definition: LField.h:58
void Compress()
Definition: LField.h:161
const NDIndex< Dim > & getOwned() const
Definition: LField.h:99
bool IsCompressed() const
Definition: LField.h:134
bool TryCompress(bool baseOnPhysicalCells=false)
Definition: LField.hpp:214
void Uncompress(bool fill_domain=true)
Definition: LField.h:172
const iterator & begin() const
Definition: LField.h:110
const NDIndex< Dim > & getDomain() const
Definition: Assign.h:48
PETE_Return_t & offset(int i, int j, int k) const
Definition: Assign.hpp:157
void rewind(unsigned d)
Definition: Assign.hpp:195
PETE_Return_t & unit_offset(int i, int j, int k)
Definition: Assign.hpp:186
PETE_Return_t & unit_offset(int i, int j)
Definition: Assign.hpp:182
int size(unsigned d) const
Definition: Assign.hpp:199
PETE_Return_t & offset(int i) const
Definition: Assign.hpp:149
void step(unsigned d)
Definition: Assign.hpp:191
int Stride(int d) const
Definition: Assign.hpp:207
int done(unsigned d) const
Definition: Assign.hpp:203
PETE_Return_t & offset(int i)
Definition: Assign.hpp:166
PETE_Return_t & offset(int i, int j) const
Definition: Assign.hpp:153
PETE_Return_t & offset(int i, int j, int k)
Definition: Assign.hpp:174
PETE_Return_t & unit_offset(int i)
Definition: Assign.hpp:178
PETE_Return_t & offset(int i, int j)
Definition: Assign.hpp:170
Expr::PETE_Return_t PETE_Return_t
Definition: Assign.hpp:142
PETE_Return_t & operator*()
Definition: Assign.hpp:162
ParensIterator(const Expr &e)
Definition: Assign.hpp:144
PETE_Return_t & operator*() const
Definition: Assign.hpp:145
WrappedExpr & PETE_unwrap()
Definition: PETE.h:81
static type apply(const T &t)
Definition: PETE.h:1089
Definition: Inform.h:42
static bool noFieldCompression
Definition: IpplInfo.h:262
static bool extraCompressChecks
Definition: IpplInfo.h:270
static void abort(const char *=0)
Definition: IpplInfo.cpp:616