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
357 
358 #if defined(EpetraExt_SHOW_DEPRECATED_WARNINGS)
359 #ifdef __GNUC__
360 #warning "The EpetraExt package is deprecated"
361 #endif
362 #endif
363 
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.