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