OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
BrickIterator.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Field/AssignDefs.h"
28 #include "Index/NDIndex.h"
29 #include "Utility/PAssert.h"
30 
31 
33 // BrickCounter methods
34 
35 template<unsigned Dim>
37 {
38  for (unsigned d=0; d<Dim; ++d)
39  {
41  BrickCounter<Dim>::Counts[d] = counted[d].length();
42  }
43 }
44 
46 
47 template<unsigned Dim>
48 void
50 {
51  // Remove this profiling because this is too lightweight.
52  //
53  //
54  for (unsigned d=0; d<Dim; ++d) {
55  step(d);
57  return;
58  rewind(d);
59  }
60  // If we get to here we have looped over the whole thing.
61 }
62 
63 
65 // BrickIterator methods
66 
67 template<class T, unsigned Dim>
69  const NDIndex<Dim>& counted,
70  const NDIndex<Dim>& domalloc)
71 : BrickCounter<Dim>(counted), Current(p), Whole(true)
72 {
73  // Remove this profiling because this is too lightweight.
74  //
75  //
76 
77  // Calculate the strides,carriage returns and offset for the pointer.
78  int n=1;
79  for (unsigned d=0; d<Dim; ++d) {
80  Strides[d] = n*counted[d].stride();
81  Current += n*(counted[d].first() - domalloc[d].first());
82  n *= domalloc[d].length();
83  Whole = (Whole && counted[d] == domalloc[d]);
84  }
85 }
86 
88 
89 template< class T, unsigned Dim >
91 {
92  // Remove this profiling because this is too lightweight.
93  //
94  //
95 
96  int n = 1;
97  for (unsigned d=0; d<Dim; ++d) {
98  BrickCounter<Dim>::Counts[d] = sizes[d];
100  Strides[d] = n;
101  n *= sizes[d];
102  }
103  Current = p;
104  Whole = true;
105 }
106 
108 
109 template<class T, unsigned Dim>
110 void
112 {
113  // Remove this profiling because this is too lightweight.
114  //
115  //
116 
117  for (unsigned d=0; d<Dim; ++d) {
118  step(d);
120  return;
121  rewind(d);
122  }
123  // If we get to here we have looped over the whole thing.
124  Current = 0;
125 }
126 
127 
129 // put data into a message to send to another node
130 // ... for putMessage, the second argument
131 // is used for an optimization for when the entire brick is being
132 // sent. If that is so, do not copy data into a new buffer, just
133 // put the pointer into the message. USE WITH CARE. The default is
134 // tohave putMessage make a copy of the data in the brick before adding
135 // it to the message. In many situations, this is required since the
136 // data referred to by the iterator is not contiguous. getMessage
137 // has no such option, it always does the most efficient thing it can.
138 template<class T, unsigned Dim>
140 
141 
142 
143  int n, s[Dim];
144  unsigned int i;
145 
146  // put in the size of the data, and calculate total number of elements
147  for (n=1, i=0; i < Dim; ++i) {
148  s[i] = BrickCounter<Dim>::Counts[i];
150  }
151  m.put(s, s + Dim);
152 
153  // Only add in the actual data if there is something to add.
154  if (n > 0) {
155  // If we are not required to make a copy, check if we can just add in
156  // the pointer. We can do this ONLY if we are adding in the entire
157  // domain, and not a subset, of the original domain.
158  if (!makecopy && whole()) {
159  // We are iterating over the whole brick (not just a subset), and
160  // we are not required to make a copy, so, well, don't. Just put
161  // in the pointer to the brick and ask the message NOT to delete
162  // the data when the message is sent.
163  m.setCopy(false);
164  m.setDelete(false);
165  m.putmsg((void *)Current, sizeof(T), n);
166  } else {
167  // FIX THIS!! Better to give a BrickIterator begin/end pair to
168  // putMessage than to do this.
169  T* cpydata = (T*) malloc(sizeof(T)*n);
170  T* cpy = cpydata;
171  T* cpyend = cpydata + n;
172  BrickIterator<T, Dim> bi = *this;
173  for (; cpy != cpyend; ++cpy, ++bi)
174  new (cpy) T(*bi);
175 
176  // put data into this message
177  m.setCopy(false);
178  m.setDelete(true);
179  m.putmsg((void *)cpydata, sizeof(T), n);
180  }
181  }
182 
183  return m;
184 }
185 
186 
188 // get data out from a message
189 template<class T, unsigned Dim>
191 
192 
193  int n, s[Dim];
194  unsigned int i;
195  // this will only work if this iterator does not yet point
196  // at any data
197  PInsist(Current == 0,
198  "Iterator already has data in BrickIterator::getMessage!!");
199 
200  // retrieve size of data in message, and set counters, strides, etc.
201  m.get((int*) s);
202  for (n=1, i=0; i < Dim; ++i) {
203  BrickCounter<Dim>::Counts[i] = s[i];
205  Strides[i] = n;
206  n *= s[i];
207  }
208 
209  // retrieve actual data into an allocated buffer
210  // NOTE: This just stores a pointer to the data that is actually stored
211  // in the Message item. It does not make its own copy. So, if you use
212  // a BrickIterator to get data from a message, you must use the data in the
213  // BrickIterator BEFORE you delete the Message. Otherwise, you'll be
214  // pointing at deallocated memory.
215  /*
216  Current = new T[n];
217  ::getMessage_iter(m, Current);
218  */
219  Current = static_cast<T *>(m.item(0).data());
220  m.get();
221  return m;
222 }
223 
224 
225 
226 /***************************************************************************
227  * $RCSfile: BrickIterator.cpp,v $ $Author: adelmann $
228  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
229  * IPPL_VERSION_ID: $Id: BrickIterator.cpp,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
230  ***************************************************************************/
Message & putMessage(Message &, bool makecopy=true)
Definition: rbendmap.h:8
MsgItem & item(size_t n)
Definition: Message.h:316
Message & getMessage(Message &)
vec< int, Dim > Strides
Message & putmsg(void *, int, int=0)
Message & get(const T &cval)
Definition: Message.h:484
Message & put(const T &val)
Definition: Message.h:414
#define PInsist(c, m)
Definition: PAssert.h:135
const unsigned Dim
T *__restrict__ Current
Message & setDelete(const bool c)
Definition: Message.h:339
Message & setCopy(const bool c)
Definition: Message.h:327
void * data()
Definition: Message.h:252