// ================================================ ====== ==== ==== == = // Apply the preconditioner to an Epetra_MultiVector X, puts the result in Y int ML_Epetra::RefMaxwellPreconditioner::ApplyInverse(const Epetra_MultiVector& B, Epetra_MultiVector& X_) const { int rv; /* Sanity Checks */ if (!B.Map().SameAs(*DomainMap_)) ML_CHK_ERR(-1); if (B.NumVectors() != X_.NumVectors()) ML_CHK_ERR(-1); /* Check for zero RHS */ bool norm0=true; double *norm=new double[B.NumVectors()]; B.Norm2(norm); for(int i=0;norm0==true && i<B.NumVectors();i++) norm0=norm0 && (norm[i]==0); delete [] norm; if(norm0) return 0; /* Build new work vector X */ Epetra_MultiVector X(X_.Map(),X_.NumVectors()); X.PutScalar(0); /* What mode to run in? */ if(mode=="212") rv=ApplyInverse_Implicit_212(B,X); else if(mode=="additive") rv=ApplyInverse_Implicit_Additive(B,X); else if(mode=="121") rv=ApplyInverse_Implicit_121(B,X); else {fprintf(stderr,"%s","RefMaxwellPreconditioner ERROR: Invalid ApplyInverse mode set in Teuchos list");ML_CHK_ERR(-2);} ML_CHK_ERR(rv); /* Copy work vector to output */ X_=X; /* Timer Stuff */ #ifdef ML_TIMING ML_Epetra::RefMaxwellPreconditioner* This = const_cast<ML_Epetra::RefMaxwellPreconditioner *>(this); if(FirstApplication_){ This->FirstApplication_=false; This->FirstApplicationTime_=ApplicationTime_; }/*end if*/ This->NumApplications_++; #endif return 0; }/*end ApplyInverse*/
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv, 0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int nProcs, myPID ; Teuchos::ParameterList pLUList ; // ParaLU parameters Teuchos::ParameterList isoList ; // Isorropia parameters Teuchos::ParameterList shyLUList ; // shyLU parameters Teuchos::ParameterList ifpackList ; // shyLU parameters string ipFileName = "ShyLU.xml"; // TODO : Accept as i/p nProcs = mpiSession.getNProc(); myPID = Comm.MyPID(); if (myPID == 0) { cout <<"Parallel execution: nProcs="<< nProcs << endl; } // =================== Read input xml file ============================= Teuchos::updateParametersFromXmlFile(ipFileName, &pLUList); isoList = pLUList.sublist("Isorropia Input"); shyLUList = pLUList.sublist("ShyLU Input"); shyLUList.set("Outer Solver Library", "AztecOO"); // Get matrix market file name string MMFileName = Teuchos::getParameter<string>(pLUList, "mm_file"); string prec_type = Teuchos::getParameter<string>(pLUList, "preconditioner"); int maxiters = Teuchos::getParameter<int>(pLUList, "Outer Solver MaxIters"); double tol = Teuchos::getParameter<double>(pLUList, "Outer Solver Tolerance"); string rhsFileName = pLUList.get<string>("rhs_file", ""); if (myPID == 0) { cout << "Input :" << endl; cout << "ParaLU params " << endl; pLUList.print(std::cout, 2, true, true); cout << "Matrix market file name: " << MMFileName << endl; } // ==================== Read input Matrix ============================== Epetra_CrsMatrix *A; Epetra_MultiVector *b1; int err = EpetraExt::MatrixMarketFileToCrsMatrix(MMFileName.c_str(), Comm, A); //EpetraExt::MatlabFileToCrsMatrix(MMFileName.c_str(), Comm, A); //assert(err != 0); //cout <<"Done reading the matrix"<< endl; int n = A->NumGlobalRows(); //cout <<"n="<< n << endl; // Create input vectors Epetra_Map vecMap(n, 0, Comm); if (rhsFileName != "") { err = EpetraExt::MatrixMarketFileToMultiVector(rhsFileName.c_str(), vecMap, b1); } else { b1 = new Epetra_MultiVector(vecMap, 1, false); b1->PutScalar(1.0); } Epetra_MultiVector x(vecMap, 1); //cout << "Created the vectors" << endl; // Partition the matrix with hypergraph partitioning and redisstribute Isorropia::Epetra::Partitioner *partitioner = new Isorropia::Epetra::Partitioner(A, isoList, false); partitioner->partition(); Isorropia::Epetra::Redistributor rd(partitioner); Epetra_CrsMatrix *newA; Epetra_MultiVector *newX, *newB; rd.redistribute(*A, newA); delete A; A = newA; rd.redistribute(x, newX); rd.redistribute(*b1, newB); Epetra_LinearProblem problem(A, newX, newB); AztecOO solver(problem); ifpackList ; Ifpack_Preconditioner *prec; ML_Epetra::MultiLevelPreconditioner *MLprec; if (prec_type.compare("ShyLU") == 0) { prec = new Ifpack_ShyLU(A); prec->SetParameters(shyLUList); prec->Initialize(); prec->Compute(); //(dynamic_cast<Ifpack_ShyLU *>(prec))->JustTryIt(); //cout << " Going to set it in solver" << endl ; solver.SetPrecOperator(prec); //cout << " Done setting the solver" << endl ; } else if (prec_type.compare("ILU") == 0) { ifpackList.set( "fact: level-of-fill", 1 ); prec = new Ifpack_ILU(A); prec->SetParameters(ifpackList); prec->Initialize(); prec->Compute(); solver.SetPrecOperator(prec); } else if (prec_type.compare("ILUT") == 0) { ifpackList.set( "fact: ilut level-of-fill", 2 ); ifpackList.set( "fact: drop tolerance", 1e-8); prec = new Ifpack_ILUT(A); prec->SetParameters(ifpackList); prec->Initialize(); prec->Compute(); solver.SetPrecOperator(prec); } else if (prec_type.compare("ML") == 0) { Teuchos::ParameterList mlList; // TODO : Take it from i/p MLprec = new ML_Epetra::MultiLevelPreconditioner(*A, mlList, true); solver.SetPrecOperator(MLprec); } solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetMatrixName(333); //solver.SetAztecOption(AZ_output, 1); //solver.SetAztecOption(AZ_conv, AZ_Anorm); //cout << "Going to iterate for the global problem" << endl; solver.Iterate(maxiters, tol); // compute ||Ax - b|| double Norm; Epetra_MultiVector Ax(vecMap, 1); Epetra_MultiVector *newAx; rd.redistribute(Ax, newAx); A->Multiply(false, *newX, *newAx); newAx->Update(1.0, *newB, -1.0); newAx->Norm2(&Norm); double ANorm = A->NormOne(); cout << "|Ax-b |/|A| = " << Norm/ANorm << endl; delete newAx; if (prec_type.compare("ML") == 0) { delete MLprec; } else { delete prec; } delete b1; delete newX; delete newB; delete A; delete partitioner; }
// // Amesos_TestMultiSolver.cpp reads in a matrix in Harwell-Boeing format, // calls one of the sparse direct solvers, using blocked right hand sides // and computes the error and residual. // // TestSolver ignores the Harwell-Boeing right hand sides, creating // random right hand sides instead. // // Amesos_TestMultiSolver can test either A x = b or A^T x = b. // This can be a bit confusing because sparse direct solvers // use compressed column storage - the transpose of Trilinos' // sparse row storage. // // Matrices: // readA - Serial. As read from the file. // transposeA - Serial. The transpose of readA. // serialA - if (transpose) then transposeA else readA // distributedA - readA distributed to all processes // passA - if ( distributed ) then distributedA else serialA // // int Amesos_TestMultiSolver( Epetra_Comm &Comm, char *matrix_file, int numsolves, SparseSolverType SparseSolver, bool transpose, int special, AMESOS_MatrixType matrix_type ) { int iam = Comm.MyPID() ; // int hatever; // if ( iam == 0 ) std::cin >> hatever ; Comm.Barrier(); Epetra_Map * readMap; Epetra_CrsMatrix * readA; Epetra_Vector * readx; Epetra_Vector * readb; Epetra_Vector * readxexact; std::string FileName = matrix_file ; int FN_Size = FileName.size() ; std::string LastFiveBytes = FileName.substr( EPETRA_MAX(0,FN_Size-5), FN_Size ); std::string LastFourBytes = FileName.substr( EPETRA_MAX(0,FN_Size-4), FN_Size ); bool NonContiguousMap = false; if ( LastFiveBytes == ".triU" ) { NonContiguousMap = true; // Call routine to read in unsymmetric Triplet matrix EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra( matrix_file, false, Comm, readMap, readA, readx, readb, readxexact, NonContiguousMap ) ); } else { if ( LastFiveBytes == ".triS" ) { NonContiguousMap = true; // Call routine to read in symmetric Triplet matrix EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra( matrix_file, true, Comm, readMap, readA, readx, readb, readxexact, NonContiguousMap ) ); } else { if ( LastFourBytes == ".mtx" ) { EPETRA_CHK_ERR( Trilinos_Util_ReadMatrixMarket2Epetra( matrix_file, Comm, readMap, readA, readx, readb, readxexact) ); } else { // Call routine to read in HB problem Trilinos_Util_ReadHb2Epetra( matrix_file, Comm, readMap, readA, readx, readb, readxexact) ; } } } Epetra_CrsMatrix transposeA(Copy, *readMap, 0); Epetra_CrsMatrix *serialA ; if ( transpose ) { assert( CrsMatrixTranspose( readA, &transposeA ) == 0 ); serialA = &transposeA ; } else { serialA = readA ; } // Create uniform distributed map Epetra_Map map(readMap->NumGlobalElements(), 0, Comm); Epetra_Map* map_; if( NonContiguousMap ) { // // map gives us NumMyElements and MyFirstElement; // int NumGlobalElements = readMap->NumGlobalElements(); int NumMyElements = map.NumMyElements(); int MyFirstElement = map.MinMyGID(); std::vector<int> MapMap_( NumGlobalElements ); readMap->MyGlobalElements( &MapMap_[0] ) ; Comm.Broadcast( &MapMap_[0], NumGlobalElements, 0 ) ; map_ = new Epetra_Map( NumGlobalElements, NumMyElements, &MapMap_[MyFirstElement], 0, Comm); } else { map_ = new Epetra_Map( map ) ; } // Create Exporter to distribute read-in matrix and vectors Epetra_Export exporter(*readMap, *map_); Epetra_CrsMatrix A(Copy, *map_, 0); Epetra_RowMatrix * passA = 0; Epetra_MultiVector * passx = 0; Epetra_MultiVector * passb = 0; Epetra_MultiVector * passxexact = 0; Epetra_MultiVector * passresid = 0; Epetra_MultiVector * passtmp = 0; Epetra_MultiVector x(*map_,numsolves); Epetra_MultiVector b(*map_,numsolves); Epetra_MultiVector xexact(*map_,numsolves); Epetra_MultiVector resid(*map_,numsolves); Epetra_MultiVector tmp(*map_,numsolves); Epetra_MultiVector serialx(*readMap,numsolves); Epetra_MultiVector serialb(*readMap,numsolves); Epetra_MultiVector serialxexact(*readMap,numsolves); Epetra_MultiVector serialresid(*readMap,numsolves); Epetra_MultiVector serialtmp(*readMap,numsolves); bool distribute_matrix = ( matrix_type == AMESOS_Distributed ) ; if ( distribute_matrix ) { // // Initialize x, b and xexact to the values read in from the file // A.Export(*serialA, exporter, Add); Comm.Barrier(); assert(A.FillComplete()==0); Comm.Barrier(); passA = &A; passx = &x; passb = &b; passxexact = &xexact; passresid = &resid; passtmp = &tmp; } else { passA = serialA; passx = &serialx; passb = &serialb; passxexact = &serialxexact; passresid = &serialresid; passtmp = &serialtmp; } passxexact->SetSeed(131) ; passxexact->Random(); passx->SetSeed(11231) ; passx->Random(); passb->PutScalar( 0.0 ); passA->Multiply( transpose, *passxexact, *passb ) ; Epetra_MultiVector CopyB( *passb ) ; double Anorm = passA->NormInf() ; SparseDirectTimingVars::SS_Result.Set_Anorm(Anorm) ; Epetra_LinearProblem Problem( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ); double max_resid = 0.0; for ( int j = 0 ; j < special+1 ; j++ ) { Epetra_Time TotalTime( Comm ) ; if ( false ) { #ifdef TEST_UMFPACK unused code } else if ( SparseSolver == UMFPACK ) { UmfpackOO umfpack( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ) ; umfpack.SetTrans( transpose ) ; umfpack.Solve() ; #endif #ifdef TEST_SUPERLU } else if ( SparseSolver == SuperLU ) { SuperluserialOO superluserial( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ) ; superluserial.SetPermc( SuperLU_permc ) ; superluserial.SetTrans( transpose ) ; superluserial.SetUseDGSSV( special == 0 ) ; superluserial.Solve() ; #endif #ifdef HAVE_AMESOS_SLUD } else if ( SparseSolver == SuperLUdist ) { SuperludistOO superludist( Problem ) ; superludist.SetTrans( transpose ) ; EPETRA_CHK_ERR( superludist.Solve( true ) ) ; #endif #ifdef HAVE_AMESOS_SLUD2 } else if ( SparseSolver == SuperLUdist2 ) { Superludist2_OO superludist2( Problem ) ; superludist2.SetTrans( transpose ) ; EPETRA_CHK_ERR( superludist2.Solve( true ) ) ; #endif #ifdef TEST_SPOOLES } else if ( SparseSolver == SPOOLES ) { SpoolesOO spooles( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ) ; spooles.SetTrans( transpose ) ; spooles.Solve() ; #endif #ifdef HAVE_AMESOS_DSCPACK } else if ( SparseSolver == DSCPACK ) { Teuchos::ParameterList ParamList ; Amesos_Dscpack dscpack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( dscpack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( dscpack.Solve( ) ); #endif #ifdef HAVE_AMESOS_UMFPACK } else if ( SparseSolver == UMFPACK ) { Teuchos::ParameterList ParamList ; Amesos_Umfpack umfpack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( umfpack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( umfpack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( umfpack.Solve( ) ); #endif #ifdef HAVE_AMESOS_KLU } else if ( SparseSolver == KLU ) { Teuchos::ParameterList ParamList ; Amesos_Klu klu( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( klu.SetParameters( ParamList ) ); EPETRA_CHK_ERR( klu.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( klu.SymbolicFactorization( ) ); EPETRA_CHK_ERR( klu.NumericFactorization( ) ); EPETRA_CHK_ERR( klu.Solve( ) ); #endif #ifdef HAVE_AMESOS_PARAKLETE } else if ( SparseSolver == PARAKLETE ) { Teuchos::ParameterList ParamList ; Amesos_Paraklete paraklete( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( paraklete.SetParameters( ParamList ) ); EPETRA_CHK_ERR( paraklete.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( paraklete.SymbolicFactorization( ) ); EPETRA_CHK_ERR( paraklete.NumericFactorization( ) ); EPETRA_CHK_ERR( paraklete.Solve( ) ); #endif #ifdef HAVE_AMESOS_SLUS } else if ( SparseSolver == SuperLU ) { Epetra_SLU superluserial( &Problem ) ; EPETRA_CHK_ERR( superluserial.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( superluserial.SymbolicFactorization( ) ); EPETRA_CHK_ERR( superluserial.NumericFactorization( ) ); EPETRA_CHK_ERR( superluserial.Solve( ) ); #endif #ifdef HAVE_AMESOS_LAPACK } else if ( SparseSolver == LAPACK ) { Teuchos::ParameterList ParamList ; ParamList.set( "MaxProcs", -3 ); Amesos_Lapack lapack( Problem ) ; EPETRA_CHK_ERR( lapack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( lapack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( lapack.NumericFactorization( ) ); EPETRA_CHK_ERR( lapack.Solve( ) ); #endif #ifdef HAVE_AMESOS_TAUCS } else if ( SparseSolver == TAUCS ) { Teuchos::ParameterList ParamList ; Amesos_Taucs taucs( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( taucs.SetParameters( ParamList ) ); EPETRA_CHK_ERR( taucs.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( taucs.SymbolicFactorization( ) ); EPETRA_CHK_ERR( taucs.NumericFactorization( ) ); EPETRA_CHK_ERR( taucs.Solve( ) ); #endif #ifdef HAVE_AMESOS_PARDISO } else if ( SparseSolver == PARDISO ) { Teuchos::ParameterList ParamList ; Amesos_Pardiso pardiso( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( pardiso.SetParameters( ParamList ) ); EPETRA_CHK_ERR( pardiso.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( pardiso.SymbolicFactorization( ) ); EPETRA_CHK_ERR( pardiso.NumericFactorization( ) ); EPETRA_CHK_ERR( pardiso.Solve( ) ); #endif #ifdef HAVE_AMESOS_PARKLETE } else if ( SparseSolver == PARKLETE ) { Teuchos::ParameterList ParamList ; Amesos_Parklete parklete( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( parklete.SetParameters( ParamList ) ); EPETRA_CHK_ERR( parklete.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( parklete.SymbolicFactorization( ) ); EPETRA_CHK_ERR( parklete.NumericFactorization( ) ); EPETRA_CHK_ERR( parklete.Solve( ) ); #endif #ifdef HAVE_AMESOS_MUMPS } else if ( SparseSolver == MUMPS ) { Teuchos::ParameterList ParamList ; Amesos_Mumps mumps( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( mumps.SetParameters( ParamList ) ); EPETRA_CHK_ERR( mumps.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( mumps.SymbolicFactorization( ) ); EPETRA_CHK_ERR( mumps.NumericFactorization( ) ); EPETRA_CHK_ERR( mumps.Solve( ) ); #endif #ifdef HAVE_AMESOS_SCALAPACK } else if ( SparseSolver == SCALAPACK ) { Teuchos::ParameterList ParamList ; Amesos_Scalapack scalapack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( scalapack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( scalapack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( scalapack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( scalapack.NumericFactorization( ) ); EPETRA_CHK_ERR( scalapack.Solve( ) ); #endif #ifdef HAVE_AMESOS_SUPERLUDIST } else if ( SparseSolver == SUPERLUDIST ) { Teuchos::ParameterList ParamList ; Amesos_Superludist superludist( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( superludist.SetParameters( ParamList ) ); EPETRA_CHK_ERR( superludist.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( superludist.SymbolicFactorization( ) ); EPETRA_CHK_ERR( superludist.NumericFactorization( ) ); EPETRA_CHK_ERR( superludist.Solve( ) ); #endif #ifdef HAVE_AMESOS_SUPERLU } else if ( SparseSolver == SUPERLU ) { Teuchos::ParameterList ParamList ; Amesos_Superlu superlu( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( superlu.SetParameters( ParamList ) ); EPETRA_CHK_ERR( superlu.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( superlu.SymbolicFactorization( ) ); EPETRA_CHK_ERR( superlu.NumericFactorization( ) ); EPETRA_CHK_ERR( superlu.Solve( ) ); #endif #ifdef TEST_SPOOLESSERIAL } else if ( SparseSolver == SPOOLESSERIAL ) { SpoolesserialOO spoolesserial( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ) ; spoolesserial.Solve() ; #endif } else { SparseDirectTimingVars::log_file << "Solver not implemented yet" << std::endl ; std::cerr << "\n\n#################### Requested solver not available (Or not tested with blocked RHS) on this platform #####################\n" << std::endl ; } SparseDirectTimingVars::SS_Result.Set_Total_Time( TotalTime.ElapsedTime() ); // SparseDirectTimingVars::SS_Result.Set_First_Time( 0.0 ); // SparseDirectTimingVars::SS_Result.Set_Middle_Time( 0.0 ); // SparseDirectTimingVars::SS_Result.Set_Last_Time( 0.0 ); // // Compute the error = norm(xcomp - xexact ) // std::vector <double> error(numsolves) ; double max_error = 0.0; passresid->Update(1.0, *passx, -1.0, *passxexact, 0.0); passresid->Norm2(&error[0]); for ( int i = 0 ; i< numsolves; i++ ) if ( error[i] > max_error ) max_error = error[i] ; SparseDirectTimingVars::SS_Result.Set_Error(max_error) ; // passxexact->Norm2(&error[0] ) ; // passx->Norm2(&error ) ; // // Compute the residual = norm(Ax - b) // std::vector <double> residual(numsolves) ; passtmp->PutScalar(0.0); passA->Multiply( transpose, *passx, *passtmp); passresid->Update(1.0, *passtmp, -1.0, *passb, 0.0); // passresid->Update(1.0, *passtmp, -1.0, CopyB, 0.0); passresid->Norm2(&residual[0]); for ( int i = 0 ; i< numsolves; i++ ) if ( residual[i] > max_resid ) max_resid = residual[i] ; SparseDirectTimingVars::SS_Result.Set_Residual(max_resid) ; std::vector <double> bnorm(numsolves); passb->Norm2( &bnorm[0] ) ; SparseDirectTimingVars::SS_Result.Set_Bnorm(bnorm[0]) ; std::vector <double> xnorm(numsolves); passx->Norm2( &xnorm[0] ) ; SparseDirectTimingVars::SS_Result.Set_Xnorm(xnorm[0]) ; if ( false && iam == 0 ) { std::cout << " Amesos_TestMutliSolver.cpp " << std::endl ; for ( int i = 0 ; i< numsolves && i < 10 ; i++ ) { std::cout << "i=" << i << " error = " << error[i] << " xnorm = " << xnorm[i] << " residual = " << residual[i] << " bnorm = " << bnorm[i] << std::endl ; } std::cout << std::endl << " max_resid = " << max_resid ; std::cout << " max_error = " << max_error << std::endl ; std::cout << " Get_residual() again = " << SparseDirectTimingVars::SS_Result.Get_Residual() << std::endl ; } } delete readA; delete readx; delete readb; delete readxexact; delete readMap; delete map_; Comm.Barrier(); return 0 ; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv, 0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int nProcs, myPID ; Teuchos::ParameterList pLUList ; // ParaLU parameters Teuchos::ParameterList isoList ; // Isorropia parameters string ipFileName = "ShyLU.xml"; // TODO : Accept as i/p nProcs = mpiSession.getNProc(); myPID = Comm.MyPID(); if (myPID == 0) { cout <<"Parallel execution: nProcs="<< nProcs << endl; } // =================== Read input xml file ============================= Teuchos::updateParametersFromXmlFile(ipFileName, &pLUList); isoList = pLUList.sublist("Isorropia Input"); // Get matrix market file name string MMFileName = Teuchos::getParameter<string>(pLUList, "mm_file"); string prec_type = Teuchos::getParameter<string>(pLUList, "preconditioner"); if (myPID == 0) { cout << "Input :" << endl; cout << "ParaLU params " << endl; pLUList.print(std::cout, 2, true, true); cout << "Matrix market file name: " << MMFileName << endl; } // ==================== Read input Matrix ============================== Epetra_CrsMatrix *A; int err = EpetraExt::MatrixMarketFileToCrsMatrix(MMFileName.c_str(), Comm, A); //EpetraExt::MatlabFileToCrsMatrix(MMFileName.c_str(), Comm, A); //assert(err != 0); cout <<"Done reading the matrix"<< endl; int n = A->NumGlobalRows(); cout <<"n="<< n << endl; // Create input vectors Epetra_Map vecMap(n, 0, Comm); Epetra_MultiVector x(vecMap, 1); Epetra_MultiVector b(vecMap, 1, false); b.PutScalar(1.0); // TODO : Accept it as input // Partition the matrix with hypergraph partitioning and redisstribute Isorropia::Epetra::Partitioner *partitioner = new Isorropia::Epetra::Partitioner(A, isoList, false); partitioner->partition(); Isorropia::Epetra::Redistributor rd(partitioner); Epetra_CrsMatrix *newA; Epetra_MultiVector *newX, *newB; rd.redistribute(*A, newA); delete A; A = newA; rd.redistribute(x, newX); rd.redistribute(b, newB); Epetra_LinearProblem problem(A, newX, newB); Amesos Factory; char* SolverType = "Amesos_Klu"; bool IsAvailable = Factory.Query(SolverType); Epetra_LinearProblem *LP = new Epetra_LinearProblem(); LP->SetOperator(A); LP->SetLHS(newX); LP->SetRHS(newB); Amesos_BaseSolver *Solver = Factory.Create(SolverType, *LP); Solver->SymbolicFactorization(); Teuchos::Time ftime("setup time"); ftime.start(); Solver->NumericFactorization(); cout << "Numeric Factorization" << endl; Solver->Solve(); cout << "Solve done" << endl; ftime.stop(); cout << "Time to setup" << ftime.totalElapsedTime() << endl; // compute ||Ax - b|| double Norm; Epetra_MultiVector Ax(vecMap, 1); Epetra_MultiVector *newAx; rd.redistribute(Ax, newAx); A->Multiply(false, *newX, *newAx); newAx->Update(1.0, *newB, -1.0); newAx->Norm2(&Norm); double ANorm = A->NormOne(); cout << "|Ax-b |/|A| = " << Norm/ANorm << endl; delete newAx; delete newX; delete newB; delete A; delete partitioner; }