OPAL (Object Oriented Parallel Accelerator Library)  2024.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"
19 #include "Field/BrickExpression.h"
20 #include "Field/IndexedBareField.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 
28 #include "PETE/IpplExpressions.h"
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 
46 template<class T, unsigned Dim, class A, class Op>
47 bool
48 TryCompressLHS(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 
138 template<class Expr>
139 class ParensIterator : public Expr
140 {
141 public:
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  }
182  PETE_Return_t& unit_offset(int i, int j)
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 
229 template<class T1, unsigned Dim, class RHS, class OP>
230 void
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);
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 
405 template<class A, class RHS, class OP, class Tag, class TP>
406 void
407 assign(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 
567 template<class T1, unsigned Dim, class RHS, class OP>
568 void
569 assign(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 
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 }
PETE_Combiner< bool, OpOr > PETE_OrCombiner
Definition: PETE.h:468
Expr::PETE_Return_t PETE_Return_t
Definition: Assign.hpp:142
int done(unsigned d) const
Definition: Assign.hpp:203
const NDIndex< Dim > & getOwned() const
Definition: LField.h:99
PETE_Return_t & offset(int i, int j) const
Definition: Assign.hpp:153
bool containsAllPoints(const NDIndex< Dim > &b) const
BareField< T, Dim > & getBareField()
iterator_if end_if()
Definition: BareField.h:101
Definition: Assign.h:47
bool compressible() const
Definition: BareField.h:191
#define ASSIGNMSG(x)
Definition: Assign.h:28
PETE_Return_t & offset(int i, int j, int k) const
Definition: Assign.hpp:157
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
bool IsCompressed() const
Definition: LField.h:134
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
void Uncompress(bool fill_domain=true)
Definition: LField.h:172
PETE_Return_t & operator*() const
Definition: Assign.hpp:145
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
PETE_Return_t & offset(int i)
Definition: Assign.hpp:166
void fillGuardCellsIfNotDirty() const
Definition: BareField.h:122
bool TryCompressLHS(LField< T, Dim > &, A &, Op, const NDIndex< Dim > &)
Definition: Assign.hpp:48
static bool extraCompressChecks
Definition: IpplInfo.h:270
PETE_Return_t & offset(int i, int j)
Definition: Assign.hpp:170
const NDIndex< Dim > & getDomain() const
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
int size(unsigned d) const
Definition: Assign.hpp:199
static type apply(const T &t)
Definition: PETE.h:1089
ParensIterator(const Expr &e)
Definition: Assign.hpp:144
PETE_Return_t & offset(int i, int j, int k)
Definition: Assign.hpp:174
iterator_if begin_if()
Definition: BareField.h:100
bool empty() const
PETE_Combiner< bool, OpAnd > PETE_AndCombiner
Definition: PETE.h:467
void Compress() const
Definition: BareField.hpp:991
void PETE_apply(const OpPeriodic< T > &, T &a, const T &b)
Definition: BCond.hpp:353
bool isDirty() const
Definition: BareField.h:116
Definition: Inform.h:42
void Compress()
Definition: LField.h:161
#define INFORM_ALL_NODES
Definition: Inform.h:39
const unsigned Dim
bool TryCompress(bool baseOnPhysicalCells=false)
Definition: LField.hpp:214
PETE_Return_t & unit_offset(int i)
Definition: Assign.hpp:178
void step(unsigned d)
Definition: Assign.hpp:191
PETE_Return_t & unit_offset(int i, int j, int k)
Definition: Assign.hpp:186
Definition: FFT.h:26
PETE_Return_t & offset(int i) const
Definition: Assign.hpp:149
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
void rewind(unsigned d)
Definition: Assign.hpp:195
Definition: FFT.h:27
constexpr double e
The value of .
Definition: Physics.h:39
bool for_each(const BareFieldIterator< T, D > &p, SameFieldID s, C)
Definition: AssignDefs.h:30
PETE_Return_t & unit_offset(int i, int j)
Definition: Assign.hpp:182
static bool noFieldCompression
Definition: IpplInfo.h:262
int Stride(int d) const
Definition: Assign.hpp:207
WrappedExpr & PETE_unwrap()
Definition: PETE.h:81
void setDirtyFlag()
Definition: BareField.h:117
PETE_Return_t & operator*()
Definition: Assign.hpp:162
const NDIndex< Dim > & getDomain() const
Definition: BareField.h:152
static void abort(const char *=0)
Definition: IpplInfo.cpp:616
const iterator & begin() const
Definition: LField.h:110
FillGCIfNecessaryTag< D, T1 > FillGCIfNecessary(const BareField< T1, D > &bf)
Definition: AssignTags.h:126