|
EpetraExt
Development
|
00001 //@HEADER 00002 // *********************************************************************** 00003 // 00004 // EpetraExt: Epetra Extended - Linear Algebra Services Package 00005 // Copyright (2011) Sandia Corporation 00006 // 00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00008 // the U.S. Government retains certain rights in this software. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 //@HEADER 00041 #include <EpetraExt_BTF_CrsGraph.h> 00042 00043 #include <Epetra_Import.h> 00044 #include <Epetra_CrsGraph.h> 00045 #include <Epetra_Map.h> 00046 00047 #include <vector> 00048 00049 using std::vector; 00050 00051 #define MATTRANS_F77 F77_FUNC(mattrans,MATTRANS) 00052 #define GENBTF_F77 F77_FUNC(genbtf,GENBTF) 00053 extern "C" { 00054 extern void MATTRANS_F77( int*, int*, int*, int*, int*, int* ); 00055 extern void GENBTF_F77( int*, int*, int*, int*, int*, int*, int*, int*, int*, 00056 int*, int*, int*, int*, int*, int*, int*, int*, int*, 00057 int*, int*, int* ); 00058 } 00059 00060 namespace EpetraExt { 00061 00062 CrsGraph_BTF:: 00063 ~CrsGraph_BTF() 00064 { 00065 if( NewRowMap_ ) delete NewRowMap_; 00066 if( NewDomainMap_ ) delete NewDomainMap_; 00067 00068 if( NewGraph_ ) delete NewGraph_; 00069 } 00070 00071 CrsGraph_BTF::NewTypeRef 00072 CrsGraph_BTF:: 00073 operator()( OriginalTypeRef orig ) 00074 { 00075 origObj_ = &orig; 00076 00077 if( orig.RowMap().DistributedGlobal() ) 00078 { cout << "FAIL for Global!\n"; abort(); } 00079 if( orig.IndicesAreGlobal() ) 00080 { cout << "FAIL for Global Indices!\n"; abort(); } 00081 00082 int n = orig.NumMyRows(); 00083 int nnz = orig.NumMyNonzeros(); 00084 00085 //create std CRS format 00086 vector<int> ia(n+1,0); 00087 vector<int> ja(nnz); 00088 int cnt; 00089 for( int i = 0; i < n; ++i ) 00090 { 00091 int * tmpP = &ja[ia[i]]; 00092 orig.ExtractMyRowCopy( i, nnz-ia[i], cnt, tmpP ); 00093 ia[i+1] = ia[i] + cnt; 00094 } 00095 00096 //convert to Fortran indexing 00097 for( int i = 0; i < n+1; ++i ) ++ia[i]; 00098 for( int i = 0; i < nnz; ++i ) ++ja[i]; 00099 00100 #ifdef BTF_VERBOSE 00101 cout << "-----------------------------------------\n"; 00102 cout << "CRS Format Graph\n"; 00103 cout << "-----------------------------------------\n"; 00104 for( int i = 0; i < n; ++i ) 00105 { 00106 cout << i << ": " << ia[i+1] << ": "; 00107 for( int j = ia[i]-1; j<ia[i+1]-1; ++j ) 00108 cout << " " << ja[j]; 00109 cout << endl; 00110 } 00111 cout << "-----------------------------------------\n"; 00112 #endif 00113 00114 vector<int> iat(n+1); 00115 vector<int> jat(nnz); 00116 int * jaf = &ja[0]; 00117 int * iaf = &ia[0]; 00118 int * jatf = &jat[0]; 00119 int * iatf = &iat[0]; 00120 MATTRANS_F77( &n, &n, jaf, iaf, jatf, iatf ); 00121 00122 #ifdef BTF_VERBOSE 00123 cout << "-----------------------------------------\n"; 00124 cout << "CCS Format Graph\n"; 00125 cout << "-----------------------------------------\n"; 00126 for( int i = 0; i < n; ++i ) 00127 { 00128 cout << i << ": " << iat[i+1] << ": "; 00129 for( int j = iat[i]-1; j<iat[i+1]-1; ++j ) 00130 cout << " " << jat[j]; 00131 cout << endl; 00132 } 00133 cout << "-----------------------------------------\n"; 00134 #endif 00135 00136 vector<int> w(10*n); 00137 00138 vector<int> rowperm(n); 00139 vector<int> colperm(n); 00140 00141 //horizontal block 00142 int nhrows, nhcols, hrzcmp; 00143 //square block 00144 int nsrows, sqcmpn; 00145 //vertial block 00146 int nvrows, nvcols, vrtcmp; 00147 00148 vector<int> rcmstr(n+1); 00149 vector<int> ccmstr(n+1); 00150 00151 int msglvl = 0; 00152 int output = 6; 00153 00154 GENBTF_F77( &n, &n, &iat[0], &jat[0], &ia[0], &ja[0], &w[0], 00155 &rowperm[0], &colperm[0], &nhrows, &nhcols, 00156 &hrzcmp, &nsrows, &sqcmpn, &nvrows, &nvcols, &vrtcmp, 00157 &rcmstr[0], &ccmstr[0], &msglvl, &output ); 00158 00159 //convert back to C indexing 00160 for( int i = 0; i < n; ++i ) 00161 { 00162 --rowperm[i]; 00163 --colperm[i]; 00164 } 00165 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i ) 00166 { 00167 --rcmstr[i]; 00168 --ccmstr[i]; 00169 } 00170 00171 #ifdef BTF_VERBOSE 00172 cout << "-----------------------------------------\n"; 00173 cout << "BTF Output\n"; 00174 cout << "-----------------------------------------\n"; 00175 cout << "RowPerm and ColPerm\n"; 00176 for( int i = 0; i<n; ++i ) 00177 cout << rowperm[i] << "\t" << colperm[i] << endl; 00178 if( hrzcmp ) 00179 { 00180 cout << "Num Horizontal: Rows, Cols, Comps\n"; 00181 cout << nhrows << "\t" << nhcols << "\t" << hrzcmp << endl; 00182 } 00183 cout << "Num Square: Rows, Comps\n"; 00184 cout << nsrows << "\t" << sqcmpn << endl; 00185 if( vrtcmp ) 00186 { 00187 cout << "Num Vertical: Rows, Cols, Comps\n"; 00188 cout << nvrows << "\t" << nvcols << "\t" << vrtcmp << endl; 00189 } 00190 cout << "Row, Col of upper left pt in blocks\n"; 00191 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i ) 00192 cout << i << " " << rcmstr[i] << " " << ccmstr[i] << endl; 00193 cout << "-----------------------------------------\n"; 00194 #endif 00195 00196 if( hrzcmp || vrtcmp ) 00197 { cout << "FAILED! hrz cmp's:" << hrzcmp << " vrtcmp: " << vrtcmp << endl; 00198 exit(0); } 00199 00200 //convert rowperm to OLD->NEW 00201 //reverse ordering of permutation to get upper triangular 00202 vector<int> rowperm_t( n ); 00203 vector<int> colperm_t( n ); 00204 for( int i = 0; i < n; ++i ) 00205 { 00206 // rowperm_t[ rowperm[i] ] = n-i; 00207 // colperm[i] = n-colperm[i]; 00208 rowperm_t[i] = rowperm[(n-1)-i]; 00209 colperm_t[i] = colperm[(n-1)-i]; 00210 } 00211 00212 //Generate New Domain and Range Maps 00213 //for now, assume they start out as identical 00214 const Epetra_BlockMap & OldMap = orig.RowMap(); 00215 vector<int> myElements( n ); 00216 OldMap.MyGlobalElements( &myElements[0] ); 00217 00218 vector<int> newDomainElements( n ); 00219 vector<int> newRangeElements( n ); 00220 for( int i = 0; i < n; ++i ) 00221 { 00222 newDomainElements[ i ] = myElements[ rowperm_t[i] ]; 00223 newRangeElements[ i ] = myElements[ colperm_t[i] ]; 00224 cout << i << "\t" << rowperm_t[i] << "\t" << colperm[i] << "\t" << myElements[i] << endl; 00225 } 00226 00227 NewRowMap_ = new Epetra_Map( n, n, &newDomainElements[0], OldMap.IndexBase(), OldMap.Comm() ); 00228 NewDomainMap_ = new Epetra_Map( n, n, &newRangeElements[0], OldMap.IndexBase(), OldMap.Comm() ); 00229 00230 #ifdef BTF_VERBOSE 00231 cout << "New Row Map\n"; 00232 cout << *RowMap << endl; 00233 cout << "New Domain Map\n"; 00234 cout << *DomainMap << endl; 00235 #endif 00236 00237 //Generate New Graph 00238 NewGraph_ = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 ); 00239 Epetra_Import Importer( *NewRowMap_, OldMap ); 00240 NewGraph_->Import( orig, Importer, Insert ); 00241 NewGraph_->FillComplete( *NewDomainMap_, *NewRowMap_ ); 00242 00243 #ifdef BTF_VERBOSE 00244 cout << "New CrsGraph\n"; 00245 cout << *NewGraph_ << endl; 00246 #endif 00247 00248 newObj_ = NewGraph_; 00249 00250 return *NewGraph_; 00251 } 00252 00253 } //namespace EpetraExt
1.7.6.1