Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CrsMatrixTranspose.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Amesos: Direct Sparse Solver Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
25 //
26 // ***********************************************************************
27 // @HEADER
28 
29 //
30 // CrsMatrixTranspose( Epetra_CrsMatrix *In, Epetra_CrsMatrix *Out )
31 // fills the matrix "Out" with the transpose of the matrix "In".
32 //
33 // Notes:
34 // Only works on pseudo-distributed matrices, where all rows are stored
35 // on process 0.
36 // Testing has been limited to square matrices
37 // This implementation requires an extra copy of the matrix as an
38 // intermediate.
39 //
40 // One of the bizarre aspects of this code is that it uses the
41 // results of calls to ExtractMyRowView() to populate the input
42 // to calls to InsertGlobalValues(). This only works because
43 // the code is only designed for matrices that all stored entirely on
44 // process 0.
45 //
46 //
47 #include "CrsMatrixTranspose.h"
48 #include <vector>
49 #include "Epetra_Comm.h"
50 
52 
53  int ierr = 0;
54 
55  int iam = In->Comm().MyPID() ;
56 
57  long long numentries = In->NumGlobalNonzeros64();
58  int NumRowEntries = 0;
59  double *RowValues = 0;
60  int *ColIndices = 0;
61 
62  long long numrows = In->NumGlobalRows64();
63  long long numcols = In->NumGlobalCols64();
64 
65  std::vector <int> Ap( numcols+1 ); // Column i is stored in Aval(Ap[i]..Ap[i+1]-1)
66  std::vector <int> nextAp( numcols+1 ); // Where to store next value in Column i
67 #ifdef EPETRA_NO_32BIT_GLOBAL_INDICES
68  std::vector <long long> Ai( EPETRA_MAX( numcols, numentries) ) ; // Row indices
69 #else
70  std::vector <int> Ai( EPETRA_MAX( numcols, numentries) ) ; // Row indices
71 #endif
72  std::vector <double> Aval( EPETRA_MAX( numcols, numentries) ) ;
73 
74  if ( iam == 0 ) {
75 
76  assert( In->NumMyRows() == In->NumGlobalRows64() ) ;
77  //
78  // Count the number of entries in each column
79  //
80  std::vector <int>RowsPerCol( numcols ) ;
81  for ( int i = 0 ; i < numcols ; i++ ) RowsPerCol[i] = 0 ;
82  for ( int MyRow = 0; MyRow <numrows; MyRow++ ) {
83  ierr = In->ExtractMyRowView( MyRow, NumRowEntries, RowValues, ColIndices );
84  assert( ierr == 0 ) ;
85  for ( int j = 0; j < NumRowEntries; j++ ) {
86  RowsPerCol[ ColIndices[j] ] ++ ;
87  }
88  }
89  //
90  // Set Ap and nextAp based on RowsPerCol
91  //
92  Ap[0] = 0 ;
93  for ( int i = 0 ; i < numcols ; i++ ) {
94  Ap[i+1]= Ap[i] + RowsPerCol[i] ;
95  nextAp[i] = Ap[i];
96  }
97  //
98  // Populate Ai and Aval
99  //
100  for ( int MyRow = 0; MyRow <numrows; MyRow++ ) {
101  ierr = In->ExtractMyRowView( MyRow, NumRowEntries, RowValues, ColIndices );
102  assert( ierr == 0 ) ;
103  for ( int j = 0; j < NumRowEntries; j++ ) {
104  Ai[ nextAp[ ColIndices[j] ] ] = MyRow ;
105  Aval[ nextAp[ ColIndices[j] ] ] = RowValues[j] ;
106  nextAp[ ColIndices[j] ] ++ ;
107  }
108  }
109 
110  //
111  // Insert values into Out
112  //
113  for ( int MyRow = 0; MyRow <numrows; MyRow++ ) {
114  int NumInCol = Ap[MyRow+1] - Ap[MyRow] ;
115 #if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
116  Out->InsertGlobalValues( MyRow, NumInCol, &Aval[Ap[MyRow]],
117  &Ai[Ap[MyRow]] );
118 #endif
119  assert( Out->IndicesAreGlobal() ) ;
120  }
121  } else {
122  assert( In->NumMyRows() == 0 ) ;
123  }
124 
125  ierr = Out->FillComplete();
126  assert( ierr==0 ) ;
127  return 0 ;
128 }
long long NumGlobalRows64() const
long long NumGlobalCols64() const
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
int CrsMatrixTranspose(Epetra_CrsMatrix *In, Epetra_CrsMatrix *Out)
virtual int MyPID() const =0
int FillComplete(bool OptimizeDataStorage=true)
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
long long NumGlobalNonzeros64() const
int NumMyRows() const
bool IndicesAreGlobal() const
const Epetra_Comm & Comm() const
#define EPETRA_MAX(x, y)