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