EpetraExt  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EpetraExt_DistArray.h
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ***********************************************************************
4 //
5 // EpetraExt: Epetra Extended - Linear Algebra Services Package
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //@HEADER
42 */
43 
44 #ifndef EPETRAEXT_DISTARRAY_H
45 #define EPETRAEXT_DISTARRAY_H
46 
47 #include "EpetraExt_ConfigDefs.h"
48 #include "EpetraExt_Exception.h"
49 #include "Epetra_Map.h"
50 #include "Epetra_DistObject.h"
51 
52 namespace EpetraExt
53 {
84  template<class T>
86  {
87  public:
88  // @{ \name Constructors and Destructors
89 
91  DistArray(const Epetra_Map& Map, const int RowSize) :
93  {
94  // only Epetra_Map's with constant element size of 1 are allowed
95  if (Map.MaxElementSize() != 1)
96  throw(Exception(__FILE__, __LINE__,
97  "Map.MaxElementSize() != 1"));
98  if (!Map.ConstantElementSize())
99  throw(Exception(__FILE__, __LINE__,
100  "Map.ConstantElementSize() != true"));
101 
102  MyLength_ = Map.NumMyElements();
103  GlobalLength_ = Map.NumGlobalElements();
104  RowSize_ = RowSize;
105  count_ = 0;
106  values_.resize(MyLength_ * RowSize_);
107  }
108 
109  // @}
110  // @{ \name Query methods
111 
113  inline int MyLength() const
114  {
115  return(MyLength_);
116  }
117 
119  inline int GlobalLength() const
120  {
121  return(GlobalLength_);
122  }
123 
125  inline int RowSize() const
126  {
127  return(RowSize_);
128  }
129 
131  inline T& operator()(const int LEID, const int ID)
132  {
133  assert (ID <= RowSize_);
134  return(values_[LEID * RowSize_ + ID]);
135  }
136 
137  inline T& operator()(const int GEID, const int ID, const bool isLocal)
138  {
139  int LEID = Map().LID(GEID);
140  assert (LEID != -1);
141  assert (ID <= RowSize_);
142  return(values_[LEID * RowSize_ + ID]);
143  }
144 
146  void Print(std::ostream& os) const
147  {
148  os << "DistArray object, label = " << this->Label() << std::endl;
149  os << "Number of local elements = " << Map().NumMyElements() << std::endl;
150  os << "Number of global elements = " << Map().NumGlobalElements() << std::endl;
151  os << std::endl;
152 
153  for (int iproc=0; iproc < Comm().NumProc(); iproc++)
154  {
155  if (iproc == 0)
156  {
157  os << "GEID\t";
158  for (int i = 0; i < RowSize(); ++i) os << "V\t";
159  os << std::endl;
160  }
161 
162  if (Comm().MyPID() == iproc)
163  {
164  for (int i = 0; i < Map().NumMyElements(); ++i)
165  {
166  os << Map().GID(i) << '\t';
167  for (int j = 0; j < RowSize_; ++j)
168  os << values_[i * RowSize_ + j] << '\t';
169  os << std::endl;
170  }
171  }
172  }
173  os << std::endl;
174  }
175 
176  int NextGID()
177  {
178  ++count_;
179  if (count_ < Map().NumMyElements())
180  return(Map().GID(count_));
181  else
182  return(-1);
183  }
184 
185  int FirstGID()
186  {
187  count_ = 0;
188  return(Map().GID(0));
189  }
190 
192  const std::vector<T>& ExtractView() const
193  {
194  return(values_);
195  }
196 
198  T* Values()
199  {
200  return(&values_[0]);
201  }
202 
204  const T* Values() const
205  {
206  return(&values_[0]);
207  }
208 
209  // @}
210  private:
211  // @{ \name Epetra_DistObject methods
212 
213  virtual int CheckSizes(const Epetra_SrcDistObject& Source)
214  {
215  return(0);
216  }
217 
218  virtual int CopyAndPermute(const Epetra_SrcDistObject& Source,
219  int NumSameIDs,
220  int NumPermuteIDs,
221  int * PermuteToLIDs,
222  int * PermuteFromLIDs,
223  const Epetra_OffsetIndex * Indexor,
224  Epetra_CombineMode CombineMode = Zero)
225  {
226  const DistArray& S = dynamic_cast<const DistArray&>(Source);
227  const std::vector<T>& From = S.ExtractView();
228 
229  std::vector<T>& To = values_;
230 
231  //int * ToFirstPointInElementList = 0;
232  //int * FromFirstPointInElementList = 0;
233  //int * FromElementSizeList = 0;
234 
235  int j;
236 
237  int NumSameEntries;
238 
239  NumSameEntries = NumSameIDs;
240 
241  // Short circuit for the case where the source and target std::vector is the same.
242  if (To==From) NumSameEntries = 0;
243 
244  // Do copy first
245  if (NumSameIDs>0)
246  if (To!=From) {
247  for (j=0; j<NumSameEntries * RowSize_; j++)
248  {
249  To[j] = From[j];
250  }
251  }
252 
253  // Do local permutation next
254  if (NumPermuteIDs>0) {
255 
256  for (j=0; j<NumPermuteIDs * RowSize_; j++)
257  To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
258  // constant element size case
259  }
260 
261  return(0);
262  }
263 
264  virtual int PackAndPrepare(const Epetra_SrcDistObject& Source,
265  int NumExportIDs,
266  int* ExportLIDs,
267  int& LenExports,
268  char*& Exports,
269  int& SizeOfPacket,
270  int* Sizes,
271  bool & VarSizes,
272  Epetra_Distributor& Distor)
273  {
274  const DistArray& S = dynamic_cast<const DistArray&>(Source);
275  const std::vector<T>& From = S.ExtractView();
276 
277  std::vector<T> To = values_;
278 
279  //int * FromFirstPointInElementList = 0;
280  //int * FromElementSizeList = 0;
281 
282  SizeOfPacket = RowSize_ * sizeof(T);
283 
284  if(NumExportIDs*SizeOfPacket>LenExports) {
285  if (LenExports>0) delete [] Exports;
286  LenExports = NumExportIDs*SizeOfPacket;
287  Exports = new char[LenExports];
288  }
289 
290  T* ptr;
291 
292  if (NumExportIDs>0) {
293  ptr = (T*) Exports;
294 
295  // Point entry case
296  for (int j=0; j<NumExportIDs; j++)
297  for (int k = 0; k < RowSize_ ; ++k)
298  *ptr++ = From[ExportLIDs[j] * RowSize_ + k];
299  }
300 
301  return(0);
302  }
303 
304  virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source,
305  int NumImportIDs,
306  int* ImportLIDs,
307  int LenImports,
308  char* Imports,
309  int& SizeOfPacket,
310  Epetra_Distributor& Distor,
311  Epetra_CombineMode CombineMode,
312  const Epetra_OffsetIndex * Indexor)
313  {
314  int j;
315 
316  if (CombineMode != Insert)
317  EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
318 
319  std::cout << NumImportIDs << std::endl;
320  if (NumImportIDs<=0) return(0);
321 
322  T* To = &values_[0];
323  //int * ToFirstPointInElementList = 0;
324  //int * ToElementSizeList = 0;
325 
326  T* ptr;
327  // Unpack it...
328 
329  ptr = (T*) Imports;
330 
331  for (j=0; j<NumImportIDs; j++)
332  for (int k = 0; k < RowSize_ ; ++k)
333  To[ImportLIDs[j] * RowSize_ + k] = *ptr++;
334 
335  return(0);
336  }
337 
338  // @}
339  // @{ \name Private data
340 
342  std::vector<T> values_;
344  int MyLength_;
346  int GlobalLength_;
348  int RowSize_;
349  int count_;
350  int last_;
351  // @}
352  };
353 
354 } // namespace EpetraExt
355 
356 #endif
int NumGlobalElements() const
int MyLength() const
Returns the length of the locally owned array.
int GlobalLength() const
Returns the global length of the array.
bool ConstantElementSize() const
DistArray(const Epetra_Map &Map, const int RowSize)
Constructor for a given Map and RowSize.
int NumMyElements() const
T * Values()
Returns a pointer to the internally stored data (non-const version).
const std::vector< T > & ExtractView() const
Extracts a view of the array.
const T * Values() const
Returns a pointer to the internally stored data (const version).
int RowSize() const
Returns the row size, that is, the amount of data associated with each element.
T & operator()(const int GEID, const int ID, const bool isLocal)
void Print(std::ostream &os) const
Prints the array on the specified stream.
int MaxElementSize() const
Epetra_CombineMode
T & operator()(const int LEID, const int ID)
Returns a reference to the ID component of the LEID local element.
DistArray&lt;T&gt;: A class to store row-oriented multivectors of type T.