OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
SIndex.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 SINDEX_H
12#define SINDEX_H
13
14// include files
15#include "Index/NDIndex.h"
16#include "Index/SOffset.h"
17#include "Index/LSIndex.h"
19#include "Utility/Inform.h"
20#include <memory>
21
22#include <vector>
23#include <iostream>
24
25// forward declarations
26template <unsigned Dim> class FieldLayout;
27template <unsigned Dim> class SIndex;
28template <unsigned Dim, unsigned Brackets> class IndexedSIndex;
29template <unsigned Dim>
30std::ostream& operator<<(std::ostream&, const SIndex<Dim>&);
31
32/***********************************************************************
33 *
34 * SIndex represents a set of single-point indices for a Field, which
35 * are used to implement sparse-index operations. The user creates an
36 * SIndex object through a where statement or by just adding individual
37 * points, and then performs operations using the SIndex object just as
38 * is done with a regular Index object. In that case, operations are
39 * only performed on those elements of the LHS which are in the SIndex
40 * list. Stencil operations are represented by using SOffset objects
41 * to indicate offsets from the SIndex indices.
42 *
43 * Initially, an SIndex object is empty; points must be added to it by
44 * calling addIndex. An SIndex has an offset, set (or changed) by
45 * calling setOffset(const SOffset&). Only indices for local vnodes are
46 * stored in this object; adding other points will return an error flag.
47 *
48 * Constructing an SIndex requires a FieldLayout object, since SIndex
49 * needs to know the range of index values for which is can store points,
50 * and the location of vnodes.
51 *
52 * A note about offsets: the offset factor is used primarily to make
53 * it possible to specify index offsets in expressions for stenciling
54 * purposes. The method for adding an offset to an SIndex is via the
55 * + or - operators, e.g., A[si] = B[si + SOffset<Dim>(1,-1)], or via
56 * the () operator, e.g., A[si] = B[si(1,-1)] (which means the same as
57 * above). Otherwise, the user should not specify an offset, and the
58 * operations such as union, intersection, etc. implicitly assume that
59 * the offset is zero for the LHS and the RHS.
60 *
61 ***********************************************************************/
62
63template <unsigned Dim>
64class SIndex : public FieldLayoutUser {
65
66public:
67 //# public typedefs
68 typedef std::vector< std::shared_ptr<LSIndex<Dim> > > container_t;
69 typedef unsigned int size_type;
71 typedef typename container_t::const_iterator const_iterator_iv;
72 typedef typename container_t::size_type size_type_iv;
75
76 // default constructor: this requires the user to call 'initialize'
77 // before any other actions are carried out with this SIndex
78 SIndex();
79
80 // constructor: requires a FieldLayout
82
83 // copy constructor
84 SIndex(const SIndex<Dim>&);
85
86 // destructor: frees memory used to store indices, and check out from Layout
87 virtual ~SIndex();
88
89 // initialize the object, if it was constructed with the default
90 // constructor
92
93 // report if we need initialization
94 bool needInitialize() const { return (Layout == 0); }
95
96 // a templated operator= taking a PETE expression
97 template<class T1>
99 assign(*this, rhs);
100 return *this;
101 }
102
103 // assignment operator, with another SIndex or SOffset object. If an
104 // NDIndex object is given, all the points in the NDIndex are used.
108
109 // intersection operator, with another SIndex or SOffset object.
110 // intersected SIndexes must have the same layout; intersection with an
111 // SOffset will leave this object with at most one point
115
116 // union operator, with another SIndex or SOffset object. This will
117 // append the point if it is not already present.
121
122 // add a new index point, specified as an Offset or as a single-point NDIndex
123 // return success (this can fail if the point is outsize the field's domain)
124 bool addIndex(const SOffset<Dim>&);
126 void addIndex(const NDIndex<Dim>&);
127
128 // remove an index point, specified as an Offset or as a single-point NDIndex
129 // return success (this can fail if the point is not on this node)
130 bool removeIndex(const SOffset<Dim>&);
132 void removeIndex(const NDIndex<Dim>&);
133
134 // reserve storage space equal to the given fraction of the size of
135 // each vnode. if fraction=1.0, reserve storage for the entire vnode.
136 void reserve(double = 1.0);
137
138 // clear out the existing indices
139 void clear();
140
141 // get the offset for this sparse index. You can change the offset by
142 // retrieving it this way and then adding to it.
144 const SOffset<Dim>& getOffset() const { return Offset; }
145
146 // get the FieldLayout we are using
148
149 // change to using a new layout.
151
152 // get or change the 'bounding box' domain of this SIndex
153 const NDIndex<Dim> &getDomain() const { return BoundingBox; }
154 void setDomain(const NDIndex<Dim> &ndi) { BoundingBox = ndi; }
155
156 //
157 // SIndex <--> SOffset operations
158 //
159
160 // add or subtract a given offset
161 // SIndex<Dim>& operator+=(const SOffset<Dim>& so) {Offset+=so;return *this;}
162 // SIndex<Dim>& operator-=(const SOffset<Dim>& so) {Offset-=so;return *this;}
163 friend
165 return SIndex(si, so);
166 }
167
168 friend
170 return SIndex(si, so);
171 }
172
173 friend
174 SIndex<Dim> operator+(const SIndex<Dim>& si, const int *so) {
175 return SIndex(si, so);
176 }
177
178 friend
179 SIndex<Dim> operator+(const int *so, const SIndex<Dim>& si) {
180 return SIndex(si, so);
181 }
182
183 friend
185 return SIndex(si, -so);
186 }
187
188 friend
190 return SIndex(si, -so);
191 }
192
193 friend
194 SIndex<Dim> operator-(const SIndex<Dim>& si, const int *so) {
195 return SIndex(si, -SOffset<Dim>(so));
196 }
197
198 friend
199 SIndex<Dim> operator-(const int *so, const SIndex<Dim>& si) {
200 return SIndex(si, -SOffset<Dim>(so));
201 }
202
203 // () operators which make a copy of this SIndex with an extra offset.
204 // These are functionally identical to the operator+, but provide a
205 // nicer syntax. That is, si(1,1) means si + SOffset<Dim>(1,1)
207 SIndex<Dim> operator()(int,int);
208 SIndex<Dim> operator()(int,int,int);
209 SIndex<Dim> operator()(int,int,int,int);
210 SIndex<Dim> operator()(int,int,int,int,int);
211 SIndex<Dim> operator()(int,int,int,int,int,int);
213 SIndex<Dim> operator()(const int *);
214
215 // operator[], which is used with Index or NDIndex objects to further
216 // subset the data. This will only work if the dimension of the Index
217 // arguments + Brackets is <= Dim. Otherwise, too many dimensions worth
218 // of Index objects are being applied
220
221 template<unsigned int Dim2>
223
224
225
226 CTAssert(Dim >= Dim2);
227 NDIndex<Dim> dom;
228 for (unsigned int i=0; i < Dim2; ++i)
229 dom[i] = ndi[i];
230 return IndexedSIndex<Dim,Dim2>(*this, dom);
231 }
232
233 //
234 // SIndex <--> NDIndex operations
235 //
236
237 // convert from the given SOffset value to an NDIndex, with offset added
238 void toNDIndex(const SOffset<Dim>&, NDIndex<Dim>&);
239
240 //
241 // container methods
242 //
243
244 // return begin/end iterators for the LSIndex container
245 iterator_iv begin_iv() { return IndexList.begin(); }
246 iterator_iv end_iv() { return IndexList.end(); }
247 const_iterator_iv begin_iv() const { return IndexList.begin(); }
248 const_iterator_iv end_iv() const { return IndexList.end(); }
249 size_type_iv size_iv() const { return IndexList.size(); }
250
251 // return the total size, which is the sum of the individual sizes
252 size_type_iv size() const;
253
254 // return whether the given point is contained here
255 bool hasIndex(const SOffset<Dim>&) const;
256
257 //
258 // virtual functions for FieldLayoutUser's
259 //
260
261 // Repartition onto a new layout
262 virtual void Repartition(UserList *);
263
264 // Tell this object that an object is being deleted
265 virtual void notifyUserOfDelete(UserList *);
266
267 //
268 // I/O
269 //
270
271 // print out debugging info
272 void printDebug(Inform&) const;
273
274private:
275 // our FieldLayout, indicating the extent and distrib. of index space
277
278 // our current offset; by default, this is zero. We keep a special flag
279 // to indicate whether it is zero or not.
281
282 // our list of indices for each local vnode
284
285 // our 'bounding box', which is the region that is or should be iterated
286 // over to determine what points are in this sparse index list. By default,
287 // this is the domain of the FieldLayout
289
290 // a special constructor, taking another SIndex and an Offset. This
291 // version is almost like a copy constructor, except that the given Offset
292 // is added in to the offset from the copied SIndex.
293 SIndex(const SIndex<Dim>&, const SOffset<Dim>&);
294 SIndex(const SIndex<Dim>&, const int *);
295
296 // set up our internal data structures from the constructor. Assumes
297 // the Layout and Offset have been set.
298 void setup();
299};
300
301#include "Index/SIndex.hpp"
302
303#endif // SINDEX_H
304
305/***************************************************************************
306 * $RCSfile: SIndex.h,v $ $Author: adelmann $
307 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
308 * IPPL_VERSION_ID: $Id: SIndex.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
309 ***************************************************************************/
const unsigned Dim
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
std::ostream & operator<<(std::ostream &, const SIndex< Dim > &)
Definition: SIndex.hpp:741
#define CTAssert(c)
Definition: PAssert.h:35
std::string::iterator iterator
Definition: MSLang.h:16
Definition: Index.h:237
container_t::iterator iterator
Definition: LSIndex.h:37
container_t::const_iterator const_iterator
Definition: LSIndex.h:38
Definition: SIndex.h:64
LSIndex< Dim >::iterator iterator_indx
Definition: SIndex.h:73
container_t::iterator iterator_iv
Definition: SIndex.h:70
virtual ~SIndex()
Definition: SIndex.hpp:113
size_type_iv size_iv() const
Definition: SIndex.h:249
SIndex()
Definition: SIndex.hpp:39
bool addIndex(const SOffset< Dim > &)
Definition: SIndex.hpp:160
void initialize(FieldLayout< Dim > &)
Definition: SIndex.hpp:124
iterator_iv end_iv()
Definition: SIndex.h:246
container_t::size_type size_type_iv
Definition: SIndex.h:72
FieldLayout< Dim > * Layout
Definition: SIndex.h:276
const_iterator_iv begin_iv() const
Definition: SIndex.h:247
size_type_iv size() const
Definition: SIndex.hpp:678
bool removeIndex(const SOffset< Dim > &)
Definition: SIndex.hpp:242
container_t IndexList
Definition: SIndex.h:283
void printDebug(Inform &) const
Definition: SIndex.hpp:764
const SOffset< Dim > & getOffset() const
Definition: SIndex.h:144
friend SIndex< Dim > operator-(const int *so, const SIndex< Dim > &si)
Definition: SIndex.h:199
void setup()
Definition: SIndex.hpp:137
const NDIndex< Dim > & getDomain() const
Definition: SIndex.h:153
friend SIndex< Dim > operator-(const SOffset< Dim > &so, const SIndex< Dim > &si)
Definition: SIndex.h:189
const_iterator_iv end_iv() const
Definition: SIndex.h:248
bool needInitialize() const
Definition: SIndex.h:94
bool hasIndex(const SOffset< Dim > &) const
Definition: SIndex.hpp:345
IndexedSIndex< Dim, Dim2 > operator[](const NDIndex< Dim2 > &ndi)
Definition: SIndex.h:222
friend SIndex< Dim > operator-(const SIndex< Dim > &si, const SOffset< Dim > &so)
Definition: SIndex.h:184
virtual void notifyUserOfDelete(UserList *)
Definition: SIndex.hpp:729
friend SIndex< Dim > operator+(const SOffset< Dim > &so, const SIndex< Dim > &si)
Definition: SIndex.h:169
SIndex< Dim > & operator=(const PETE_Expr< T1 > &rhs)
Definition: SIndex.h:98
container_t::const_iterator const_iterator_iv
Definition: SIndex.h:71
IndexedSIndex< Dim, 1 > operator[](const Index &)
Definition: SIndex.hpp:649
bool addIndex(iterator_iv &, const SOffset< Dim > &)
SOffset< Dim > & getOffset()
Definition: SIndex.h:143
virtual void Repartition(UserList *)
Definition: SIndex.hpp:713
SOffset< Dim > Offset
Definition: SIndex.h:280
SIndex< Dim > operator()(int)
Definition: SIndex.hpp:573
void setDomain(const NDIndex< Dim > &ndi)
Definition: SIndex.h:154
std::vector< std::shared_ptr< LSIndex< Dim > > > container_t
Definition: SIndex.h:68
iterator_iv begin_iv()
Definition: SIndex.h:245
friend SIndex< Dim > operator+(const SIndex< Dim > &si, const SOffset< Dim > &so)
Definition: SIndex.h:164
unsigned int size_type
Definition: SIndex.h:69
friend SIndex< Dim > operator-(const SIndex< Dim > &si, const int *so)
Definition: SIndex.h:194
void clear()
Definition: SIndex.hpp:332
SIndex< Dim > & operator&=(const SIndex< Dim > &)
Definition: SIndex.hpp:427
friend SIndex< Dim > operator+(const SIndex< Dim > &si, const int *so)
Definition: SIndex.h:174
NDIndex< Dim > BoundingBox
Definition: SIndex.h:288
void setFieldLayout(FieldLayout< Dim > &)
Definition: SIndex.hpp:695
friend SIndex< Dim > operator+(const int *so, const SIndex< Dim > &si)
Definition: SIndex.h:179
LSIndex< Dim >::const_iterator const_iterator_indx
Definition: SIndex.h:74
void toNDIndex(const SOffset< Dim > &, NDIndex< Dim > &)
Definition: SIndex.hpp:664
FieldLayout< Dim > & getFieldLayout() const
Definition: SIndex.h:147
void reserve(double=1.0)
Definition: SIndex.hpp:318
bool removeIndex(iterator_iv &, const SOffset< Dim > &)
SIndex< Dim > & operator|=(const SIndex< Dim > &)
Definition: SIndex.hpp:511
Definition: PETE.h:77
Definition: Inform.h:42