1 #ifndef SELDON_FILE_DISTRIBUTED_SOLVER_CXX
3 #include "DistributedSolver.hxx"
16 this->refine_solution =
true;
18 #ifdef SELDON_WITH_MPI
21 nb_unknowns_scal_ = 1;
22 comm_ = MPI_COMM_SELF;
23 ProcSharingRows_ = NULL;
24 SharingRowNumbers_ = NULL;
35 else if (print_level >= 6)
36 this->ShowFullHistory();
48 diagonal_scale_left.Clear();
49 diagonal_scale_right.Clear();
54 template<
class T>
template<
class MatrixSparse>
58 diagonal_scaling_left =
true;
59 diagonal_scaling_right =
true;
61 GetRowColSum(diagonal_scale_left, diagonal_scale_right, A);
65 for (
int i = 0; i < n; i++)
67 if (diagonal_scale_left(i) != 0)
68 diagonal_scale_left(i) = abs(1.0/diagonal_scale_left(i));
70 diagonal_scale_left(i) = 1.0;
72 if (diagonal_scale_right(i) != 0)
73 diagonal_scale_right(i) = abs(1.0/diagonal_scale_right(i));
75 diagonal_scale_right(i) = 1.0;
78 ScaleMatrix(A, diagonal_scale_left, diagonal_scale_right);
84 template<
class Prop,
class Storage,
class Allocator>
87 bool keep_matrix,
bool scale_matrix)
89 diagonal_scaling_left =
false;
90 diagonal_scaling_right =
false;
101 template<
class Prop,
class Storage,
class Allocator>
111 template<
class Prop,
class Storage,
class Allocator>
116 diagonal_scaling_left =
false;
117 diagonal_scaling_right =
false;
119 ScaleMatrixRowCol(A);
126 #ifdef SELDON_WITH_MPI
129 template<
class Prop0,
class Storage0,
class Allocator0>
132 bool keep_matrix,
bool scale_matrix)
134 diagonal_scaling_left =
false;
135 diagonal_scaling_right =
false;
137 ScaleMatrixRowCol(A);
140 int nb_proc; MPI_Comm_size(comm, &nb_proc);
157 DistributedMatrix<T, Prop0, Storage0, Allocator0> Bstore;
158 DistributedMatrix<T, Prop0, Storage0, Allocator0>* B;
167 int rank_proc; MPI_Comm_rank(comm, &rank_proc);
168 if ((this->print_level >= 1) &&(rank_proc == 0))
169 cout <<
"Assembling the distributed matrix..." << endl;
171 if (this->solver->UseInteger8())
173 Vector<int64_t> Ptr, IndRow;
175 bool sym_pattern =
false;
176 if (this->type_solver == this->PASTIX)
179 bool reorder_num =
false;
180 if (this->type_solver == this->PASTIX)
183 if (this->type_solver == this->SUPERLU)
187 AssembleDistributed(*B, sym, comm, global_col_numbers,
189 Ptr, IndRow, Val, sym_pattern, reorder_num);
194 AssembleDistributed(*B, sym, comm, global_col_numbers,
196 Ptr, IndRow, Val, sym_pattern, reorder_num);
199 if ((this->print_level >= 1) && (rank_proc == 0))
200 cout <<
"Factorizing the distributed matrix..." << endl;
203 this->FactorizeDistributed(comm, Ptr, IndRow, Val,
204 global_col_numbers, sym_matrix, reorder_num);
208 Vector<long> Ptr; Vector<int> IndRow;
210 bool sym_pattern =
false;
211 if (this->type_solver == this->PASTIX)
214 bool reorder_num =
false;
215 if (this->type_solver == this->PASTIX)
218 if (this->type_solver == this->SUPERLU)
222 AssembleDistributed(*B, sym, comm, global_col_numbers,
224 Ptr, IndRow, Val, sym_pattern, reorder_num);
229 AssembleDistributed(*B, sym, comm, global_col_numbers,
231 Ptr, IndRow, Val, sym_pattern, reorder_num);
234 if ((this->print_level >= 1) && (rank_proc == 0))
235 cout <<
"Factorizing the distributed matrix..." << endl;
238 this->FactorizeDistributed(comm, Ptr, IndRow, Val,
239 global_col_numbers, sym_matrix, reorder_num);
247 template<
class Prop0,
class Storage0,
class Allocator0>
248 void SparseDistributedSolver<T>
249 ::PerformAnalysis(DistributedMatrix<T, Prop0, Storage0, Allocator0>& A)
251 MPI_Comm& comm = A.GetCommunicator();
252 int nb_proc; MPI_Comm_size(comm, &nb_proc);
263 ProcSharingRows_ = &A.GetProcessorSharingRows();
264 SharingRowNumbers_ = &A.GetSharingRowNumbers();
265 nodl_scalar_ = A.GetNodlScalar();
266 nb_unknowns_scal_ = A.GetNbScalarUnknowns();
270 int rank_proc; MPI_Comm_rank(comm, &rank_proc);
271 if ((this->print_level >= 1) &&(rank_proc == 0))
272 cout <<
"Assembling the distributed matrix..." << endl;
274 DistributedMatrix<T, Prop0, Storage0, Allocator0> B; B = A;
275 if (this->solver->UseInteger8())
277 Vector<int64_t> Ptr, IndRow;
279 bool sym_pattern =
false;
280 if (this->type_solver == this->PASTIX)
283 bool reorder_num =
false;
284 if (this->type_solver == this->SUPERLU)
288 AssembleDistributed(B, sym, comm, global_col_numbers,
290 Ptr, IndRow, Val, sym_pattern, reorder_num);
295 AssembleDistributed(B, sym, comm, global_col_numbers,
297 Ptr, IndRow, Val, sym_pattern, reorder_num);
300 if ((this->print_level >= 1) && (rank_proc == 0))
301 cout <<
"Analysing the distributed matrix..." << endl;
304 this->PerformAnalysisDistributed(comm, Ptr, IndRow, Val,
305 global_col_numbers, sym_matrix, reorder_num);
309 Vector<long> Ptr; Vector<int> IndRow;
311 bool sym_pattern =
false;
312 if (this->type_solver == this->PASTIX)
315 bool reorder_num =
false;
316 if (this->type_solver == this->SUPERLU)
320 AssembleDistributed(B, sym, comm, global_col_numbers,
322 Ptr, IndRow, Val, sym_pattern, reorder_num);
327 AssembleDistributed(B, sym, comm, global_col_numbers,
329 Ptr, IndRow, Val, sym_pattern, reorder_num);
332 if ((this->print_level >= 1) && (rank_proc == 0))
333 cout <<
"Analysing the distributed matrix..." << endl;
336 this->PerformAnalysisDistributed(comm, Ptr, IndRow, Val,
337 global_col_numbers, sym_matrix, reorder_num);
346 template<
class Prop0,
class Storage0,
class Allocator0>
347 void SparseDistributedSolver<T>
348 ::PerformFactorization(DistributedMatrix<T, Prop0, Storage0, Allocator0>& A,
351 diagonal_scaling_left =
false;
352 diagonal_scaling_right =
false;
354 ScaleMatrixRowCol(A);
356 MPI_Comm& comm = A.GetCommunicator();
357 int nb_proc, rank_proc;
358 MPI_Comm_size(comm, &nb_proc); MPI_Comm_rank(comm, &rank_proc);
370 if ((this->print_level >= 1) &&(rank_proc == 0))
371 cout <<
"Assembling the distributed matrix..." << endl;
373 if (this->solver->UseInteger8())
375 Vector<int64_t> Ptr, IndRow;
377 bool sym_pattern =
false;
378 if (this->type_solver == this->PASTIX)
381 bool reorder_num =
false;
382 if (this->type_solver == this->SUPERLU)
386 AssembleDistributed(A, sym, comm, global_col_numbers,
388 Ptr, IndRow, Val, sym_pattern, reorder_num);
393 AssembleDistributed(A, sym, comm, global_col_numbers,
395 Ptr, IndRow, Val, sym_pattern, reorder_num);
398 if ((this->print_level >= 1) && (rank_proc == 0))
399 cout <<
"Factorizing the distributed matrix..." << endl;
402 this->PerformFactorizationDistributed(comm, Ptr, IndRow, Val,
403 global_col_numbers, sym_matrix, reorder_num);
407 Vector<long> Ptr; Vector<int> IndRow;
409 bool sym_pattern =
false;
410 if (this->type_solver == this->PASTIX)
413 bool reorder_num =
false;
414 if (this->type_solver == this->SUPERLU)
418 AssembleDistributed(A, sym, comm, global_col_numbers,
420 Ptr, IndRow, Val, sym_pattern, reorder_num);
425 AssembleDistributed(A, sym, comm, global_col_numbers,
427 Ptr, IndRow, Val, sym_pattern, reorder_num);
430 if ((this->print_level >= 1) && (rank_proc == 0))
431 cout <<
"Factorizing the distributed matrix..." << endl;
434 this->PerformFactorizationDistributed(comm, Ptr, IndRow, Val,
435 global_col_numbers, sym_matrix, reorder_num);
443 template<
class T>
template<
class T2>
444 void SparseDistributedSolver<T>::AssembleVec(Vector<T2>& X)
const
446 AssembleVector(X, MPI_SUM, *ProcSharingRows_, *SharingRowNumbers_,
447 comm_, nodl_scalar_, nb_unknowns_scal_, 20);
451 template<
class T>
template<
class T2>
452 void SparseDistributedSolver<T>::AssembleVec(Matrix<T2, General, ColMajor>& A)
const
457 for (
int k = 0; k < nrhs; k++)
459 X.SetData(A.GetM(), &A(0, k));
460 AssembleVector(X, MPI_SUM, *ProcSharingRows_, *SharingRowNumbers_,
461 comm_, nodl_scalar_, nb_unknowns_scal_, 21);
475 template<
class T>
template<
class T1>
479 Copy(b_rhs, x_solution);
489 template<
class T>
template<
class T1>
492 Solve(SeldonNoTrans, x_solution);
501 template<
class T>
template<
class T1>
504 Solve(SeldonTrans, x_solution);
508 template<
class T>
template<
class T1>
512 if (diagonal_scaling_left && trans.NoTrans())
513 for (
int i = 0; i < x_solution.GetM(); i++)
514 x_solution(i) *= diagonal_scale_left(i);
516 if (diagonal_scaling_right && trans.Trans())
517 for (
int i = 0; i < x_solution.GetM(); i++)
518 x_solution(i) *= diagonal_scale_right(i);
522 #ifdef SELDON_WITH_MPI
523 MPI_Comm& comm = comm_;
524 int nb_proc; MPI_Comm_size(comm, &nb_proc);
526 SolveLU(trans, *
this, x_solution);
530 int n = local_col_numbers.GetM();
532 for (
int i = 0; i < local_col_numbers.GetM(); i++)
533 x_sol_extract(i) = x_solution(local_col_numbers(i));
535 SolveLU_Distributed(comm, trans, *
this,
536 x_sol_extract, global_col_numbers);
539 for (
int i = 0; i < local_col_numbers.GetM(); i++)
540 x_solution(local_col_numbers(i)) = x_sol_extract(i);
544 this->AssembleVec(x_solution);
547 SolveLU(trans, *
this, x_solution);
550 if (diagonal_scaling_right && trans.NoTrans())
551 for (
int i = 0; i < x_solution.GetM(); i++)
552 x_solution(i) *= diagonal_scale_right(i);
554 if (diagonal_scaling_left && trans.Trans())
555 for (
int i = 0; i < x_solution.GetM(); i++)
556 x_solution(i) *= diagonal_scale_left(i);
564 template<
class T>
template<
class T1>
567 Solve(SeldonNoTrans, x_solution);
575 template<
class T>
template<
class T1>
578 Solve(SeldonTrans, x_solution);
582 template<
class T>
template<
class T1>
586 if (diagonal_scaling_left && trans.NoTrans())
587 ScaleLeftMatrix(x_solution, diagonal_scale_left);
589 if (diagonal_scaling_right && trans.Trans())
590 ScaleLeftMatrix(x_solution, diagonal_scale_right);
592 #ifdef SELDON_WITH_MPI
593 MPI_Comm& comm = comm_;
594 int nb_proc; MPI_Comm_size(comm, &nb_proc);
596 SolveLU(trans, *
this, x_solution);
600 int n = local_col_numbers.GetM();
601 int N = x_solution.GetM(), nrhs = x_solution.GetN();
603 for (
int k = 0; k < nrhs; k++)
604 for (
int i = 0; i < local_col_numbers.GetM(); i++)
605 x_sol_extract(i, k) = x_solution(local_col_numbers(i), k);
608 SolveLU_Distributed(comm, trans, *
this,
609 x_sol_extract, global_col_numbers);
611 x_solution.Reallocate(N, nrhs);
613 for (
int k = 0; k < nrhs; k++)
614 for (
int i = 0; i < local_col_numbers.GetM(); i++)
615 x_solution(local_col_numbers(i), k) = x_sol_extract(i, k);
618 this->AssembleVec(x_solution);
621 SolveLU(trans, *
this, x_solution);
624 if (diagonal_scaling_right && trans.NoTrans())
625 ScaleLeftMatrix(x_solution, diagonal_scale_right);
627 if (diagonal_scaling_left && trans.Trans())
628 ScaleLeftMatrix(x_solution, diagonal_scale_left);
638 template<
class T>
template<
class MatrixSparse,
class MatrixFull>
641 MatrixFull& mat_schur)
643 if (this->type_solver == this->MUMPS)
645 #ifdef SELDON_WITH_MUMPS
651 cout<<
"Recompile Montjoie with Mumps."
652 <<
" Schur complement can't be performed otherwise"<<endl;
658 cout <<
"Try to use Mumps, not implemented with other solvers " <<endl;
668 size_t taille = diagonal_scale_left.GetMemorySize()
669 + diagonal_scale_right.GetMemorySize();
671 taille += this->permut.GetMemorySize();
672 taille += this->solver->GetMemorySize();
679 #define SELDON_FILE_DISTRIBUTED_SOLVER_CXX