OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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
22 template <unsigned Dim> class SOffset;
23 
24 template <unsigned Dim>
26 template <unsigned Dim>
27 SOffset<Dim> operator+(const SOffset<Dim>&, const int *);
28 template <unsigned Dim>
29 SOffset<Dim> operator+(const int *, const SOffset<Dim>&);
30 template <unsigned Dim>
32 template <unsigned Dim>
34 
35 template <unsigned Dim>
37 template <unsigned Dim>
38 SOffset<Dim> operator-(const SOffset<Dim>&, const int *);
39 template <unsigned Dim>
40 SOffset<Dim> operator-(const int *, const SOffset<Dim>&);
41 template <unsigned Dim>
43 template <unsigned Dim>
45 
46 template <unsigned Dim>
48 template <unsigned Dim>
49 SOffset<Dim> operator*(const SOffset<Dim>&, const int *);
50 template <unsigned Dim>
51 SOffset<Dim> operator*(const int *, const SOffset<Dim>&);
52 template <unsigned Dim>
54 template <unsigned Dim>
56 
57 template <unsigned Dim>
59 template <unsigned Dim>
60 SOffset<Dim> operator/(const SOffset<Dim>&, const int *);
61 template <unsigned Dim>
62 SOffset<Dim> operator/(const int *, const SOffset<Dim>&);
63 template <unsigned Dim>
65 
66 template <unsigned Dim>
68 
69 template <unsigned Dim>
70 std::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 
82 template <unsigned Dim>
83 class SOffset {
84 
85 public:
86  typedef int * iterator;
87  typedef const int * const_iterator;
88 
89 public:
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
99  SOffset(const SOffset<Dim>&);
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 
141 private:
142  int v[Dim];
143 };
144 
145 
146 /***********************************************************************
147  *
148  * Inlined constructors and SOffset functions.
149  *
150  ***********************************************************************/
151 
152 template<unsigned int Dim>
153 inline
154 SOffset<Dim>::SOffset(int v0, int v1) {
155  CTAssert(Dim==2);
156  v[0] = v0;
157  v[1] = v1;
158 }
159 
160 template<unsigned int Dim>
161 inline
162 SOffset<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 
169 template<unsigned int Dim>
170 inline
171 SOffset<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 
179 template<unsigned int Dim>
180 inline
181 SOffset<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 
190 template<unsigned int Dim>
191 inline
192 SOffset<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 
202 template<unsigned int Dim>
203 inline 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 
211 template<unsigned int Dim>
212 inline 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 
225 template<unsigned int Dim>
226 inline Message&
228  ::putMessage(m, v, v + Dim);
229  return m;
230 }
231 
232 template<unsigned int Dim>
233 inline Message&
235  ::getMessage_iter(m, v);
236  return m;
237 }
238 
239 template<unsigned int Dim>
240 inline std::ostream&
241 operator<<(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.
252 template<unsigned int Dim>
253 inline 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
272 template<unsigned int Dim, int Flag>
274 #ifdef IPPL_PURIFY
275  // Add explicit default/copy constructors and op= to avoid UMR's.
276 public:
280  operator=(const DivideSOffsetCopyTag<Dim,Flag> &) { return *this; }
281 #endif
282 };
283 
284 // simple functors for performing operations on SOffset elements
286 #ifdef IPPL_PURIFY
287  // Add explicit default/copy constructors and op= to avoid UMR's.
288  SOffsetAssignOp() {}
289  SOffsetAssignOp(const SOffsetAssignOp &) {}
290  SOffsetAssignOp& operator=(const SOffsetAssignOp &) { return *this; }
291 #endif
292  void operator()(int& a, int b) { a = b; }
293 };
294 
296 #ifdef IPPL_PURIFY
297  // Add explicit default/copy constructors and op= to avoid UMR's.
298  SOffsetAddAssignOp() {}
300  SOffsetAddAssignOp& operator=(const SOffsetAddAssignOp &) { return *this; }
301 #endif
302  void operator()(int& a, int b) { a += b; }
303 };
304 
306 #ifdef IPPL_PURIFY
307  // Add explicit default/copy constructors and op= to avoid UMR's.
308  SOffsetSubAssignOp() {}
310  SOffsetSubAssignOp& operator=(const SOffsetSubAssignOp &) { return *this; }
311 #endif
312  void operator()(int& a, int b) { a -= b; }
313 };
314 
316 #ifdef IPPL_PURIFY
317  // Add explicit default/copy constructors and op= to avoid UMR's.
320  SOffsetMultAssignOp& operator=(const SOffsetMultAssignOp &) { return *this; }
321 #endif
322  void operator()(int& a, int b) { a *= b; }
323 };
324 
326 #ifdef IPPL_PURIFY
327  // Add explicit default/copy constructors and op= to avoid UMR's.
328  SOffsetDivAssignOp() {}
330  SOffsetDivAssignOp& operator=(const SOffsetDivAssignOp &) { return *this; }
331 #endif
332  void operator()(int& a, int b) { a /= b; }
333 };
334 
335 
336 // Operate on a vector of dim 4 or greater. Split it in half and do each half.
337 // Do it this way so that the depth of inlining is O(log(Dim)).
338 template<class T1, class T2, class Op, unsigned int L>
339 inline void
341  divide_soffset_op(p1, p2, op, DivideSOffsetCopyTag<L/2, (L>=8 ? 4 : L/2)>());
342  divide_soffset_op(p1+(L/2), p2+(L/2), op,
343  DivideSOffsetCopyTag<L-L/2, (L>=8?4:L-L/2)>());
344 }
345 
346 
347 // Modify a vector of length 0, 1, 2 or 3.
348 template<class T1, class T2, class Op>
349 inline void
351  op(p1[0], p2[0]);
352  op(p1[1], p2[1]);
353  op(p1[2], p2[2]);
354 }
355 
356 template<class T1, class T2, class Op>
357 inline void
359  op(p1[0], p2[0]);
360  op(p1[1], p2[1]);
361 }
362 
363 template<class T1, class T2, class Op>
364 inline void
366  op(*p1, *p2);
367 }
368 
369 template<class T1, class T2, class Op>
370 inline void
372 }
373 
374 //
375 // The SOffset operators just call divide_soffset_op to do the operation
376 //
377 
378 template<unsigned int L>
379 inline
381 {
383  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
384 }
385 
386 template<unsigned int L>
387 inline
388 SOffset<L>::SOffset(const int *SO)
389 {
391  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
392 }
393 
394 template<unsigned int L>
395 inline SOffset<L>&
397 {
398  if ( this != &SO )
400  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
401  return *this;
402 }
403 
404 template<unsigned int L>
405 inline SOffset<L>&
406 SOffset<L>::operator=(const int *SO)
407 {
409  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
410  return *this;
411 }
412 
413 template<unsigned int L>
414 inline SOffset<L>&
416 {
418  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
419  return *this;
420 }
421 
422 template<unsigned int L>
423 inline SOffset<L>&
425 {
427  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
428  return *this;
429 }
430 
431 template<unsigned int L>
432 inline SOffset<L>&
434 {
436  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
437  return *this;
438 }
439 
440 template<unsigned int L>
441 inline SOffset<L>&
443 {
445  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
446  return *this;
447 }
448 
449 template<unsigned int L>
450 inline SOffset<L>&
452 {
454  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
455  return *this;
456 }
457 
458 template<unsigned int L>
459 inline SOffset<L>&
461 {
463  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
464  return *this;
465 }
466 
467 template<unsigned int L>
468 inline SOffset<L>&
470 {
472  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
473  return *this;
474 }
475 
476 template<unsigned int L>
477 inline SOffset<L>&
479 {
481  DivideSOffsetCopyTag<L,( L>=4 ? 4 : L)>() );
482  return *this;
483 }
484 
485 
486 //
487 // binary operators
488 // SOffset +-*/ SOffset --> SOffset
489 // SOffset +-*/ int * --> SOffset
490 // SOffset +-*/ NDIndex --> NDIndex
491 //
492 
493 template<unsigned int L>
494 inline SOffset<L>
495 operator+(const SOffset<L>& a, const SOffset<L>& b)
496 {
497  SOffset<L> retval(a);
498  return (retval += b);
499 }
500 
501 template<unsigned int L>
502 inline SOffset<L>
503 operator+(const SOffset<L>& a, const int *b)
504 {
505  SOffset<L> retval(a);
506  return (retval += b);
507 }
508 
509 template<unsigned int L>
510 inline SOffset<L>
511 operator+(const int *b, const SOffset<L>& a)
512 {
513  SOffset<L> retval(a);
514  return (retval += b);
515 }
516 
517 template<unsigned int L>
518 inline NDIndex<L>
519 operator+(const SOffset<L>& a, const NDIndex<L>& b)
520 {
521  NDIndex<L> retval;
522  for (int d=0; d < L; ++d)
523  retval[d] = b[d] + a[d];
524  return retval;
525 }
526 
527 template<unsigned int L>
528 inline NDIndex<L>
529 operator+(const NDIndex<L>& b, const SOffset<L>& a)
530 {
531  NDIndex<L> retval;
532  for (int d=0; d < L; ++d)
533  retval[d] = b[d] + a[d];
534  return retval;
535 }
536 
537 template<unsigned int L>
538 inline SOffset<L>
539 operator-(const SOffset<L>& a, const SOffset<L>& b)
540 {
541  SOffset<L> retval(a);
542  return (retval -= b);
543 }
544 
545 template<unsigned int L>
546 inline SOffset<L>
547 operator-(const SOffset<L>& a, const int *b)
548 {
549  SOffset<L> retval(a);
550  return (retval -= b);
551 }
552 
553 template<unsigned int L>
554 inline SOffset<L>
555 operator-(const int *b, const SOffset<L>& a)
556 {
557  SOffset<L> retval(a);
558  return (retval -= b);
559 }
560 
561 template<unsigned int L>
562 inline NDIndex<L>
563 operator-(const SOffset<L>& a, const NDIndex<L>& b)
564 {
565  NDIndex<L> retval;
566  for (int d=0; d < L; ++d)
567  retval[d] = b[d] - a[d];
568  return retval;
569 }
570 
571 template<unsigned int L>
572 inline NDIndex<L>
573 operator-(const NDIndex<L>& b, const SOffset<L>& a)
574 {
575  NDIndex<L> retval;
576  for (int d=0; d < L; ++d)
577  retval[d] = b[d] - a[d];
578  return retval;
579 }
580 
581 template<unsigned int L>
582 inline SOffset<L>
583 operator*(const SOffset<L>& a, const SOffset<L>& b)
584 {
585  SOffset<L> retval(a);
586  return (retval *= b);
587 }
588 
589 template<unsigned int L>
590 inline SOffset<L>
591 operator*(const SOffset<L>& a, const int *b)
592 {
593  SOffset<L> retval(a);
594  return (retval *= b);
595 }
596 
597 template<unsigned int L>
598 inline SOffset<L>
599 operator*(const int *b, const SOffset<L>& a)
600 {
601  SOffset<L> retval(a);
602  return (retval *= b);
603 }
604 
605 template<unsigned int L>
606 inline NDIndex<L>
607 operator*(const SOffset<L>& a, const NDIndex<L>& b)
608 {
609  NDIndex<L> retval;
610  for (int d=0; d < L; ++d)
611  retval[d] = b[d] * a[d];
612  return retval;
613 }
614 
615 template<unsigned int L>
616 inline NDIndex<L>
617 operator*(const NDIndex<L>& b, const SOffset<L>& a)
618 {
619  NDIndex<L> retval;
620  for (int d=0; d < L; ++d)
621  retval[d] = b[d] * a[d];
622  return retval;
623 }
624 
625 template<unsigned int L>
626 inline SOffset<L>
627 operator/(const SOffset<L>& a, const SOffset<L>& b)
628 {
629  SOffset<L> retval(a);
630  return (retval /= b);
631 }
632 
633 template<unsigned int L>
634 inline SOffset<L>
635 operator/(const SOffset<L>& a, const int *b)
636 {
637  SOffset<L> retval(a);
638  return (retval /= b);
639 }
640 
641 template<unsigned int L>
642 inline SOffset<L>
643 operator/(const int *b, const SOffset<L>& a)
644 {
645  SOffset<L> retval(a);
646  return (retval /= b);
647 }
648 
649 template<unsigned int L>
650 inline NDIndex<L>
651 operator/(const NDIndex<L>& b, const SOffset<L>& a)
652 {
653  NDIndex<L> retval;
654  for (int d=0; d < L; ++d)
655  retval[d] = b[d] / a[d];
656  return retval;
657 }
658 
659 
660 //
661 // unary operators
662 //
663 
664 template<unsigned int L>
665 inline SOffset<L>&
667 {
668  SOffset<L> retval;
669  return (retval -= a);
670 }
671 
672 #endif // SOFFSET_H
673 
674 /***************************************************************************
675  * $RCSfile: SOffset.h,v $ $Author: adelmann $
676  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
677  * IPPL_VERSION_ID: $Id: SOffset.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
678  ***************************************************************************/
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
bool inside(const NDIndex< Dim > &) const
Definition: SOffset.h:254
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
SOffset< Dim > & operator=(const SOffset< Dim > &)
Definition: SOffset.h:396
void operator()(int &a, int b)
Definition: SOffset.h:322
Message & putMessage(Message &)
Definition: SOffset.h:227
int * iterator
Definition: SOffset.h:86
unsigned int size() const
Definition: SOffset.h:136
SOffset< Dim > & operator-=(const SOffset< Dim > &)
Definition: SOffset.h:433
SOffset< Dim > & operator/=(const SOffset< Dim > &)
Definition: SOffset.h:469
const int & operator[](unsigned int d) const
Definition: SOffset.h:105
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
#define CTAssert(c)
Definition: PAssert.h:40
bool operator!=(const SOffset< Dim > &a) const
Definition: SOffset.h:110
void getMessage_iter(Message &m, OutputIterator o)
Definition: Message.h:603
SOffset()
Definition: SOffset.h:91
int & operator[](unsigned int d)
Definition: SOffset.h:104
const_iterator end() const
Definition: SOffset.h:135
SOffset(int v0)
Definition: SOffset.h:92
bool operator<(const SOffset< Dim > &) const
Definition: SOffset.h:213
SOffset< Dim > & operator+=(const SOffset< Dim > &)
Definition: SOffset.h:415
void operator()(int &a, int b)
Definition: SOffset.h:292
bool operator>(const SOffset< Dim > &a) const
Definition: SOffset.h:113
Message & getMessage(Message &)
Definition: SOffset.h:234
bool operator==(const SOffset< Dim > &) const
Definition: SOffset.h:204
iterator begin()
Definition: SOffset.h:132
void operator()(int &a, int b)
Definition: SOffset.h:302
int v[Dim]
Definition: SOffset.h:142
const_iterator begin() const
Definition: SOffset.h:134
iterator end()
Definition: SOffset.h:133
const int * const_iterator
Definition: SOffset.h:87
const unsigned Dim
void putMessage(Message &m, const T &t)
Definition: Message.h:557
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
SOffset< Dim > & operator*=(const SOffset< Dim > &)
Definition: SOffset.h:451
void divide_soffset_op(T1 *p1, T2 *p2, Op op, DivideSOffsetCopyTag< L, 4 >)
Definition: SOffset.h:340
void operator()(int &a, int b)
Definition: SOffset.h:312
bool operator>=(const SOffset< Dim > &a) const
Definition: SOffset.h:112
void operator()(int &a, int b)
Definition: SOffset.h:332