OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
SOffset.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 SOFFSET_H
12#define SOFFSET_H
13
14// include files
15#include "Index/NDIndex.h"
16#include "Utility/PAssert.h"
17#include "Message/Message.h"
18
19#include <iostream>
20
21// forward declarations
22template <unsigned Dim> class SOffset;
23
24template <unsigned Dim>
26template <unsigned Dim>
27SOffset<Dim> operator+(const SOffset<Dim>&, const int *);
28template <unsigned Dim>
29SOffset<Dim> operator+(const int *, const SOffset<Dim>&);
30template <unsigned Dim>
32template <unsigned Dim>
34
35template <unsigned Dim>
37template <unsigned Dim>
38SOffset<Dim> operator-(const SOffset<Dim>&, const int *);
39template <unsigned Dim>
40SOffset<Dim> operator-(const int *, const SOffset<Dim>&);
41template <unsigned Dim>
43template <unsigned Dim>
45
46template <unsigned Dim>
48template <unsigned Dim>
49SOffset<Dim> operator*(const SOffset<Dim>&, const int *);
50template <unsigned Dim>
51SOffset<Dim> operator*(const int *, const SOffset<Dim>&);
52template <unsigned Dim>
54template <unsigned Dim>
56
57template <unsigned Dim>
59template <unsigned Dim>
60SOffset<Dim> operator/(const SOffset<Dim>&, const int *);
61template <unsigned Dim>
62SOffset<Dim> operator/(const int *, const SOffset<Dim>&);
63template <unsigned Dim>
65
66template <unsigned Dim>
68
69template <unsigned Dim>
70std::ostream& operator<<(std::ostream&, const SOffset<Dim>&);
71
72/***********************************************************************
73 *
74 * SOffset is a simple class which stores an array of N integers
75 * for use by the SIndex class. It represents an integer offset
76 * for the numbers in the SIndex set of indices. Otherwise, it acts
77 * just like a set of N integers. The class is templated on the number
78 * of elements N.
79 *
80 ***********************************************************************/
81
82template <unsigned Dim>
83class SOffset {
84
85public:
86 typedef int * iterator;
87 typedef const int * const_iterator;
88
89public:
90 // constructors: note the default constructor initializes data to 0
91 SOffset() { for (unsigned int d=0; d < Dim; v[d++] = 0); }
92 SOffset(int v0) { for (unsigned int d=0; d < Dim; v[d++] = v0); }
93 SOffset(int v0, int v1); // only works for a 2D SOffset
94 SOffset(int v0, int v1, int v2); // only works for a 3D SOffset
95 SOffset(int v0, int v1, int v2, int v3); // only works for a 4D SOffset
96 SOffset(int v0, int v1, int v2, int v3, int v4); // only for 5D SOffset
97 SOffset(int v0, int v1, int v2, int v3, int v4, int v5); // only for 6D
98 SOffset(const int *vv); // Takes array of offsets, for any dimensionality
100
101 // copy and index operators
103 SOffset<Dim>& operator=(const int *);
104 int& operator[](unsigned int d) { return v[d]; }
105 const int& operator[](unsigned int d) const { return v[d]; }
106
107 // comparison operators
108 bool operator==(const SOffset<Dim>&) const;
109 bool operator<(const SOffset<Dim>&) const;
110 bool operator!=(const SOffset<Dim>& a) const { return !(*this == a); }
111 bool operator<=(const SOffset<Dim>& a) const { return !(*this > a); }
112 bool operator>=(const SOffset<Dim>& a) const { return !(*this < a); }
113 bool operator>(const SOffset<Dim>& a) const {
114 return !(*this < a || *this == a);
115 }
116
117 // arithmetic operators
119 SOffset<Dim>& operator+=(const int *);
121 SOffset<Dim>& operator-=(const int *);
123 SOffset<Dim>& operator*=(const int *);
125 SOffset<Dim>& operator/=(const int *);
126
127 // put or get to/from a Message
130
131 // iterators for the offset, and information about the data
132 iterator begin() { return v; }
133 iterator end() { return (v + Dim); }
134 const_iterator begin() const { return v; }
135 const_iterator end() const { return (v + Dim); }
136 unsigned int size() const { return Dim; }
137
138 // is this point within an NDIndex object (includes the edges) ?
139 bool inside(const NDIndex<Dim>&) const;
140
141private:
142 int v[Dim];
143};
144
145
146/***********************************************************************
147 *
148 * Inlined constructors and SOffset functions.
149 *
150 ***********************************************************************/
151
152template<unsigned int Dim>
153inline
154SOffset<Dim>::SOffset(int v0, int v1) {
155 CTAssert(Dim==2);
156 v[0] = v0;
157 v[1] = v1;
158}
159
160template<unsigned int Dim>
161inline
162SOffset<Dim>::SOffset(int v0, int v1, int v2) {
163 CTAssert(Dim==3);
164 v[0] = v0;
165 v[1] = v1;
166 v[2] = v2;
167}
168
169template<unsigned int Dim>
170inline
171SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3) {
172 CTAssert(Dim==4);
173 v[0] = v0;
174 v[1] = v1;
175 v[2] = v2;
176 v[3] = v3;
177}
178
179template<unsigned int Dim>
180inline
181SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3, int v4) {
182 CTAssert(Dim==5);
183 v[0] = v0;
184 v[1] = v1;
185 v[2] = v2;
186 v[3] = v3;
187 v[4] = v4;
188}
189
190template<unsigned int Dim>
191inline
192SOffset<Dim>::SOffset(int v0, int v1, int v2, int v3, int v4, int v5) {
193 CTAssert(Dim==6);
194 v[0] = v0;
195 v[1] = v1;
196 v[2] = v2;
197 v[3] = v3;
198 v[4] = v4;
199 v[5] = v5;
200}
201
202template<unsigned int Dim>
203inline bool
205 for (unsigned int i=0; i < Dim; ++i)
206 if (v[i] != a.v[i])
207 return false;
208 return true;
209}
210
211template<unsigned int Dim>
212inline bool
214 for (unsigned int i=0; i < Dim; ++i) {
215 if (v[i] < a.v[i])
216 return true;
217 else if (v[i] > a.v[i])
218 return false;
219 }
220
221 // if we're here, they're exactly equal
222 return false;
223}
224
225template<unsigned int Dim>
226inline Message&
228 ::putMessage(m, v, v + Dim);
229 return m;
230}
231
232template<unsigned int Dim>
233inline Message&
235 ::getMessage_iter(m, v);
236 return m;
237}
238
239template<unsigned int Dim>
240inline std::ostream&
241operator<<(std::ostream& o, const SOffset<Dim>& a) {
242 o << "[";
243 for (unsigned int i=0; i < Dim; ++i)
244 o << a[i] << (i < (Dim-1) ? "," : "");
245 o << "]";
246 return o;
247}
248
249// is this point within an NDIndex object (includes the edges) ?
250// NOTE: this intersects with the whole region of the NDIndex, basically
251// assuming unit stride.
252template<unsigned int Dim>
253inline bool
255 for (unsigned int d=0; d < Dim; ++d) {
256 if (v[d] < ndi[d].first() || v[d] > ndi[d].last())
257 return false;
258 }
259 return true;
260}
261
262
263/***********************************************************************
264 *
265 * Template classes and functions to unroll the loops into subloops of
266 * a maximum of 3 elements.
267 * This is taken from the Utility/Vec.h class with modifications.
268 *
269 ***********************************************************************/
270
271// a tag class used to indicate how many elements and when to split a loop
272template<unsigned int Dim, int Flag>
274};
275
276// simple functors for performing operations on SOffset elements
278 void operator()(int& a, int b) { a = b; }
279};
280
282 void operator()(int& a, int b) { a += b; }
283};
284
286 void operator()(int& a, int b) { a -= b; }
287};
288
290 void operator()(int& a, int b) { a *= b; }
291};
292
294 void operator()(int& a, int b) { a /= b; }
295};
296
297
298// Operate on a vector of dim 4 or greater. Split it in half and do each half.
299// Do it this way so that the depth of inlining is O(log(Dim)).
300template<class T1, class T2, class Op, unsigned int L>
301inline void
303 divide_soffset_op(p1, p2, op, DivideSOffsetCopyTag<L/2, (L>=8 ? 4 : L/2)>());
304 divide_soffset_op(p1+(L/2), p2+(L/2), op,
305 DivideSOffsetCopyTag<L-L/2, (L>=8?4:L-L/2)>());
306}
307
308
309// Modify a vector of length 0, 1, 2 or 3.
310template<class T1, class T2, class Op>
311inline void
313 op(p1[0], p2[0]);
314 op(p1[1], p2[1]);
315 op(p1[2], p2[2]);
316}
317
318template<class T1, class T2, class Op>
319inline void
321 op(p1[0], p2[0]);
322 op(p1[1], p2[1]);
323}
324
325template<class T1, class T2, class Op>
326inline void
328 op(*p1, *p2);
329}
330
331template<class T1, class T2, class Op>
332inline void
334}
335
336//
337// The SOffset operators just call divide_soffset_op to do the operation
338//
339
340template<unsigned int L>
341inline
343{
345 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
346}
347
348template<unsigned int L>
349inline
351{
353 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
354}
355
356template<unsigned int L>
357inline SOffset<L>&
359{
360 if ( this != &SO )
362 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
363 return *this;
364}
365
366template<unsigned int L>
367inline SOffset<L>&
369{
371 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
372 return *this;
373}
374
375template<unsigned int L>
376inline SOffset<L>&
378{
380 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
381 return *this;
382}
383
384template<unsigned int L>
385inline SOffset<L>&
387{
389 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
390 return *this;
391}
392
393template<unsigned int L>
394inline SOffset<L>&
396{
398 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
399 return *this;
400}
401
402template<unsigned int L>
403inline SOffset<L>&
405{
407 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
408 return *this;
409}
410
411template<unsigned int L>
412inline SOffset<L>&
414{
416 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
417 return *this;
418}
419
420template<unsigned int L>
421inline SOffset<L>&
423{
425 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
426 return *this;
427}
428
429template<unsigned int L>
430inline SOffset<L>&
432{
434 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
435 return *this;
436}
437
438template<unsigned int L>
439inline SOffset<L>&
441{
443 DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
444 return *this;
445}
446
447
448//
449// binary operators
450// SOffset +-*/ SOffset --> SOffset
451// SOffset +-*/ int * --> SOffset
452// SOffset +-*/ NDIndex --> NDIndex
453//
454
455template<unsigned int L>
456inline SOffset<L>
458{
459 SOffset<L> retval(a);
460 return (retval += b);
461}
462
463template<unsigned int L>
464inline SOffset<L>
465operator+(const SOffset<L>& a, const int *b)
466{
467 SOffset<L> retval(a);
468 return (retval += b);
469}
470
471template<unsigned int L>
472inline SOffset<L>
473operator+(const int *b, const SOffset<L>& a)
474{
475 SOffset<L> retval(a);
476 return (retval += b);
477}
478
479template<unsigned int L>
480inline NDIndex<L>
482{
483 NDIndex<L> retval;
484 for (unsigned int d=0; d < L; ++d)
485 retval[d] = b[d] + a[d];
486 return retval;
487}
488
489template<unsigned int L>
490inline NDIndex<L>
492{
493 NDIndex<L> retval;
494 for (unsigned int d=0; d < L; ++d)
495 retval[d] = b[d] + a[d];
496 return retval;
497}
498
499template<unsigned int L>
500inline SOffset<L>
502{
503 SOffset<L> retval(a);
504 return (retval -= b);
505}
506
507template<unsigned int L>
508inline SOffset<L>
509operator-(const SOffset<L>& a, const int *b)
510{
511 SOffset<L> retval(a);
512 return (retval -= b);
513}
514
515template<unsigned int L>
516inline SOffset<L>
517operator-(const int *b, const SOffset<L>& a)
518{
519 SOffset<L> retval(a);
520 return (retval -= b);
521}
522
523template<unsigned int L>
524inline NDIndex<L>
526{
527 NDIndex<L> retval;
528 for (int d=0; d < L; ++d)
529 retval[d] = b[d] - a[d];
530 return retval;
531}
532
533template<unsigned int L>
534inline NDIndex<L>
536{
537 NDIndex<L> retval;
538 for (int d=0; d < L; ++d)
539 retval[d] = b[d] - a[d];
540 return retval;
541}
542
543template<unsigned int L>
544inline SOffset<L>
546{
547 SOffset<L> retval(a);
548 return (retval *= b);
549}
550
551template<unsigned int L>
552inline SOffset<L>
553operator*(const SOffset<L>& a, const int *b)
554{
555 SOffset<L> retval(a);
556 return (retval *= b);
557}
558
559template<unsigned int L>
560inline SOffset<L>
561operator*(const int *b, const SOffset<L>& a)
562{
563 SOffset<L> retval(a);
564 return (retval *= b);
565}
566
567template<unsigned int L>
568inline NDIndex<L>
570{
571 NDIndex<L> retval;
572 for (unsigned int d=0; d < L; ++d)
573 retval[d] = b[d] * a[d];
574 return retval;
575}
576
577template<unsigned int L>
578inline NDIndex<L>
580{
581 NDIndex<L> retval;
582 for (unsigned int d=0; d < L; ++d)
583 retval[d] = b[d] * a[d];
584 return retval;
585}
586
587template<unsigned int L>
588inline SOffset<L>
590{
591 SOffset<L> retval(a);
592 return (retval /= b);
593}
594
595template<unsigned int L>
596inline SOffset<L>
597operator/(const SOffset<L>& a, const int *b)
598{
599 SOffset<L> retval(a);
600 return (retval /= b);
601}
602
603template<unsigned int L>
604inline SOffset<L>
605operator/(const int *b, const SOffset<L>& a)
606{
607 SOffset<L> retval(a);
608 return (retval /= b);
609}
610
611template<unsigned int L>
612inline NDIndex<L>
614{
615 NDIndex<L> retval;
616 for (int d=0; d < L; ++d)
617 retval[d] = b[d] / a[d];
618 return retval;
619}
620
621
622//
623// unary operators
624//
625
626template<unsigned int L>
627inline SOffset<L>&
629{
630 SOffset<L> retval;
631 return (retval -= a);
632}
633
634#endif // SOFFSET_H
635
636/***************************************************************************
637 * $RCSfile: SOffset.h,v $ $Author: adelmann $
638 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
639 * IPPL_VERSION_ID: $Id: SOffset.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
640 ***************************************************************************/
const unsigned Dim
void putMessage(Message &m, const T &t)
Definition: Message.h:549
void getMessage_iter(Message &m, OutputIterator o)
Definition: Message.h:595
SOffset< Dim > operator+(const SOffset< Dim > &, const SOffset< Dim > &)
SOffset< Dim > operator*(const SOffset< Dim > &, const SOffset< Dim > &)
std::ostream & operator<<(std::ostream &, const SOffset< Dim > &)
Definition: SOffset.h:241
void divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag< L, 4 >)
Definition: SOffset.h:302
SOffset< Dim > operator-(const SOffset< Dim > &, const SOffset< Dim > &)
SOffset< Dim > operator/(const SOffset< Dim > &, const SOffset< Dim > &)
std::complex< double > a
#define CTAssert(c)
Definition: PAssert.h:35
bool inside(const NDIndex< Dim > &) const
Definition: SOffset.h:254
SOffset(const SOffset< Dim > &)
SOffset< Dim > & operator+=(const SOffset< Dim > &)
bool operator>(const SOffset< Dim > &a) const
Definition: SOffset.h:113
int & operator[](unsigned int d)
Definition: SOffset.h:104
iterator begin()
Definition: SOffset.h:132
const int * const_iterator
Definition: SOffset.h:87
SOffset< Dim > & operator-=(const SOffset< Dim > &)
const int & operator[](unsigned int d) const
Definition: SOffset.h:105
SOffset(int v0)
Definition: SOffset.h:92
int * iterator
Definition: SOffset.h:86
Message & getMessage(Message &)
Definition: SOffset.h:234
const_iterator begin() const
Definition: SOffset.h:134
bool operator!=(const SOffset< Dim > &a) const
Definition: SOffset.h:110
SOffset< Dim > & operator/=(const SOffset< Dim > &)
bool operator<(const SOffset< Dim > &) const
Definition: SOffset.h:213
SOffset()
Definition: SOffset.h:91
SOffset< Dim > & operator=(const SOffset< Dim > &)
unsigned int size() const
Definition: SOffset.h:136
int v[Dim]
Definition: SOffset.h:142
Message & putMessage(Message &)
Definition: SOffset.h:227
const_iterator end() const
Definition: SOffset.h:135
SOffset< Dim > & operator*=(const SOffset< Dim > &)
bool operator>=(const SOffset< Dim > &a) const
Definition: SOffset.h:112
bool operator<=(const SOffset< Dim > &a) const
Definition: SOffset.h:111
iterator end()
Definition: SOffset.h:133
bool operator==(const SOffset< Dim > &) const
Definition: SOffset.h:204
void operator()(int &a, int b)
Definition: SOffset.h:278
void operator()(int &a, int b)
Definition: SOffset.h:282
void operator()(int &a, int b)
Definition: SOffset.h:286
void operator()(int &a, int b)
Definition: SOffset.h:290
void operator()(int &a, int b)
Definition: SOffset.h:294