OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
BareField.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_H
12 #define BARE_FIELD_H
13 
14 /***************************************************************************
15  *
16  * This is the user visible BareField of type T.
17  * It doesn't even really do expression evaluation; that is
18  * handled with the templates in Expressions.h
19  *
20  ***************************************************************************/
21 
22 // include files
23 #include "Field/LField.h"
24 #include "Field/IndexedBareField.h"
25 #include "Field/GuardCellSizes.h"
26 #include "Field/FieldLoc.h"
30 #include "PETE/IpplExpressions.h"
31 #include "Index/SIndex.h"
32 #include "SubField/SubBareField.h"
33 #include "Utility/IpplInfo.h"
34 #include "Utility/PAssert.h"
35 #include "Utility/Unique.h"
36 #include "Utility/my_auto_ptr.h"
37 #include "Utility/vmap.h"
38 
39 #include <iostream>
40 #include <cstdlib>
41 
42 // forward declarations
43 class Index;
44 template<unsigned Dim> class NDIndex;
45 template<unsigned Dim> class FieldLayout;
46 template<class T, unsigned Dim> class LField;
47 template<class T, unsigned Dim> class BareField;
48 template<class T, unsigned Dim>
49 std::ostream& operator<<(std::ostream&, const BareField<T,Dim>&);
50 
51 // class definition
52 template<class T, unsigned Dim>
53 class BareField : public FieldLayoutUser,
54  public PETE_Expr< BareField<T,Dim> >
55 {
56 
57 public:
58  // Some externally visible typedefs and enums
59  typedef T T_t;
62  enum { Dim_u = Dim };
63 
64 public:
65  // A default constructor, which should be used only if the user calls the
66  // 'initialize' function before doing anything else. There are no special
67  // checks in the rest of the BareField methods to check that the field has
68  // been properly initialized.
69  BareField();
70 
71  // Copy ctor. Deep copy.
73 
74  // Create a new BareField with a given layout and optional guard cells.
77 
78  // Destroy the BareField.
79  ~BareField();
80 
81  // Initialize the field, if it was constructed from the default constructor.
82  // This should NOT be called if the field was constructed by providing
83  // a FieldLayout.
84  void initialize(Layout_t &);
85  void initialize(Layout_t &, const bool); //UL: for pinned memory allocation
86  void initialize(Layout_t &, const GuardCellSizes<Dim>&);
87 
88  // Some typedefs to make access to the maps a bit simpler.
93  typedef typename LField<T,Dim>::iterator LFI;
94 
95  // An iterator over the elements of the BareField.
97 
98  // Let the user iterate over the larrays.
100  iterator_if end_if() { return Locals_ac.end(); }
102  const_iterator_if end_if() const { return Locals_ac.end(); }
103  typename ac_id_larray::size_type size_if() const { return Locals_ac.size(); }
104 
105  // If you make any modifications using an iterator, you must call this.
106  virtual void fillGuardCells(bool reallyFill = true) const;
107 
108  // For use before scatters into guard cells
109  void setGuardCells(const T&) const;
110 
111  // For use after scatters into guard cells
112  void accumGuardCells();
113 
114  // Dirty flag maintenance.
115  bool isDirty() const { return dirty_m; }
117  void clearDirtyFlag() { dirty_m = false; }
118 
119  // If the dirty flag is not set, fill guard cells; otherwise,
120  // don't fill guard cells, but do call boundary conditions.
122  {
123  if (!isDirty())
124  fillGuardCells();
125  else
126  fillGuardCells(false);
127  }
128 
129  // Access to the layout.
131  {
132  PAssert(Layout != 0);
133  return *Layout;
134  }
135 
136  // When we apply a bracket it converts the type
137  // to IndexedBareField so that we can check at compile time
138  // that we have the right number of indexes and brackets.
143 
144  // Boundary condition handling.
145  const GuardCellSizes<Dim>& getGC() const { return Gc; }
146  const GuardCellSizes<Dim>& getGuardCellSizes() const { return Gc; }
147  unsigned leftGuard(unsigned d) const { return getGC().left(d); }
148  unsigned rightGuard(unsigned d) const { return getGC().right(d); }
149 
150  const Index& getIndex(unsigned d) const {return getLayout().getDomain()[d];}
151  const NDIndex<Dim>& getDomain() const { return getLayout().getDomain(); }
152 
153  // Assignment from a constant.
155  {
156  assign(*this,x);
157  return *this;
158  }
159 
160  // Assign another array.
161  const BareField<T,Dim>&
163  {
164  assign(*this,x);
165  return *this;
166  }
167 
168  template<class X>
169  const BareField<T,Dim>&
171  {
172  assign(*this,x);
173  return *this;
174  }
175 
176  // If we have member templates available, assign a generic expression.
177  template<class B>
178  const BareField<T,Dim>&
180  {
181  assign(*this,x);
182  return *this;
183  }
184 
185  //
186  // Methods to deal with compression
187  //
188 
189  // Tell whether BareField may be compressed or not
190  bool compressible() const
191  {
192  return compressible_m;
193  }
194 
195  // Report what fraction of the elements are compressed.
196  // Completely compressed is 1.0, completely uncompressed is 0.0.
197  double CompressedFraction() const;
198 
199  // Tell a BareField to compress/uncompress itself.
200 
201  void Compress() const;
202  void Uncompress() const;
203 
204  // dictate whether BareField may be compressed or not. This will set
205  // a flag, and set the state to be consistent with the flag.
206  void setCompression(bool compress)
207  {
209  compressible_m = compress;
210  if (compress)
211  Compress();
212  else
213  Uncompress();
214  }
215  }
216 
217  //
218  // virtual functions for FieldLayoutUser's (and other UserList users)
219  //
220 
221  // Repartition onto a new layout
222  virtual void Repartition(UserList *);
223 
224  // Tell this object that an object is being deleted
225  virtual void notifyUserOfDelete(UserList *);
226 
227  //
228  // Scalar code interface
229  //
230 
231  // Let the user iterate over each element. Return a begin iterator
232  // for the whole BareField.
233  iterator begin() const
234  {
235  return iterator(const_cast<BareField<T,Dim> &>(*this));
236  }
237 
238  // Let the user iterate over each element. Return an end iterator
239  // for the whole BareField.
240  iterator end() const
241  {
242  return iterator();
243  }
244 
245  // Let the user iterate over each element, but specify where they should
246  // start (other than the beginning). We don't need an end, since this just
247  // affect where we start, not how we traverse the data.
248  iterator beginLoc(const FieldLoc<Dim> &loc) const
249  {
250  return iterator(loc, const_cast<BareField<T,Dim> &>(*this));
251  }
252 
253  // Prepare this BareField for some future scalar code use where the
254  // BareField may be modified by BareFieldIterators. This means
255  // to make sure that the field is properly uncompressed and guard cells
256  // are filled. The
257  // one argument allows the user to explicitly avoid filling guard
258  // cells if they do not need this.
259  // If tryfill is true, this routine must be called in SPMD-fashion. If
260  // it is false, it can be called on a per-node basis.
261  void prepareForScalarCode(bool tryfill = true)
262  {
263  // Turn off compression for now
264  setCompression(false);
265 
266  // Fill the guard cells if they are dirty
267  if (tryfill && isDirty())
268  fillGuardCells(true);
269 
270  // Increment the counter for scalar code starts
271  INCIPPLSTAT(incBeginScalarCodes);
272  }
273 
274  // Finish up after a scalar code section. This means go back to
275  // a compressed state if possible, and, if the user says so, indicate
276  // that things have been modified so the dirty flag must be set.
277  // If modified is true, this routine must be called in SPMD-fashion. If
278  // it is false, it can be called on a per-node basis.
279  void finishScalarCode(bool modified = true)
280  {
281  // If the user says the field has been modified, either we have
282  // to set the dirty flag or go and actually fill GC's (if we are not
283  // deferring GC fills, we need to update things now). So, we try to
284  // set the dirty flag; if it gets set, then fillGuardCellsIfNotDirty
285  // will just leave it set, if it does not get set, then that routine
286  // will go and actually do a GC fill.
287  if (modified)
288  {
289  setDirtyFlag();
291  }
292 
293  // Turn compression back on, and try to compress if possible
294  setCompression(true);
295 
296  // Increment the counter for scalar code stops
297  INCIPPLSTAT(incEndScalarCodes);
298  }
299 
300  //
301  // Single-element access
302  //
303 
304  // Get a ref to a single element of the Field; if it is not local to our
305  // processor, print an error and exit. This allows the user to provide
306  // different index values on each node, instead of using the same element
307  // and broadcasting to all nodes.
308  T& localElement(const NDIndex<Dim>&) const;
309 
310  // get a single value and return it in the given storage. Whichever
311  // node owns the value must broadcast it to the other nodes.
312  void getsingle(const NDIndex<Dim>&, T&) const;
313 
314  //
315  // I/O routines for a BareField
316  //
317 
318  void write(std::ostream&);
319  void write(char*) const;
320  void writeb(char*) const;
321 
322  //
323  // PETE interface.
324  //
325 
326  enum { IsExpr = 0 };
328  iterator MakeExpression() const { return begin(); }
329 
330 protected:
331  // The container of local arrays.
333 
334 private:
335  friend class BareFieldIterator<T,Dim>;
336 
337  // Setup allocates all the LFields. The various ctors call this.
338  void setup();
339 
340  // How the local arrays are laid out.
342 
343  // The specification of how many guard cells this array needs.
345 
346  // A version of get_single that uses a slower but more
347  // robust method. The externally visible get_single
348  // calls this when it determines it needs it.
349  void getsingle_bc(const NDIndex<Dim>&, T&) const;
350 
351  // Dirty flag. Tells whether or not we need to fill guard cells.
352  bool dirty_m;
353 
354  // compression flags
355  bool compressible_m; // are we allowed to compress this BareField?
356 
357  //UL: for pinned memory allocation
358  bool pinned;
359 };
360 
362 
363 //
364 // Construct a BareField from nothing ... default case.
365 //
366 
367 template< class T, unsigned Dim >
368 inline
371 : Layout(0), // No layout yet.
372  Gc( GuardCellSizes<Dim>(0U) ), // No guard cells.
373  compressible_m(!Ippl::noFieldCompression),
374  pinned(false) //UL: for pinned memory allocation
375 {
376 }
377 
378 
379 //
380 // Construct a BareField from a FieldLayout.
381 //
382 
383 template< class T, unsigned Dim >
384 inline
387 : Layout(&l), // Just record the layout.
388  Gc( GuardCellSizes<Dim>(0U) ), // No guard cells.
389  compressible_m(!Ippl::noFieldCompression),
390  pinned(false) //UL: for pinned memory allocation
391 {
392  setup(); // Do the common setup chores.
393 }
394 
395 
396 //
397 // Construct a BareField from a FieldLayout and guard cell sizes.
398 //
399 
400 template< class T, unsigned Dim >
401 inline
404 : Layout(&l), // Just record the layout.
405  Gc(g), // Just record guard cells.
406  compressible_m(!Ippl::noFieldCompression),
407  pinned(false) //UL: for pinned memory allocation
408 {
409  setup(); // Do the common setup chores.
410 }
411 
412 
414 
415 template< class T, unsigned Dim >
418 {
419  return IndexedBareField<T,Dim,1>(*this,idx);
420 }
421 
422 template< class T, unsigned Dim >
425 {
426  return IndexedBareField<T,Dim,1>(*this,i);
427 }
428 
429 template< class T, unsigned Dim >
432 {
433  return IndexedBareField<T,Dim,Dim>(*this,nidx);
434 }
435 
436 template< class T, unsigned Dim >
439 {
440  return SubBareField<T,Dim,SIndex<Dim> >(*this, s);
441 }
442 
443 template< class T, unsigned Dim >
444 inline
445 std::ostream& operator<<(std::ostream& out, const BareField<T,Dim>& a)
446 {
447 
448 
449 
450  BareField<T,Dim>& nca = const_cast<BareField<T,Dim>&>(a);
451  nca.write(out);
452  return out;
453 }
454 
455 
457 
458 #include "Field/BareField.hpp"
459 
460 #endif // BARE_FIELD_H
461 
462 /***************************************************************************
463  * $RCSfile: BareField.h,v $ $Author: adelmann $
464  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
465  * IPPL_VERSION_ID: $Id: BareField.h,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
466  ***************************************************************************/
iterator begin()
Definition: vmap.h:125
vmap< typename Unique::type, my_auto_ptr< LField< T, Dim > > > ac_id_larray
Definition: BareField.h:90
const Index & getIndex(unsigned d) const
Definition: BareField.h:150
Definition: PETE.h:80
Layout_t & getLayout() const
Definition: BareField.h:130
ac_id_larray::iterator iterator_if
Definition: BareField.h:91
bool isDirty() const
Definition: BareField.h:115
const NDIndex< Dim > & getDomain() const
Definition: BareField.h:151
void getsingle(const NDIndex< Dim > &, T &) const
Definition: BareField.hpp:1522
LField< T, Dim > LField_t
Definition: BareField.h:61
Definition: rbendmap.h:8
const BareField< T, Dim > & operator=(const BareField< T, Dim > &x)
Definition: BareField.h:162
Definition: SIndex.h:28
void Compress() const
Definition: BareField.hpp:1304
virtual void Repartition(UserList *)
Definition: BareField.hpp:1367
ac_id_larray Locals_ac
Definition: BareField.h:332
GuardCellSizes< Dim > Gc
Definition: BareField.h:344
bool compressible_m
Definition: BareField.h:355
const BareField< T, Dim > & operator=(const BareField< X, Dim > &x)
Definition: BareField.h:170
Definition: FFT.h:31
void getsingle_bc(const NDIndex< Dim > &, T &) const
Definition: BareField.hpp:1592
void Uncompress() const
Definition: BareField.hpp:1318
void setGuardCells(const T &) const
Definition: BareField.hpp:682
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
T & localElement(const NDIndex< Dim > &) const
Definition: BareField.hpp:1475
bool compressible() const
Definition: BareField.h:190
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:298
iterator MakeExpression() const
Definition: BareField.h:328
static bool deferGuardCellFills
Definition: IpplInfo.h:295
void setDirtyFlag()
Definition: BareField.h:116
iterator_if end_if()
Definition: BareField.h:100
static bool noFieldCompression
Definition: IpplInfo.h:298
Definition: Index.h:236
iterator end() const
Definition: BareField.h:240
const_iterator_if begin_if() const
Definition: BareField.h:101
Layout_t * Layout
Definition: BareField.h:341
unsigned rightGuard(unsigned d) const
Definition: BareField.h:148
const BareField< T, Dim > & operator=(const PETE_Expr< B > &x)
Definition: BareField.h:179
unsigned leftGuard(unsigned d) const
Definition: BareField.h:147
LField< T, Dim >::iterator LFI
Definition: BareField.h:93
const_iterator_if end_if() const
Definition: BareField.h:102
void prepareForScalarCode(bool tryfill=true)
Definition: BareField.h:261
bool dirty_m
Definition: BareField.h:352
void fillGuardCellsIfNotDirty() const
Definition: BareField.h:121
FieldLayout< Dim > Layout_t
Definition: BareField.h:60
void setup()
Definition: BareField.hpp:151
#define INCIPPLSTAT(stat)
Definition: IpplStats.h:235
Definition: FFT.h:30
void accumGuardCells()
Definition: BareField.hpp:764
ac_id_larray::const_iterator const_iterator_if
Definition: BareField.h:92
ac_id_larray::size_type size_if() const
Definition: BareField.h:103
iterator begin() const
Definition: BareField.h:233
void write(std::ostream &)
Definition: BareField.hpp:209
const GuardCellSizes< Dim > & getGC() const
Definition: BareField.h:145
void writeb(char *) const
Definition: BareField.hpp:1220
void setCompression(bool compress)
Definition: BareField.h:206
void finishScalarCode(bool modified=true)
Definition: BareField.h:279
#define PAssert(c)
Definition: PAssert.h:117
bool pinned
Definition: BareField.h:358
size_type size() const
Definition: vmap.h:138
const GuardCellSizes< Dim > & getGuardCellSizes() const
Definition: BareField.h:146
const unsigned Dim
BareFieldIterator< T, Dim > iterator
Definition: BareField.h:96
IndexedBareField< T, Dim, 1 > operator[](const Index &idx)
Definition: BareField.h:417
double CompressedFraction() const
Definition: BareField.hpp:1334
iterator beginLoc(const FieldLoc< Dim > &loc) const
Definition: BareField.h:248
iterator_if begin_if()
Definition: BareField.h:99
virtual void notifyUserOfDelete(UserList *)
Definition: BareField.hpp:1392
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
iterator PETE_Expr_t
Definition: BareField.h:327
void initialize(Layout_t &)
Definition: BareField.hpp:101
iterator end()
Definition: vmap.h:126
const BareField< T, Dim > & operator=(T x)
Definition: BareField.h:154
Definition: vmap.h:65
void clearDirtyFlag()
Definition: BareField.h:117