OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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#ifdef DEBUG_ASSIGN
266 int lfcount=0;
267#endif
268 bool needFinalCompressCheck = false;
269 while (la != aend)
270 {
271 // The pointer to the current lhs local field.
272 LField<T1,Dim> *lf = (*la).second.get();
273
274 // If it is on the rhs somewhere, make a copy of it.
275 if ( both_sides ) {
276 lf = new LField<T1,Dim>( *lf );
277 ASSIGNMSG(msg << "For lf " << lfcount << ": making lfield copy.");
278 ASSIGNMSG(msg << endl);
279 }
280
281 // Find the local domain.
282 // Intersect with the indexes used to see how much we will actually use.
283 NDIndex<Dim> local_domain = a.getDomain().intersect( lf->getOwned() );
284
285 // If there is something there...
286 if ( ! local_domain.empty() )
287 {
288 // Some typedefs to make the lines shorter...
289 // types for the left hand side, right hand side and
290 // the whole expression.
291 typedef typename LField<T1,Dim>::iterator LHS;
293
294 // First look and see if the arrays are sufficiently aligned
295 // to do this in one shot.
296 // We do this by trying to do a plugBase and seeing if it worked.
297
298 ASSIGNMSG(msg << "For lf " << lfcount << ": plugbase on ");
299 ASSIGNMSG(msg << local_domain << endl);
300 if ( for_each(bb,PlugBase<Dim>( local_domain ), PETE_AndCombiner()) )
301 {
302 ASSIGNMSG(msg << "For lf " << lfcount << " with owned domain ");
303 ASSIGNMSG(msg << lf->getOwned() << " assigned intersection ");
304 ASSIGNMSG(msg << local_domain << " : ");
305
306 if (a.getBareField().compressible() &&
307 TryCompressLHS(*lf,bb,op,local_domain) ) {
308 // Compressed assign.
309 ASSIGNMSG(msg << "compressed assign, changing ");
310 ASSIGNMSG(msg << *(lf->begin()));
311
312 // Just apply the operator to the single compressed value
313 // on the LHS. If we're here, we know the RHS is compressed
314 // so we can just evaluate it at its first position.
315 PETE_apply(op, *(lf->begin()), for_each(bb,EvalFunctor_0()));
316 ASSIGNMSG(msg << " to " << *(lf->begin()) << endl);
317 } else {
318 // Loop assign.
319 ASSIGNMSG(msg << "loop assign." << endl);
320
321 // Create the expression object.
322 ExprT expr(lf->begin(local_domain), bb);
323 expr.apply();
324
325 // Try to compress this LField since we did an uncompressed
326 // assignment, if the user has requested this kind of
327 // check right after computation on the LField. If this
328 // is not selected, then we'll need to do some end-of-loop
329 // compression checks.
331 ASSIGNMSG(msg << "For lf " << lfcount);
332 ASSIGNMSG(msg << ": doing extra post-compute ");
333 ASSIGNMSG(msg << "compression check ..." << endl);
334 lf->TryCompress(a.getBareField().isDirty());
335 } else {
336 needFinalCompressCheck = true;
337 }
338 }
339 }
340 else
341 {
342 ERRORMSG("All Fields in an expression must be aligned. ");
343 ERRORMSG("(Do you have enough guard cells?)" << endl);
344 ERRORMSG("This error occurred while evaluating an expression ");
345 ERRORMSG("for an LField with domain " << lf->getOwned() << endl);
346 Ippl::abort();
347 }
348 }
349
350 // If we had to make a copy of the current LField,
351 // swap the pointers and delete the old memory.
352 if ( both_sides )
353 {
354 ASSIGNMSG(msg << "For lf " << lfcount << ": swapping lfield data.");
355 ASSIGNMSG(msg << endl);
356 ASSIGNMSG(msg << "For lf " << lfcount << ": at beg, lfield=" << *lf);
357 ASSIGNMSG(msg << endl);
358 (*la).second->swapData( *lf );
359 delete lf;
360 ASSIGNMSG(msg << "For lf " << lfcount << ": at end, lfield=");
361 ASSIGNMSG(msg << *((*la).second) << endl);
362 }
363
364 ++la;
365#ifdef DEBUG_ASSIGN
366 ++lfcount;
367#endif
368 }
369
370
371 // If we are not deferring guard cell fills, and we need to do this
372 // now, fill the guard cells. This will also apply any boundary
373 // conditions after the guards have been updated.
374 if (fillGC) {
375 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
376
377 a.getBareField().fillGuardCellsIfNotDirty();
378
379 }
380
381 // Try to compress the result.
382 if (fillGC && needFinalCompressCheck) {
383 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
384 a.getBareField().Compress(); // tjw added fillGC 12/16/1997
385 }
386
387 //INCIPPLSTAT(incExpressions);
388 //INCIPPLSTAT(incIBFEqualsExpression);
389}
390
391
393//
394// ParensExpression = expression assignment.
395//
396// A version of assign() that handles assignment to just a component of
397// a Field that has been selected via operator(). This version
398// only works if the LHS and RHS terms all agree in their parallel
399// layout within guard-cell tolerances. If they do not, it is
400// an error and IPPL will report it and die. The item having operator()
401// applied can be a BareField or an IndexedBareField.
402//
404
405template<class A, class RHS, class OP, class Tag, class TP>
406void
407assign(PETE_TUTree<OpParens<TP>,A> lhs, RHS wrhs, OP op, Tag,
408 bool fillGC)
409{
410
411 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
412 // defined.
413 ASSIGNMSG(Inform msg("assign Parens", INFORM_ALL_NODES));
414 ASSIGNMSG(msg << "Computing assignment to IBF[" << lhs.Child.getDomain());
415 ASSIGNMSG(msg << "](" << lhs.Value.Arg << ") ..." << endl);
416
417 enum { Dim = A::Dim_u };
418 typedef typename A::return_type T1;
419
420 typedef typename Expressionize<RHS>::type::Wrapped RHS_Wrapped;
422 RHS_Wrapped & rhs = expr.PETE_unwrap();
423
424 // Get a reference to the BareField on the left hand side, and the
425 // total domain we are modifying.
426 BareField<T1,Dim>& bare = lhs.Child.getBareField();
427 const NDIndex<Dim> &total_domain = lhs.Child.getDomain();
428
429 // Fill guard cells if necessary
430 ASSIGNMSG(msg << "Checking whether to fill GC's on RHS ..." << endl);
432
433 // Begin and end iterators for the local fields in the left hand side.
434 typename BareField<T1,Dim>::iterator_if la = bare.begin_if();
435 typename BareField<T1,Dim>::iterator_if aend = bare.end_if();
436
437 // Set the dirty flag indicating this field should have guard cells
438 // filled next time if we are doing deferred GC fills.
439 // We need to set this here so that our compression checks on each
440 // LField take the dirty flag setting into account.
441 bare.setDirtyFlag();
442
443 // Loop over all the local fields of the left hand side.
444
445 bool needFinalCompressCheck = false;
446 while (la != aend)
447 {
448 // The pointer to the current lhs local field, and the owned domain.
449 LField<T1,Dim> *lf = (*la).second.get();
450 const NDIndex<Dim> &lo = lf->getOwned();
451
452 // Find the local domain.
453 // Intersect with the indexes used to see how much we will actually use.
454 NDIndex<Dim> local_domain = total_domain.intersect(lo);
455
456 // If there is something there...
457 if (!local_domain.empty())
458 {
459 // Some typedefs to make the lines shorter...
460 // types for the left hand side, right hand side and
461 // the whole expression.
462 typedef typename LField<T1,Dim>::iterator LA;
463 typedef PETE_TUTree<OpParens<TP>,LA> LHS;
464 typedef BrickExpression<Dim,ParensIterator<LHS>,RHS_Wrapped,OP>
465 ExprT;
466
467 // First look and see if the arrays are sufficiently aligned
468 // to do this in one shot.
469 // We do this by trying to do a plugBase and seeing if it worked.
470 ASSIGNMSG(msg << "For lf " << lo << ": plugbase on ");
471 ASSIGNMSG(msg << local_domain << endl);
472 if (for_each(rhs, PlugBase<Dim>(local_domain), PETE_AndCombiner()))
473 {
474 // Check and see if the lhs is already compressed, and if so,
475 // if the RHS is compressed as well. If so, then we can
476 // just do a compressed assign to modify the Nth element
477 // of the compressed value.
478 bool c1 = for_each(rhs, IsCompressed(), PETE_AndCombiner());
479 bool c2 = local_domain.containsAllPoints(lo);
480 bool c3 = lf->IsCompressed();
481 if (bare.compressible() && c1 && c2 && c3) {
482 // We can do a compressed assign, and we know the LHS is
483 // already compressed. So we can just assign to the first
484 // value, which will modify the selected element of that
485 // value.
486 ASSIGNMSG(msg << "Compressed assign on ");
487 ASSIGNMSG(msg << local_domain << ", changing "<< *lf->begin());
488 const ParensIterator<LHS> ilhs = LHS(lhs.Value, lf->begin());
489 PETE_apply(op, *ilhs, for_each(rhs, EvalFunctor_0()));
490 ASSIGNMSG(msg << " to " << *lf->begin() << endl);
491
492 } else {
493 ASSIGNMSG(msg << "Loop assign on " << local_domain << endl);
494
495 // We must uncompress, and since we will only be writing
496 // to a portion of each element, we must definitely fill
497 // the domain with the compressed value if it is currently
498 // compressed.
499 lf->Uncompress();
500
501 // Build an object that will carry out the expression.
502 const ParensIterator<LHS> ilhs =
503 LHS(lhs.Value, lf->begin(local_domain));
504 ExprT expr2(ilhs, rhs, op);
505 expr2.apply();
506
507 // Try to compress this LField right after we've modified it,
508 // if the user wants us to do this now.
510 ASSIGNMSG(msg << "Doing extra post-compute ");
511 ASSIGNMSG(msg << "compression check ..." << endl);
512 lf->TryCompress(bare.isDirty());
513 } else {
514 needFinalCompressCheck = true;
515 }
516 }
517 }
518 else
519 {
520 ERRORMSG("All Fields in an expression must be aligned. ");
521 ERRORMSG("(Do you have enough guard cells?)" << endl);
522 ERRORMSG("This error occurred while evaluating an expression ");
523 ERRORMSG("for an LField with domain ");
524 ERRORMSG((*la).second->getOwned() << endl);
525 Ippl::abort();
526 }
527 }
528 ++la;
529 }
530
531
532 // Fill the guard cells on the left hand side, if we are deferring
533 // this operation until the next time it is needed.
534 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
535 if (fillGC) {
536
538
539 }
540
541 // Compress the LHS.
542 if (fillGC && needFinalCompressCheck) {
543 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
544 bare.Compress();
545 }
546
547 //INCIPPLSTAT(incExpressions);
548 //INCIPPLSTAT(incParensEqualsExpression);
549}
550
551
553//
554// BareField = expression assignment.
555//
556// This is the specialization with ExprTag<true>, meaning the RHS
557// is an expression, not just a simple BareField. This version
558// only works if the LHS and RHS terms all agree in their parallel
559// layout within guard-cell tolerances. If they do not, it is
560// an error and IPPL will report it and die.
561// Since this is for BareField, the entire domain of the LHS is
562// used to index the RHS. The RHS terms cannot be IndexedBareFields,
563// they must be BareFields as well (or other simpler items).
564//
566
567template<class T1, unsigned Dim, class RHS, class OP>
568void
569assign(const BareField<T1,Dim>& ca, RHS b, OP op, ExprTag<true>)
570{
571
572 // debugging output macros. these are only enabled if DEBUG_ASSIGN is
573 // defined.
574 ASSIGNMSG(Inform msg("assign BF(t)", INFORM_ALL_NODES));
575 ASSIGNMSG(msg << "Computing assignment to BF[" << ca.getDomain());
576 ASSIGNMSG(msg << "] ..." << endl);
577
578 // cast away const here for lhs ... unfortunate but necessary.
579 // Also get the item wrapped within the PETE expression.
580 BareField<T1,Dim>& a = const_cast<BareField<T1,Dim>&>(ca);
581 typename RHS::Wrapped& bb = b.PETE_unwrap();
582
583 // Create iterators over the LHS's LFields.
584 typedef typename LField<T1,Dim>::iterator It;
586 typename BareField<T1,Dim>::iterator_if la = a.begin_if();
587 typename BareField<T1,Dim>::iterator_if aend = a.end_if();
588
589 // Set the dirty flag indicating this field should have guard cells
590 // filled next time if we are doing deferred GC fills.
591 // We need to set this here so that our compression checks on each
592 // LField take the dirty flag setting into account.
593 a.setDirtyFlag();
594
595 // Loop over the LHS LFields, and assign from RHS LFields
596#ifdef DEBUG_ASSIGN
597 int lfcount = 0;
598#endif
599 bool needFinalCompressCheck = false;
600 while (la != aend)
601 {
602 // Get the current LHS and set up the RHS to point to the beginning
603 // of its current LField. This second step is done in lieu of doing
604 // a "plugbase", since it is faster and we know we're dealing with
605 // a whole BareField here, not an indexed BareField.
606 LField<T1,Dim>& lf = *(*la).second;
608
609 ASSIGNMSG(msg << "For lf " << lfcount << " with domain ");
610 ASSIGNMSG(msg << lf.getOwned() << " : ");
611
612 // Check to see if we can compress here. If so, we can avoid a lot
613 // of work.
614 if (a.compressible() && TryCompressLHS(lf, bb, op, a.getDomain())) {
615 ASSIGNMSG(msg << "compressed assign, changing " << *lf.begin());
616 PETE_apply(op,*lf.begin(),for_each(bb,EvalFunctor_0()));
617 ASSIGNMSG(msg << " to " << *lf.begin() << endl);
618 } else {
619 ASSIGNMSG(msg << "loop assign." << endl);
620
621 // Create the expression object.
622 ExprT expr(lf.begin(),bb,op);
623 expr.apply();
624
625 // Try to compress this LField since we did an uncompressed
626 // assignment, if the user has requested this kind of
627 // check right after computation on the LField. If this kind
628 // of request has not been made, then we'll need to do a compression
629 // check at the end.
631 ASSIGNMSG(msg << "For lf " << lfcount);
632 ASSIGNMSG(msg << ": doing extra post-compute ");
633 ASSIGNMSG(msg << "compression check ..." << endl);
634 lf.TryCompress(a.isDirty());
635 } else {
636 needFinalCompressCheck = true;
637 }
638 }
639
640 ++la;
642#ifdef DEBUG_ASSIGN
643 ++lfcount;
644#endif
645 }
646
647
648 // Fill the guard cells on the left hand side, if we are deferring
649 // this operation until the next time it is needed.
650 ASSIGNMSG(msg << "Filling GC's at end if necessary ..." << endl);
651
652 a.fillGuardCellsIfNotDirty();
653
654
655 // Compress the LHS, if necessary
656 if (needFinalCompressCheck) {
657 ASSIGNMSG(msg << "Trying to compress BareField at end ..." << endl);
658 a.Compress();
659 }
660
661 // Compress the LHS.
662 //INCIPPLSTAT(incExpressions);
663 //INCIPPLSTAT(incBFEqualsExpression);
664}
const unsigned Dim
#define ASSIGNMSG(x)
Definition Assign.h:28
bool TryCompressLHS(LField< T, Dim > &, A &, Op, const NDIndex< Dim > &)
Definition Assign.hpp:48
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
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
bool compressible() const
Definition BareField.h:191
iterator_if end_if()
Definition BareField.h:101
void Compress()
Definition LField.h:161
const NDIndex< Dim > & getOwned() const
Definition LField.h:99
CompressedBrickIterator< T, Dim > iterator
Definition LField.h:62
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
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
PETE_TUTree< Value_t, Child_t > & PETE_unwrap()
Definition PETE.h:81
PETE_TUTree< OpIdentity, T > Wrapped
Definition PETE.h:79
static type apply(const T &t)
Definition PETE.h:1089
PETE_TUTree< OpIdentity, T > type
Definition PETE.h:1087
static bool noFieldCompression
Definition IpplInfo.h:262
static bool extraCompressChecks
Definition IpplInfo.h:270
static void abort(const char *=0)
Definition IpplInfo.cpp:616