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 #if defined(EpetraExt_SHOW_DEPRECATED_WARNINGS)
48 #ifdef __GNUC__
49 #warning "The EpetraExt package is deprecated"
50 #endif
51 #endif
52 
53 #include "EpetraExt_ConfigDefs.h"
54 #include "EpetraExt_Exception.h"
55 #include "Epetra_Map.h"
56 #include "Epetra_DistObject.h"
57 
58 namespace EpetraExt
59 {
90  template<class T>
92  {
93  public:
94  // @{ \name Constructors and Destructors
95 
97  DistArray(const Epetra_Map& Map, const int RowSize) :
99  {
100  // only Epetra_Map's with constant element size of 1 are allowed
101  if (Map.MaxElementSize() != 1)
102  throw(Exception(__FILE__, __LINE__,
103  "Map.MaxElementSize() != 1"));
104  if (!Map.ConstantElementSize())
105  throw(Exception(__FILE__, __LINE__,
106  "Map.ConstantElementSize() != true"));
107 
108  MyLength_ = Map.NumMyElements();
109  GlobalLength_ = Map.NumGlobalElements();
110  RowSize_ = RowSize;
111  count_ = 0;
112  values_.resize(MyLength_ * RowSize_);
113  }
114 
115  // @}
116  // @{ \name Query methods
117 
119  inline int MyLength() const
120  {
121  return(MyLength_);
122  }
123 
125  inline int GlobalLength() const
126  {
127  return(GlobalLength_);
128  }
129 
131  inline int RowSize() const
132  {
133  return(RowSize_);
134  }
135 
137  inline T& operator()(const int LEID, const int ID)
138  {
139  assert (ID <= RowSize_);
140  return(values_[LEID * RowSize_ + ID]);
141  }
142 
143  inline T& operator()(const int GEID, const int ID, const bool isLocal)
144  {
145  int LEID = Map().LID(GEID);
146  assert (LEID != -1);
147  assert (ID <= RowSize_);
148  return(values_[LEID * RowSize_ + ID]);
149  }
150 
152  void Print(std::ostream& os) const
153  {
154  os << "DistArray object, label = " << this->Label() << std::endl;
155  os << "Number of local elements = " << Map().NumMyElements() << std::endl;
156  os << "Number of global elements = " << Map().NumGlobalElements() << std::endl;
157  os << std::endl;
158 
159  for (int iproc=0; iproc < Comm().NumProc(); iproc++)
160  {
161  if (iproc == 0)
162  {
163  os << "GEID\t";
164  for (int i = 0; i < RowSize(); ++i) os << "V\t";
165  os << std::endl;
166  }
167 
168  if (Comm().MyPID() == iproc)
169  {
170  for (int i = 0; i < Map().NumMyElements(); ++i)
171  {
172  os << Map().GID(i) << '\t';
173  for (int j = 0; j < RowSize_; ++j)
174  os << values_[i * RowSize_ + j] << '\t';
175  os << std::endl;
176  }
177  }
178  }
179  os << std::endl;
180  }
181 
182  int NextGID()
183  {
184  ++count_;
185  if (count_ < Map().NumMyElements())
186  return(Map().GID(count_));
187  else
188  return(-1);
189  }
190 
191  int FirstGID()
192  {
193  count_ = 0;
194  return(Map().GID(0));
195  }
196 
198  const std::vector<T>& ExtractView() const
199  {
200  return(values_);
201  }
202 
204  T* Values()
205  {
206  return(&values_[0]);
207  }
208 
210  const T* Values() const
211  {
212  return(&values_[0]);
213  }
214 
215  // @}
216  private:
217  // @{ \name Epetra_DistObject methods
218 
219  virtual int CheckSizes(const Epetra_SrcDistObject& Source)
220  {
221  return(0);
222  }
223 
224  virtual int CopyAndPermute(const Epetra_SrcDistObject& Source,
225  int NumSameIDs,
226  int NumPermuteIDs,
227  int * PermuteToLIDs,
228  int * PermuteFromLIDs,
229  const Epetra_OffsetIndex * Indexor,
230  Epetra_CombineMode CombineMode = Zero)
231  {
232  const DistArray& S = dynamic_cast<const DistArray&>(Source);
233  const std::vector<T>& From = S.ExtractView();
234 
235  std::vector<T>& To = values_;
236 
237  //int * ToFirstPointInElementList = 0;
238  //int * FromFirstPointInElementList = 0;
239  //int * FromElementSizeList = 0;
240 
241  int j;
242 
243  int NumSameEntries;
244 
245  NumSameEntries = NumSameIDs;
246 
247  // Short circuit for the case where the source and target std::vector is the same.
248  if (To==From) NumSameEntries = 0;
249 
250  // Do copy first
251  if (NumSameIDs>0)
252  if (To!=From) {
253  for (j=0; j<NumSameEntries * RowSize_; j++)
254  {
255  To[j] = From[j];
256  }
257  }
258 
259  // Do local permutation next
260  if (NumPermuteIDs>0) {
261 
262  for (j=0; j<NumPermuteIDs * RowSize_; j++)
263  To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
264  // constant element size case
265  }
266 
267  return(0);
268  }
269 
270  virtual int PackAndPrepare(const Epetra_SrcDistObject& Source,
271  int NumExportIDs,
272  int* ExportLIDs,
273  int& LenExports,
274  char*& Exports,
275  int& SizeOfPacket,
276  int* Sizes,
277  bool & VarSizes,
278  Epetra_Distributor& Distor)
279  {
280  const DistArray& S = dynamic_cast<const DistArray&>(Source);
281  const std::vector<T>& From = S.ExtractView();
282 
283  std::vector<T> To = values_;
284 
285  //int * FromFirstPointInElementList = 0;
286  //int * FromElementSizeList = 0;
287 
288  SizeOfPacket = RowSize_ * sizeof(T);
289 
290  if(NumExportIDs*SizeOfPacket>LenExports) {
291  if (LenExports>0) delete [] Exports;
292  LenExports = NumExportIDs*SizeOfPacket;
293  Exports = new char[LenExports];
294  }
295 
296  T* ptr;
297 
298  if (NumExportIDs>0) {
299  ptr = (T*) Exports;
300 
301  // Point entry case
302  for (int j=0; j<NumExportIDs; j++)
303  for (int k = 0; k < RowSize_ ; ++k)
304  *ptr++ = From[ExportLIDs[j] * RowSize_ + k];
305  }
306 
307  return(0);
308  }
309 
310  virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source,
311  int NumImportIDs,
312  int* ImportLIDs,
313  int LenImports,
314  char* Imports,
315  int& SizeOfPacket,
316  Epetra_Distributor& Distor,
317  Epetra_CombineMode CombineMode,
318  const Epetra_OffsetIndex * Indexor)
319  {
320  int j;
321 
322  if (CombineMode != Insert)
323  EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
324 
325  std::cout << NumImportIDs << std::endl;
326  if (NumImportIDs<=0) return(0);
327 
328  T* To = &values_[0];
329  //int * ToFirstPointInElementList = 0;
330  //int * ToElementSizeList = 0;
331 
332  T* ptr;
333  // Unpack it...
334 
335  ptr = (T*) Imports;
336 
337  for (j=0; j<NumImportIDs; j++)
338  for (int k = 0; k < RowSize_ ; ++k)
339  To[ImportLIDs[j] * RowSize_ + k] = *ptr++;
340 
341  return(0);
342  }
343 
344  // @}
345  // @{ \name Private data
346 
348  std::vector<T> values_;
350  int MyLength_;
352  int GlobalLength_;
354  int RowSize_;
355  int count_;
356  int last_;
357  // @}
358  };
359 
360 } // namespace EpetraExt
361 
362 #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.