OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
LField.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 LFIELD_H
12 #define LFIELD_H
13 
14 // include files
15 #include "Utility/Pooled.h"
17 
18 #include <iostream>
19 
20 // forward declarations
21 template <class T, unsigned Dim> class LField;
22 template <class T, unsigned Dim>
23 std::ostream& operator<<(std::ostream&, const LField<T,Dim>&);
24 
25 // Template metaprogram to calculate Dim**N. Used to
26 // reserve space in the overlap cache below.
27 
28 template <int Dim>
29 struct ToTheDim
30 {
31  inline static int calc(int n)
32  {
33  return ToTheDim<Dim-1>::calc(n) * n;
34  }
35 };
36 
37 template<>
38 struct ToTheDim<1>
39 {
40  inline static int calc(int n)
41  {
42  return n;
43  }
44 };
45 
46 
48 
49 // This stores the local data for a Field.
50 template<class T, unsigned Dim>
51 class LField : public Pooled< LField<T,Dim> >
52 {
53 
54 public:
55  // An iterator for the contents of this LField.
57 
58  // The type of domain stored here
60 
61  //
62  // Constructors and destructor
63  //
64 
65  // Ctors for an LField. Arguments:
66  // owned = domain of "owned" region of LField (without guards)
67  // allocated = domain of "allocated" region, which includes guards
68  // vnode = global vnode ID number (see below)
69  LField(const NDIndex<Dim>& owned,
70  const NDIndex<Dim>& allocated,
71  int vnode = -1);
72 
73  //UL: for pinned memory allocation
74  LField(const NDIndex<Dim>& owned,
75  const NDIndex<Dim>& allocated,
76  int vnode,
77  bool p);
78 
79  // Copy constructor.
80  LField(const LField<T,Dim>&);
81 
82  // Destructor: just free the memory, if it's there.
83 
84  ~LField();
85 
86  //
87  // General information accessors
88  //
89 
90  // Return information about the LField.
91  int size(unsigned d) const { return Owned[d].length(); }
92  const NDIndex<Dim>& getAllocated() const { return Allocated; }
93  const NDIndex<Dim>& getOwned() const { return Owned; }
94  T* getP() { return P; }
95 
96  // Return global vnode ID number (between 0 and nvnodes - 1)
97  int getVnode() const { return vnode_m; }
98 
99  //
100  // iterator interface
101  //
102 
103  // Return begin/end iterators for the LField data
104  const iterator& begin() const { return Begin; }
105  const iterator& end() const { return End; }
106 
107  // get an iterator over a subrange.
108  iterator begin(const NDIndex<Dim>& domain);
109 
110  // Get an iterator over a subrange, when we might want to try to
111  // compress the data in the subrange without affecting the rest of
112  // the LField data.
113  // The LField iterator here must be told about a specific
114  // location into which to store a compressed value, since this
115  // iterator is used only to create a message. Since the intersect
116  // region may not be the whole LField, we cannot use the LField's
117  // storage, we need to provide our own (otherwise, when compressing
118  // the Field, we'll write the compressed value for ALL current
119  // iterators on the LField which use the LField's compression
120  // storage).
121  iterator begin(const NDIndex<Dim>& domain, T&);
122 
123  //
124  // Compression handling.
125  //
126 
127  // Let the user ask if we are already compressed.
128  inline bool IsCompressed() const
129  {
130  return P==0;
131  }
132 
133  // Let the user tell us to try to compress.
134  // Return quickly if we already are compressed.
135  // If the argument is true, then only examine the owned domain to determine
136  // if all the values are the same.
137  bool TryCompress(bool baseOnPhysicalCells = false);
138 
139  // Look through the data and figure out if it can be compressed.
140  inline bool CanCompress() const
141  {
142  if (!IsCompressed())
143  return CanCompress(*Begin);
144  return true;
145  }
146 
147  // Look through the data and figure out if it can be compressed
148  // to the given value. Return true if it can be compressed down to the
149  // given value. If this returns false, then the data is currently not
150  // compressed and contains different values.
151  bool CanCompress(T x) const;
152 
153  // Force a compress. Delete the memory and make Begin compressed.
154  // First is a version that uses the first value.
155  inline void Compress()
156  {
157  if (!IsCompressed())
158  Compress(*P);
159  }
160 
161  // Here is version that lets the user specify a new value.
162  void Compress(const T &val);
163 
164  // Let the user tell us to uncompress.
165  // Return quickly if we are already uncompressed.
166  inline void Uncompress(bool fill_domain = true)
167  {
168  if (IsCompressed())
169  ReallyUncompress(fill_domain);
170  }
171 
172  // Return a reference to the compressed data for debugging.
174  const T &getCompressedData() const { return CompressedData; }
175 
176  //
177  // Overlap cache interface
178  //
179 
181 
182  void AddToOverlapCache(LField<T, Dim> *newCacheItem)
183  {
184  if (overlap.size() == 0)
185  overlap.reserve(ToTheDim<Dim>::calc(3)-1);
186  overlap.push_back(newCacheItem);
187  overlapCacheInited = true;
188  }
189 
190  typedef typename std::vector< LField<T, Dim> *>::iterator OverlapIterator;
191 
192  OverlapIterator BeginOverlap() { return overlap.begin(); }
193  OverlapIterator EndOverlap() { return overlap.end(); }
194 
195  //
196  // Swap the pointers between two LFields.
197  //
198 
199  void swapData( LField<T,Dim>& a );
200 
201  //
202  // I/O
203  //
204 
205  // print an LField out
206  void write(std::ostream&) const;
207 
208 private:
209  // Global vnode ID number for the associated Vnode (useful with more recent
210  // FieldLayouts which store a logical "array" of vnodes; user specifies
211  // numbers of vnodes along each direction). Classes or user codes that use
212  // LField are responsible for setting and managing the values of this index;
213  // if unset, it has the value -1. Generally, this parameter value is set on
214  // construction of the vnode:
215 
216  int vnode_m;
217 
218  // The actual pointer to the LField data.
219 
220  T* P;
221 
222  // UL: for pinned memory allocation
223 
224  bool Pinned;
225 
226  // What domain in the data is owned by this LField.
227 
229 
230  // How total domain is actually allocated for thie LField (including guards)
231 
233 
234  // An iterator pointing to the first element in the owned domain.
235 
237 
238  // An iterator pointing one past the last element in the owned domain.
239 
241 
242  // If compressed, put the data here. If not compressed, this is not used.
243 
245 
246  // The overlap cache, an whether it has been initialized.
247 
248  std::vector< LField<T, Dim> * > overlap;
250 
251  // The index of the element to start comparing to the first element
252  // in a "CanCompress" check. This is generally set to the index of the
253  // first element that failed a compression check last time. There are
254  // two versions, one for when we're checking using the entire allocated
255  // domain, and another when we're checking using just the owned domain.
256 
257  mutable int allocCompressIndex;
258  mutable int ownedCompressIndex;
259 
260  // A counter for an offset that is used to keep data from always aligning
261  // at the same point in a memory page.
262 
264 
265  // Private methods used to implement compression
266 
267  bool CanCompressBasedOnPhysicalCells() const;
268  void ReallyUncompress(bool fill_domain);
270 
271  // Actualy allocate storage for the LField data, doing any special
272  // memory tricks needed for performance. Sets P pointer to new memory.
273  void allocateStorage(int newsize);
274 
275  // Actually free the storage used in the LField, if any. Resets P to zero.
276  void deallocateStorage();
277 
278 
279  // Disable default constructor and operator=
280 
281  LField();
282  const LField<T,Dim> &operator=(const LField<T,Dim> &);
283 };
284 
285 
286 template<class T, unsigned Dim>
287 inline
288 std::ostream& operator<<(std::ostream& out, const LField<T,Dim>& a)
289 {
290 
291 
292  a.write(out);
293  return out;
294 }
295 
297 
298 #include "Field/LField.hpp"
299 
300 #endif // LFIELD_H
301 
302 /***************************************************************************
303  * $RCSfile: LField.h,v $ $Author: adelmann $
304  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
305  * IPPL_VERSION_ID: $Id: LField.h,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
306  ***************************************************************************/
int getVnode() const
Definition: LField.h:97
static int calc(int n)
Definition: LField.h:40
iterator End
Definition: LField.h:240
const LField< T, Dim > & operator=(const LField< T, Dim > &)
void deallocateStorage()
Definition: LField.hpp:747
static int calc(int n)
Definition: LField.h:31
bool TryCompress(bool baseOnPhysicalCells=false)
Definition: LField.hpp:223
void swapData(LField< T, Dim > &a)
Definition: LField.hpp:655
bool CanCompressBasedOnPhysicalCells() const
Definition: LField.hpp:398
Definition: rbendmap.h:8
int vnode_m
Definition: LField.h:216
const NDIndex< Dim > & getOwned() const
Definition: LField.h:93
NDIndex< Dim > Domain_t
Definition: LField.h:59
T CompressedData
Definition: LField.h:244
bool OverlapCacheInitialized()
Definition: LField.h:180
OverlapIterator BeginOverlap()
Definition: LField.h:192
void write(std::ostream &) const
Definition: LField.hpp:778
void ReallyUncompress(bool fill_domain)
Definition: LField.hpp:567
T * P
Definition: LField.h:220
Definition: FFT.h:31
~LField()
Definition: LField.hpp:208
void Uncompress(bool fill_domain=true)
Definition: LField.h:166
int ownedCompressIndex
Definition: LField.h:258
const T & getCompressedData() const
Definition: LField.h:174
bool CanCompress() const
Definition: LField.h:140
const iterator & begin() const
Definition: LField.h:104
int allocCompressIndex
Definition: LField.h:257
CompressedBrickIterator< T, Dim > iterator
Definition: LField.h:56
OverlapIterator EndOverlap()
Definition: LField.h:193
iterator Begin
Definition: LField.h:236
const iterator & end() const
Definition: LField.h:105
bool Pinned
Definition: LField.h:224
long offsetBlocks
Definition: LField.h:263
const NDIndex< Dim > & getAllocated() const
Definition: LField.h:92
NDIndex< Dim > Allocated
Definition: LField.h:232
bool IsCompressed() const
Definition: LField.h:128
NDIndex< Dim > Owned
Definition: LField.h:228
std::vector< LField< T, Dim > * > overlap
Definition: LField.h:248
void CompressBasedOnPhysicalCells()
Definition: LField.hpp:536
bool overlapCacheInited
Definition: LField.h:249
void Compress()
Definition: LField.h:155
std::vector< LField< T, Dim > * >::iterator OverlapIterator
Definition: LField.h:190
Definition: Pooled.h:20
void allocateStorage(int newsize)
Definition: LField.hpp:714
T * getP()
Definition: LField.h:94
T & getCompressedData()
Definition: LField.h:173
int size(unsigned d) const
Definition: LField.h:91
void AddToOverlapCache(LField< T, Dim > *newCacheItem)
Definition: LField.h:182