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