29 #ifdef HAVE_AMESOS_CSPARSE
38 using namespace Teuchos;
55 Amesos_CSparse::~Amesos_CSparse()
60 if ((verbose_ && PrintTiming_) || verbose_ == 2) PrintTiming();
61 if ((verbose_ && PrintStatus_) || verbose_ == 2) PrintStatus();
65 int Amesos_CSparse::ConvertToSerial()
73 #ifdef HAVE_AMESOS_EPETRAEXT
74 const Epetra_Map& OriginalMap = Matrix_->RowMatrixRowMap();
77 UseTranspose()?GetProblem()->GetOperator()->OperatorRangeMap():
78 GetProblem()->GetOperator()->OperatorDomainMap();
80 UseTranspose()?GetProblem()->GetOperator()->OperatorDomainMap():
81 GetProblem()->GetOperator()->OperatorRangeMap();
88 StdIndexMatrix_ = StdIndex_->StandardizeIndex( CrsMatrixA_ );
90 std::cerr <<
"Amesos_CSparse requires EpetraExt to reindex matrices." << std::endl
94 StdIndexMatrix_ = Matrix_ ;
101 if (
Comm().MyPID() == 0)
102 NumMyRows = NumGlobalRows;
105 if (SerialMap_.get() == 0)
109 if (Importer_.get() == 0)
113 if (SerialCrsMatrix_.get() == 0)
116 AMESOS_CHK_ERR(SerialCrsMatrix().Import(*StdIndexMatrix_, Importer(), Add));
120 SerialMatrix_ =
rcp(SerialCrsMatrix_.get(),
false);
122 MtxRedistTime_ = AddTime(
"Total matrix redistribution time", MtxRedistTime_);
128 int Amesos_CSparse::ConvertToCSparse()
131 #ifdef HAVE_AMESOS_CSPARSE
135 if (
Comm().MyPID() == 0)
137 csMatrix.p = (ptrdiff_t *) malloc((SerialMatrix().NumMyRows()+1)*
sizeof(ptrdiff_t));
138 csMatrix.i = (ptrdiff_t *) malloc(SerialMatrix().NumMyNonzeros()*
sizeof(ptrdiff_t));
139 csMatrix.x = (
double *) malloc(SerialMatrix().NumMyNonzeros()*
sizeof(double));
140 csMatrix.nzmax = SerialMatrix().NumMyNonzeros();
141 csMatrix.m = SerialMatrix().NumMyRows();
142 csMatrix.n = SerialMatrix().NumMyRows();
145 int MaxNumEntries = SerialMatrix().MaxNumEntries();
146 std::vector<int> Indices(MaxNumEntries);
147 std::vector<double> Values(MaxNumEntries);
152 for (
int i = 0 ; i < SerialMatrix().NumMyRows() ; ++i)
154 int ierr, NumEntriesThisRow;
155 ierr = SerialMatrix().ExtractMyRowCopy(i, MaxNumEntries,
157 &Values[0], &Indices[0]);
161 csMatrix.p[i + 1] = csMatrix.p[i] + NumEntriesThisRow;
163 for (
int j = 0 ; j < NumEntriesThisRow ; ++j)
166 Values[j] += AddToDiag_;
168 csMatrix.i[count] = Indices[j];
169 csMatrix.x[count] = Values[j];
174 if (count != SerialMatrix().NumMyNonzeros())
178 csTranMatrix = cs_transpose(&csMatrix, 1);
185 MtxConvTime_ = AddTime(
"Total matrix conversion time", MtxConvTime_);
199 SetStatusParameters( ParameterList );
201 SetControlParameters( ParameterList );
215 int Amesos_CSparse::PerformSymbolicFactorization()
217 #ifdef HAVE_AMESOS_CSPARSE
221 if (
Comm().MyPID() == 0)
229 csSymbolic = cs_sqr(2, csTranMatrix, 0);
234 SymFactTime_ = AddTime(
"Total symbolic factorization time", SymFactTime_);
244 int Amesos_CSparse::PerformNumericFactorization( )
246 #ifdef HAVE_AMESOS_CSPARSE
249 if (
Comm().MyPID() == 0)
253 csNumeric = cs_lu(csTranMatrix, csSymbolic, 1e-15);
258 NumFactTime_ = AddTime(
"Total numeric factorization time", NumFactTime_);
268 bool Amesos_CSparse::MatrixShapeOK()
const
272 if (GetProblem()->GetOperator()->OperatorRangeMap().NumGlobalPoints() !=
273 GetProblem()->GetOperator()->OperatorDomainMap().NumGlobalPoints() )
281 int Amesos_CSparse::SymbolicFactorization()
283 IsSymbolicFactorizationOK_ =
false;
284 IsNumericFactorizationOK_ =
false;
291 Map_ = &(Matrix_->RowMatrixRowMap());
300 if (
Comm().NumProc() != 1)
304 SerialMap_ =
rcp(const_cast<Epetra_Map*>(&Map()),
false);
305 SerialMatrix_ =
rcp(const_cast<Epetra_RowMatrix*>(&Matrix()),
false);
315 PerformSymbolicFactorization();
317 IsSymbolicFactorizationOK_ =
true;
323 int Amesos_CSparse::NumericFactorization()
325 IsNumericFactorizationOK_ =
false;
327 if (IsSymbolicFactorizationOK_ ==
false)
336 PerformNumericFactorization();
338 IsNumericFactorizationOK_ =
true;
344 int Amesos_CSparse::Solve()
346 #ifdef HAVE_AMESOS_CSPARSE
350 #ifdef HAVE_AMESOS_EPETRAEXT
355 if (IsNumericFactorizationOK_ ==
false)
361 if ((X == 0) || (B == 0))
364 int NumVectors = X->NumVectors();
365 if (NumVectors != B->NumVectors())
369 #ifdef HAVE_AMESOS_EPETRAEXT
370 vecX_rcp = StdIndexDomain_->StandardizeIndex( *X ) ;
371 vecB_rcp = StdIndexRange_->StandardizeIndex( *B ) ;
392 SerialB->Import(*vecB,Importer(),Insert);
394 VecRedistTime_ = AddTime(
"Total vector redistribution time", VecRedistTime_);
398 if (
Comm().MyPID() == 0)
400 double* SerialXValues;
401 double* SerialBValues;
410 int n = SerialMatrix().NumMyRows();
412 double *x = (
double *) malloc(n *
sizeof(
double));
414 for (
int i = 0 ; i < NumVectors ; ++i)
417 cs_ipvec(csNumeric->pinv, SerialBValues+i*n, x, n);
418 cs_lsolve(csNumeric->L, x);
419 cs_usolve(csNumeric->U, x);
420 cs_ipvec(csSymbolic->q, x, SerialXValues+i*n, n);
427 SolveTime_ = AddTime(
"Total solve time", SolveTime_);
433 vecX->Export(*SerialX, Importer(), Insert);
437 VecRedistTime_ = AddTime(
"Total vector redistribution time", VecRedistTime_);
439 if (ComputeTrueResidual_)
440 ComputeTrueResidual(Matrix(), *X, *B, UseTranspose(),
"Amesos_CSparse");
442 if (ComputeVectorNorms_)
443 ComputeVectorNorms(*X, *B,
"Amesos_CSparse");
455 void Amesos_CSparse::PrintStatus()
const
457 if (Problem_->GetOperator() == 0 ||
Comm().MyPID() != 0)
460 std::string p =
"Amesos_CSparse : ";
469 void Amesos_CSparse::PrintTiming()
const
471 if (Problem_->GetOperator() == 0 ||
Comm().MyPID() != 0)
474 double ConTime = GetTime(MtxConvTime_);
475 double MatTime = GetTime(MtxRedistTime_);
476 double VecTime = GetTime(VecRedistTime_);
477 double SymTime = GetTime(SymFactTime_);
478 double NumTime = GetTime(NumFactTime_);
479 double SolTime = GetTime(SolveTime_);
481 if (NumSymbolicFact_)
482 SymTime /= NumSymbolicFact_;
485 NumTime /= NumNumericFact_;
488 SolTime /= NumSolve_;
490 std::string p =
"Amesos_CSparse : ";
493 std::cout << p <<
"Time to convert matrix to Csparse format = "
494 << ConTime <<
" (s)" << std::endl;
495 std::cout << p <<
"Time to redistribute matrix = "
496 << MatTime <<
" (s)" << std::endl;
497 std::cout << p <<
"Time to redistribute vectors = "
498 << VecTime <<
" (s)" << std::endl;
499 std::cout << p <<
"Number of symbolic factorizations = "
500 << NumSymbolicFact_ << std::endl;
501 std::cout << p <<
"Time for sym fact = "
502 << SymTime <<
" (s), avg = " << SymTime <<
" (s)" << std::endl;
503 std::cout << p <<
"Number of numeric factorizations = "
504 << NumNumericFact_ << std::endl;
505 std::cout << p <<
"Time for num fact = "
506 << NumTime <<
" (s), avg = " << NumTime <<
" (s)" << std::endl;
507 std::cout << p <<
"Number of solve phases = "
508 << NumSolve_ << std::endl;
509 std::cout << p <<
"Time for solve = "
510 << SolTime <<
" (s), avg = " << SolTime <<
" (s)" << std::endl;
523 std::cerr <<
"Amesos: CSparse returned error code " << error << std::endl;
virtual const Epetra_Map & RowMatrixRowMap() const =0
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define AMESOS_CHK_ERR(a)
bool isSublist(const std::string &name) const
#define AMESOS_RETURN(amesos_err)
bool CheckError(const std::string SolverType, const std::string Descriptor, const Epetra_RowMatrix &A, const Epetra_MultiVector &x, const Epetra_MultiVector &b, const Epetra_MultiVector &x_exact)
virtual int NumGlobalRows() const =0