OPAL (Object Oriented Parallel Accelerator Library)  2024.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
26 template <unsigned Dim> class FieldLayout;
27 template <unsigned Dim> class SIndex;
28 template <unsigned Dim, unsigned Brackets> class IndexedSIndex;
29 template <unsigned Dim>
30 std::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 
63 template <unsigned Dim>
64 class SIndex : public FieldLayoutUser {
65 
66 public:
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>&);
125  bool addIndex(iterator_iv&, 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>&);
131  bool removeIndex(iterator_iv&, 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
147  FieldLayout<Dim>& getFieldLayout() const { return *Layout; };
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)
206  SIndex<Dim> operator()(int);
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 
274 private:
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  ***************************************************************************/
container_t::const_iterator const_iterator_iv
Definition: SIndex.h:71
void setFieldLayout(FieldLayout< Dim > &)
Definition: SIndex.hpp:695
void setDomain(const NDIndex< Dim > &ndi)
Definition: SIndex.h:154
FieldLayout< Dim > & getFieldLayout() const
Definition: SIndex.h:147
container_t::iterator iterator
Definition: LSIndex.h:37
const_iterator_iv end_iv() const
Definition: SIndex.h:248
friend SIndex< Dim > operator+(const int *so, const SIndex< Dim > &si)
Definition: SIndex.h:179
bool addIndex(const SOffset< Dim > &)
Definition: SIndex.hpp:160
virtual void notifyUserOfDelete(UserList *)
Definition: SIndex.hpp:729
bool removeIndex(const SOffset< Dim > &)
Definition: SIndex.hpp:242
#define CTAssert(c)
Definition: PAssert.h:35
std::vector< std::shared_ptr< LSIndex< Dim > > > container_t
Definition: SIndex.h:68
size_type_iv size_iv() const
Definition: SIndex.h:249
friend SIndex< Dim > operator+(const SIndex< Dim > &si, const int *so)
Definition: SIndex.h:174
LSIndex< Dim >::const_iterator const_iterator_indx
Definition: SIndex.h:74
IndexedSIndex< Dim, 1 > operator[](const Index &)
Definition: SIndex.hpp:649
FieldLayout< Dim > * Layout
Definition: SIndex.h:276
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
const_iterator_iv begin_iv() const
Definition: SIndex.h:247
SIndex< Dim > & operator=(const PETE_Expr< T1 > &rhs)
Definition: SIndex.h:98
void setup()
Definition: SIndex.hpp:137
container_t::iterator iterator_iv
Definition: SIndex.h:70
void reserve(double=1.0)
Definition: SIndex.hpp:318
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is and will automatically terminate your rights under this License parties who have received or from you under this License will not have their licenses terminated so long as such parties remain in full compliance You are not required to accept this since you have not signed it nothing else grants you permission to modify or distribute the Program or its derivative works These actions are prohibited by law if you do not accept this License by modifying or distributing the you indicate your acceptance of this License to do so
Definition: LICENSE:185
friend SIndex< Dim > operator-(const SIndex< Dim > &si, const SOffset< Dim > &so)
Definition: SIndex.h:184
Definition: Index.h:236
friend SIndex< Dim > operator-(const SOffset< Dim > &so, const SIndex< Dim > &si)
Definition: SIndex.h:189
container_t::const_iterator const_iterator
Definition: LSIndex.h:38
std::string::iterator iterator
Definition: MSLang.h:15
NDIndex< Dim > BoundingBox
Definition: SIndex.h:288
void clear()
Definition: SIndex.hpp:332
SOffset< Dim > & getOffset()
Definition: SIndex.h:143
void toNDIndex(const SOffset< Dim > &, NDIndex< Dim > &)
Definition: SIndex.hpp:664
void initialize(FieldLayout< Dim > &)
Definition: SIndex.hpp:124
Definition: Inform.h:42
friend SIndex< Dim > operator-(const SIndex< Dim > &si, const int *so)
Definition: SIndex.h:194
bool hasIndex(const SOffset< Dim > &) const
Definition: SIndex.hpp:345
SIndex< Dim > operator()(int)
Definition: SIndex.hpp:573
container_t::size_type size_type_iv
Definition: SIndex.h:72
const NDIndex< Dim > & getDomain() const
Definition: SIndex.h:153
SIndex()
Definition: SIndex.hpp:39
const unsigned Dim
unsigned int size_type
Definition: SIndex.h:69
iterator_iv begin_iv()
Definition: SIndex.h:245
friend SIndex< Dim > operator+(const SOffset< Dim > &so, const SIndex< Dim > &si)
Definition: SIndex.h:169
Definition: SIndex.h:27
const SOffset< Dim > & getOffset() const
Definition: SIndex.h:144
SIndex< Dim > & operator|=(const SIndex< Dim > &)
Definition: SIndex.hpp:511
size_type_iv size() const
Definition: SIndex.hpp:678
SOffset< Dim > Offset
Definition: SIndex.h:280
SIndex< Dim > & operator&=(const SIndex< Dim > &)
Definition: SIndex.hpp:427
void printDebug(Inform &) const
Definition: SIndex.hpp:764
Definition: PETE.h:76
virtual ~SIndex()
Definition: SIndex.hpp:113
LSIndex< Dim >::iterator iterator_indx
Definition: SIndex.h:73
iterator_iv end_iv()
Definition: SIndex.h:246
bool needInitialize() const
Definition: SIndex.h:94
container_t IndexList
Definition: SIndex.h:283
virtual void Repartition(UserList *)
Definition: SIndex.hpp:713
friend SIndex< Dim > operator-(const int *so, const SIndex< Dim > &si)
Definition: SIndex.h:199
friend SIndex< Dim > operator+(const SIndex< Dim > &si, const SOffset< Dim > &so)
Definition: SIndex.h:164
IndexedSIndex< Dim, Dim2 > operator[](const NDIndex< Dim2 > &ndi)
Definition: SIndex.h:222