OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
BareFieldIterator.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef BARE_FIELD_ITERATOR_H
12 #define BARE_FIELD_ITERATOR_H
13 
14 /***************************************************************************
15  *
16  * A iterator class used for BareField. This will store a ref to a
17  * BareField and keep track of a position within it's LField's. Note that
18  * this is not the most efficient way to loop through the elements of
19  * a BareField, it is more efficient to do an explicit loop over LField's
20  * and then loop over each LField separately (this avoids continual if-tests
21  * in the increment operator checking to see if you are at the end of an
22  * LField).
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Index/NDIndex.h"
28 #include "Field/LField.h"
29 #include "Field/FieldLoc.h"
31 #include "Utility/IpplInfo.h"
32 #include "Utility/PAssert.h"
33 
34 // forward declarations
35 template<class T, unsigned Dim> class BareField;
36 
37 // An iterator over all the elements of a BareField.
38 template<class T, unsigned Dim>
40  : public CompressedBrickIterator<T,Dim>
41 {
42 public:
43  // Typedef for the type of data iterated over by this iterator
44  typedef T return_type;
45 
46  // Default constructor
49  MyBareField(0),
50  LFIndex(-1)
51  {
52  // Increment the statistic on how many iterators were created.
53  //INCIPPLSTAT(incDefaultBareFieldIterators);
54  }
55 
56  // Construct with a BareField, and a flag indicating if the field
57  // is constant. If it is constant, we do not try to decompress.
60  CurrentLField(df.begin_if()),
61  MyBareField(&df),
62  LFIndex(0)
63  {
64  // set iterator at first element
65  beginLField();
66 
67  // Increment the statistic on how many iterators were created.
68  //INCIPPLSTAT(incBareFieldIterators);
69  }
70 
71  // Construct with a BareField and a FieldLoc pointing to some relative
72  // location in the Field, perhaps in a different LField than the
73  // first one. If it is constant, we do not try to decompress.
76  CurrentLField(df.begin_if()),
77  MyBareField(&df),
78  LFIndex(0)
79  {
80  // set iterator location to loc
81  SetCurrentLocation(loc);
82 
83  // Increment the statistic on how many iterators were created.
84  //INCIPPLSTAT(incBareFieldIterators);
85  }
86 
87  // Copy constructor.
89  : CompressedBrickIterator<T,Dim>(iter),
92  LFIndex(iter.LFIndex)
93  {
94  // Increment the statistic on how many iterators were created.
95  //INCIPPLSTAT(incBareFieldIterators);
96  }
97 
98  // Destructor
100  {
101  }
102 
103  // Assignment operator
106  {
107  // if they are the same, just return
108  if (this == &rhs)
109  return *this;
110 
111  // invoke base class operator=
112  *(dynamic_cast<CompressedBrickIterator<T,Dim>*>(this)) = rhs;
113 
114  // copy data members
115  LFIndex = rhs.LFIndex;
117  MyBareField = rhs.MyBareField;
118 
119  return *this;
120  }
121 
122  // Reset where we are pointing
124  {
125  // Whoops! This assumes our iterator is pointing to the first LField!
126  // We need to make sure this is true.
127  PAssert(MyBareField != NULL);
128  CurrentLField = MyBareField->begin_if();
129  LFIndex = 0;
130 
131  // Now advance to the requested LField, indicated by getIndex, which
132  // returns the relative index of the LField we want to interate over.
133  int curr = loc.getIndex();
134  while (!done() && curr-- > 0)
135  nextLField();
136 
137  if (!done()) {
138  // find the relative offset in this LField
139  const NDIndex<Dim>& domain = (*CurrentLField).second->getOwned();
140  int offloc[Dim];
141  for (unsigned int d=0; d < Dim; ++d)
142  offloc[d] = (loc[d] - domain[d].first()) / domain[d].stride();
143 
144  // set the position in the current LField
145  beginLField();
146  this->moveBy(offloc);
147  } else {
148  IpplInfo::abort("Inconsistent FieldLoc in SetCurrentLocation.");
149  }
150  }
151 
152  // Set the given FieldLoc to the current position of this iterator.
154  {
155  const NDIndex<Dim>& domain = (*CurrentLField).second->getOwned();
156  for (unsigned d=0; d<Dim; ++d)
157  loc[d] = this->GetOffset(d)*domain[d].stride() + domain[d].first();
158  loc.setIndex(LFIndex);
159  }
160 
161  // Just return the relative offset within the current LField
162  void GetCurrentLocation(int *loc) const
163  {
164  const NDIndex<Dim>& domain = (*CurrentLField).second->getOwned();
165  for (unsigned d=0; d<Dim; ++d)
166  loc[d] = this->GetOffset(d)*domain[d].stride() + domain[d].first();
167  }
168 
169  // Increment the iterator
171  {
173  if ( *this == (*CurrentLField).second->end() )
175  return *this;
176  }
177 
178  // Dereference the iterator, and return a ref to the data
179  T& operator*() const
180  {
181  PAssert(MyBareField != NULL);
182  // We fill guard cells before using iterator
183  // PAssert(MyBareField->isDirty() ? !isInGC() : true);
185  }
186 
187  // Move on to the LField
188  void nextLField()
189  {
190  ++CurrentLField; ++LFIndex;
191  }
192 
193  // Check if we are at the end of the total iteration space
194  bool done() const
195  {
196  PAssert(MyBareField != NULL);
197  return CurrentLField == MyBareField->end_if();
198  }
199 
200  // Check if we are done with iteration over just the specified dimension
201  bool done(unsigned d) const
202  {
204  }
205 
206  // Set ourselves up to point to the beginning of the first LField
207  void beginLField()
208  {
209  if (!done())
211  (*CurrentLField).second->begin();
212  else
213  LFIndex = (-1);
214  }
215 
216  // Report true if the data being iterated over is currently compressed
217  bool IsCompressed() const
218  {
219  bool is_compressed = CompressedBrickIterator<T,Dim>::IsCompressed();
220  PAssert_EQ((*CurrentLField).second->IsCompressed(), is_compressed);
221  return is_compressed;
222  }
223 
224  // Report true if the data being iterated over can be compressed
225  bool CanCompress() const
226  {
227  PAssert(MyBareField != NULL);
228  if (!MyBareField->compressible()) return false;
229  return (*CurrentLField).second->CanCompress();
230  }
231 
232  // Go and compress the current LField
233  void Compress()
234  {
235  (*CurrentLField).second->Compress();
236  }
237 
238  // Go and compress the current LField to the given value
239  void Compress(T val)
240  {
241  (*CurrentLField).second->Compress(val);
242  }
243 
244  // Try to compress the current LField
245  bool TryCompress()
246  {
247  return (*CurrentLField).second->TryCompress();
248  }
249 
250  // Return a reference to the BareField we're iterating over
252  {
253  PAssert(MyBareField != NULL);
254  return *MyBareField;
255  }
256 
257  // Same, just for const BareField's
259  {
260  PAssert(MyBareField != NULL);
261  return *MyBareField;
262  }
263 
264  //
265  // Scalar code interface
266  //
267 
268  // Prepare this BareField for some future scalar code use where the
269  // BareField may be modified by BareFieldIterators. This means
270  // to make sure that the field is properly uncompressed and guard cells
271  // are filled. The
272  // one argument allows the user to explicitly avoid filling guard
273  // cells if they do not need this.
274  // If tryfill is true, this routine must be called in SPMD-fashion. If
275  // it is false, it can be called on a per-node basis.
276  void prepareForScalarCode(bool tryfill = true)
277  {
278  PAssert(MyBareField != NULL);
279  MyBareField->prepareForScalarCode(tryfill);
280  }
281 
282  // Finish up after a scalar code section. This means go back to
283  // a compressed state if possible, and, if the user says so, indicate
284  // that things have been modified so the dirty flag must be set.
285  // If modified is true, this routine must be called in SPMD-fashion. If
286  // it is false, it can be called on a per-node basis.
287  void finishScalarCode(bool modified = true)
288  {
289  PAssert(MyBareField != NULL);
290  MyBareField->finishScalarCode(modified);
291  }
292 
293 protected:
294  // The current LField we're iterating within right now
296 
297  // The BareField we're iterating over
299 
300  // Storage for some compressed value if needed.
302 
303  // The index of our current LField, from 0 ... # LField's - 1
304  int LFIndex;
305 
306  // Increment and go on to the next LField if necessary.
307  // Put this here because the SGI compiler doesn't
308  // recognize it out of line.
310  {
311  nextLField();
312  beginLField();
313  }
314 
315  // Check to see if our current iteration position is inside the owned
316  // domain of the current LField.
317  bool isInGC() const
318  {
319  // Get the owned domain for our current LField
320  const NDIndex<Dim> &owned = (*CurrentLField).second->getOwned();
321 
322  // Check to see if our current position is within this owned domain
323  for (unsigned d=0; d<Dim; ++d)
324  {
325  unsigned locd = this->GetOffset(d)*owned[d].stride() + owned[d].first();
326  if (!owned[d].contains(Index(locd,locd)))
327  return true;
328  }
329 
330  // If we're here, we must not be in the owned domain.
331  return false;
332  }
333 };
334 
335 
336 #endif // BARE_FIELD_ITERATOR_H
337 
338 /***************************************************************************
339  * $RCSfile: BareFieldIterator.h,v $ $Author: adelmann $
340  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
341  * IPPL_VERSION_ID: $Id: BareFieldIterator.h,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
342  ***************************************************************************/
const unsigned Dim
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
#define PAssert(c)
Definition: PAssert.h:102
ac_id_larray::iterator iterator_if
Definition: BareField.h:92
BareFieldIterator(BareField< T, Dim > &df)
void SetCurrentLocation(const FieldLoc< Dim > &loc)
BareFieldIterator(const FieldLoc< Dim > &loc, BareField< T, Dim > &df)
BareFieldIterator< T, Dim > & operator++()
bool CanCompress() const
void GetCurrentLocation(FieldLoc< Dim > &loc) const
BareField< T, Dim > * MyBareField
const BareField< T, Dim > & GetBareField() const
bool IsCompressed() const
BareFieldIterator(const BareFieldIterator< T, Dim > &iter)
BareField< T, Dim >::iterator_if CurrentLField
void prepareForScalarCode(bool tryfill=true)
void GetCurrentLocation(int *loc) const
BareField< T, Dim > & GetBareField()
void finishScalarCode(bool modified=true)
const BareFieldIterator< T, Dim > & operator=(const BareFieldIterator< T, Dim > &rhs)
bool done(unsigned d) const
int GetOffset(unsigned d) const
Definition: BrickIterator.h:46
bool done(unsigned d) const
Definition: BrickIterator.h:36
BrickIterator & operator++()
Definition: BrickIterator.h:73
T & operator*() const
Definition: BrickIterator.h:89
void moveBy(int i)
int getIndex() const
Definition: FieldLoc.h:61
void setIndex(int newval)
Definition: FieldLoc.h:64
Definition: Index.h:237
static void abort(const char *=0)
Definition: IpplInfo.cpp:616