Epetra Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Epetra_RowMatrixTransposer.cpp
Go to the documentation of this file.
1 
2 //@HEADER
3 // ************************************************************************
4 //
5 // Epetra: 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 #include "Epetra_ConfigDefs.h"
45 #include "Epetra_RowMatrix.h"
46 #include "Epetra_CrsMatrix.h"
47 #include "Epetra_CrsGraph.h"
48 #include "Epetra_Map.h"
49 #include "Epetra_Export.h"
50 
51 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // FIXME
52 // FIXME long long : whole file
53 
54 //=============================================================================
56  : OrigMatrix_(OrigMatrix),
57  TransposeMatrix_(0),
58  TransposeExporter_(0),
59  TransposeRowMap_(0),
60  TransposeCreated_(false),
61  MakeDataContiguous_(false),
62  NumMyRows_(0),
63  NumMyCols_(0),
64  MaxNumEntries_(0),
65  Indices_(NULL),
66  Values_(NULL),
67  TransNumNz_(NULL),
68  TransIndices_(NULL),
69  TransValues_(NULL),
70  TransMyGlobalEquations_(NULL),
71  OrigMatrixIsCrsMatrix_(false)
72 {
73 }
74 //=============================================================================
76  :OrigMatrix_(Source.OrigMatrix_),
77  TransposeMatrix_(0),
78  TransposeExporter_(0),
79  TransposeRowMap_(0),
80  TransposeCreated_(Source.TransposeCreated_),
81  MakeDataContiguous_(Source.MakeDataContiguous_),
82  NumMyRows_(0),
83  NumMyCols_(0),
84  MaxNumEntries_(0),
85  Indices_(NULL),
86  Values_(NULL),
87  TransNumNz_(NULL),
88  TransIndices_(NULL),
89  TransValues_(NULL),
90  TransMyGlobalEquations_(NULL),
91  OrigMatrixIsCrsMatrix_(false)
92 {
96 }
97 //=========================================================================
99 
100  DeleteData();
101 
102 }
103 
104 //=========================================================================
106 
107  int i;
108 
110 
111  // Delete any intermediate storage
112 
113  if (!OrigMatrixIsCrsMatrix_) {
114  delete [] Indices_;
115  delete [] Values_;
116  }
117 
118 
119  for(i=0; i<NumMyCols_; i++) {
120  int NumIndices = TransNumNz_[i];
121  if (NumIndices>0) {
122  delete [] TransIndices_[i];
123  delete [] TransValues_[i];
124  }
125  }
126  delete [] TransNumNz_;
127  delete [] TransIndices_;
128  delete [] TransValues_;
129  delete [] TransMyGlobalEquations_;
130 }
131 
132 //=========================================================================
133 int Epetra_RowMatrixTransposer::CreateTranspose (const bool MakeDataContiguous,
134  Epetra_CrsMatrix *& TransposeMatrix,
135  Epetra_Map * TransposeRowMap_in) {
136 
137 // FIXME long long
138 
139  int i, j;
140 
141  if (TransposeCreated_) DeleteData(); // Get rid of existing data first
142 
143  if (TransposeRowMap_in==0)
144  TransposeRowMap_ = (Epetra_Map *) &(OrigMatrix_->OperatorDomainMap()); // Should be replaced with refcount =
145  else
146  TransposeRowMap_ = TransposeRowMap_in;
147 
148  // This routine will work for any RowMatrix object, but will attempt cast the matrix to a CrsMatrix if
149  // possible (because we can then use a View of the matrix and graph, which is much cheaper).
150 
151  // First get the local indices to count how many nonzeros will be in the
152  // transpose graph on each processor
153 
154 
155  Epetra_CrsMatrix * OrigCrsMatrix = dynamic_cast<Epetra_CrsMatrix *>(OrigMatrix_);
156 
157  OrigMatrixIsCrsMatrix_ = (OrigCrsMatrix!=0); // If this pointer is non-zero, the cast to CrsMatrix worked
158 
162  TransNumNz_ = new int[NumMyCols_];
163  TransIndices_ = new int*[NumMyCols_];
164  TransValues_ = new double*[NumMyCols_];
165 
166 
167  int NumIndices;
168 
170 
171 
172  const Epetra_CrsGraph & OrigGraph = OrigCrsMatrix->Graph(); // Get matrix graph
173 
174  for (i=0;i<NumMyCols_; i++) TransNumNz_[i] = 0;
175  for (i=0; i<NumMyRows_; i++) {
176  EPETRA_CHK_ERR(OrigGraph.ExtractMyRowView(i, NumIndices, Indices_)); // Get view of ith row
177  for (j=0; j<NumIndices; j++) ++TransNumNz_[Indices_[j]];
178  }
179  }
180  else { // OrigMatrix is not a CrsMatrix
181 
182  MaxNumEntries_ = 0;
183  int NumEntries;
184  for (i=0; i<NumMyRows_; i++) {
185  OrigMatrix_->NumMyRowEntries(i, NumEntries);
187  }
188  Indices_ = new int[MaxNumEntries_];
189  Values_ = new double[MaxNumEntries_];
190 
191  for (i=0;i<NumMyCols_; i++) TransNumNz_[i] = 0;
192  for (i=0; i<NumMyRows_; i++) {
193  // Get ith row
195  for (j=0; j<NumIndices; j++) ++TransNumNz_[Indices_[j]];
196  }
197  }
198 
199 
200  // Most of remaining code is common to both cases
201 
202  for(i=0; i<NumMyCols_; i++) {
203  NumIndices = TransNumNz_[i];
204  if (NumIndices>0) {
205  TransIndices_[i] = new int[NumIndices];
206  TransValues_[i] = new double[NumIndices];
207  }
208  }
209 
210  // Now copy values and global indices into newly created transpose storage
211 
212  for (i=0;i<NumMyCols_; i++) TransNumNz_[i] = 0; // Reset transpose NumNz counter
213  for (i=0; i<NumMyRows_; i++) {
215  EPETRA_CHK_ERR(OrigCrsMatrix->ExtractMyRowView(i, NumIndices, Values_, Indices_));
216  }
217  else {
219  }
220 
221  int ii = OrigMatrix_->RowMatrixRowMap().GID64(i); // FIXME long long
222  for (j=0; j<NumIndices; j++) {
223  int TransRow = Indices_[j];
224  int loc = TransNumNz_[TransRow];
225  TransIndices_[TransRow][loc] = ii;
226  TransValues_[TransRow][loc] = Values_[j];
227  ++TransNumNz_[TransRow]; // increment counter into current transpose row
228  }
229  }
230 
231  // Build Transpose matrix with some rows being shared across processors.
232  // We will use a view here since the matrix will not be used for anything else
233 
234  const Epetra_Map & TransMap = OrigMatrix_->RowMatrixColMap();
235 
236  Epetra_CrsMatrix TempTransA1(View, TransMap, TransNumNz_);
238 
240 
241  /* Add rows one-at-a-time */
242 
243  for (i=0; i<NumMyCols_; i++)
244  {
247  }
248  // Note: The following call to FillComplete is currently necessary because
249  // some global constants that are needed by the Export () are computed in this routine
250 
251  const Epetra_Map& domain_map = OrigMatrix_->OperatorDomainMap();
252  const Epetra_Map& range_map = OrigMatrix_->OperatorRangeMap();
253 
254  EPETRA_CHK_ERR(TempTransA1.FillComplete(range_map, domain_map, false));
255 
256  // Now that transpose matrix with shared rows is entered, create a new matrix that will
257  // get the transpose with uniquely owned rows (using the same row distribution as A).
258 
260 
261  // Create an Export object that will move TempTransA around
262 
264 
265  EPETRA_CHK_ERR(TransposeMatrix_->Export(TempTransA1, *TransposeExporter_, Add));
266 
267  EPETRA_CHK_ERR(TransposeMatrix_->FillComplete(range_map, domain_map));
268 
269  if (MakeDataContiguous) {
270  EPETRA_CHK_ERR(TransposeMatrix_->MakeDataContiguous());
271  }
272 
273  TransposeMatrix = TransposeMatrix_;
274  TransposeCreated_ = true;
275 
276  return(0);
277 }
278 //=========================================================================
280 
281  int i, j, NumIndices;
282 
283  if (!TransposeCreated_) EPETRA_CHK_ERR(-1); // Transpose must be already created
284 
285  // Sanity check of incoming matrix. Perform some tests to see if it is compatible with original input matrix
286  if (OrigMatrix_!=MatrixWithNewValues) { // Check if pointer of new matrix is same as previous input matrix
287  OrigMatrix_ = MatrixWithNewValues; // Reset this pointer if not, then check for other attributes
288  if (NumMyRows_ != OrigMatrix_->NumMyRows() ||
291  EPETRA_CHK_ERR(-2); // New matrix not compatible with previous
292  }
293  }
294 
295  Epetra_CrsMatrix * OrigCrsMatrix = dynamic_cast<Epetra_CrsMatrix *>(MatrixWithNewValues);
296 
297 
298  OrigMatrixIsCrsMatrix_ = (OrigCrsMatrix!=0); // If this pointer is non-zero, the cast to CrsMatrix worked
299 
300 
301  // Now copy values and global indices into newly create transpose storage
302 
303  for (i=0;i<NumMyCols_; i++) TransNumNz_[i] = 0; // Reset transpose NumNz counter
304  for (i=0; i<NumMyRows_; i++) {
306  EPETRA_CHK_ERR(OrigCrsMatrix->ExtractMyRowView(i, NumIndices, Values_, Indices_));
307  }
308  else {
310  }
311 
312  int ii = OrigMatrix_->RowMatrixRowMap().GID64(i); // FIXME long long
313  for (j=0; j<NumIndices; j++) {
314  int TransRow = Indices_[j];
315  int loc = TransNumNz_[TransRow];
316  TransIndices_[TransRow][loc] = ii;
317  TransValues_[TransRow][loc] = Values_[j];
318  ++TransNumNz_[TransRow]; // increment counter into current transpose row
319  }
320  }
321 
322  // Build Transpose matrix with some rows being shared across processors.
323  // We will use a view here since the matrix will not be used for anything else
324 
325  const Epetra_Map & TransMap = OrigMatrix_->RowMatrixColMap();
326 
327  Epetra_CrsMatrix TempTransA1(View, TransMap, TransNumNz_);
329  /* Add rows one-at-a-time */
330 
331  for (i=0; i<NumMyCols_; i++)
332  {
335  }
336  // Note: The following call to FillComplete is currently necessary because
337  // some global constants that are needed by the Export () are computed in this routine
338  const Epetra_Map& domain_map = OrigMatrix_->OperatorDomainMap();
339  const Epetra_Map& range_map = OrigMatrix_->OperatorRangeMap();
340 
341  EPETRA_CHK_ERR(TempTransA1.FillComplete(range_map, domain_map, false));
342 
343  // Now that transpose matrix with shared rows is entered, update values of target transpose matrix
344 
345  TransposeMatrix_->PutScalar(0.0); // Zero out all values of the matrix
346 
348 
349  return(0);
350 }
351 
354 {
355  (void)src;//prevents unused variable compiler warning
356 
357  //not currently supported
358  bool throw_error = true;
359  if (throw_error) {
360  std::cerr << std::endl
361  << "Epetra_RowMatrixTransposer::operator= not supported."
362  <<std::endl;
363  throw -1;
364  }
365 
366  return(*this);
367 }
368 
369 #endif // EPETRA_NO_32BIT_GLOBAL_INDICES
Epetra_Map: A class for partitioning vectors and matrices.
Definition: Epetra_Map.h:119
int CreateTranspose(const bool MakeDataContiguous, Epetra_CrsMatrix *&TransposeMatrix, Epetra_Map *TransposeRowMap=0)
Generate a new Epetra_CrsMatrix as the transpose of an Epetra_RowMatrix passed into the constructor...
virtual const Epetra_Map & RowMatrixRowMap() const =0
Returns the Epetra_Map object associated with the rows of this matrix.
int MyGlobalElements(int *MyGlobalElementList) const
Puts list of global elements on this processor into the user-provided array.
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
Insert a list of elements in a given global row of the matrix.
Epetra_RowMatrixTransposer & operator=(const Epetra_RowMatrixTransposer &src)
#define EPETRA_CHK_ERR(a)
Epetra_Export: This class builds an export object for efficient exporting of off-processor elements...
Definition: Epetra_Export.h:62
virtual const Epetra_Map & OperatorDomainMap() const =0
Returns the Epetra_Map object associated with the domain of this operator.
Epetra_RowMatrixTransposer(Epetra_RowMatrix *OrigMatrix)
Primary Epetra_RowMatrixTransposer constructor.
int FillComplete(bool OptimizeDataStorage=true)
Signal that data entry is complete. Perform transformations to local index space. ...
int MakeDataContiguous()
Eliminates memory that is used for construction. Make consecutive row index sections contiguous...
virtual int NumMyCols() const =0
Returns the number of matrix columns owned by the calling processor.
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
Returns a view of the specified local row values via pointers to internal data.
int PutScalar(double ScalarConstant)
Initialize all values in the matrix with constant value.
virtual int NumMyRowEntries(int MyRow, int &NumEntries) const =0
Returns the number of nonzero entries in MyRow.
virtual const Epetra_Map & OperatorRangeMap() const =0
Returns the Epetra_Map object associated with the range of this operator.
long long GID64(int LID) const
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
Exports an Epetra_DistObject using the Epetra_Import object.
int UpdateTransposeValues(Epetra_RowMatrix *MatrixWithNewValues)
Update the values of an already-redistributed problem.
virtual int NumMyRows() const =0
Returns the number of matrix rows owned by the calling processor.
virtual ~Epetra_RowMatrixTransposer()
Epetra_RowMatrixTransposer destructor.
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
Get a view of the elements in a specified local row of the graph.
Epetra_RowMatrixTransposer: A class for transposing an Epetra_RowMatrix object.
Epetra_CrsMatrix: A class for constructing and using real-valued double-precision sparse compressed r...
virtual int ExtractMyRowCopy(int MyRow, int Length, int &NumEntries, double *Values, int *Indices) const =0
Returns a copy of the specified local row in user-provided arrays.
virtual const Epetra_Map & RowMatrixColMap() const =0
Returns the Epetra_Map object associated with the columns of this matrix.
const Epetra_CrsGraph & Graph() const
Returns a reference to the Epetra_CrsGraph object associated with this matrix.
Epetra_RowMatrix: A pure virtual class for using real-valued double-precision row matrices...
#define EPETRA_MAX(x, y)
Epetra_CrsGraph: A class for constructing and using sparse compressed row graphs. ...