00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef SELDON_FILE_PASTIX_CXX
00020
00021 #include "Pastix.hxx"
00022
00023 namespace Seldon
00024 {
00025
00027 template<class T>
00028 MatrixPastix<T>::MatrixPastix()
00029 {
00030 pastix_data = NULL;
00031 n = 0;
00032 for (int i = 0; i < 64; i++)
00033 {
00034 iparm[i] = 0;
00035 dparm[i] = 0;
00036 }
00037
00038
00039 distributed = false;
00040
00041
00042 refine_solution = true;
00043
00044
00045 pastix_initParam(iparm, dparm);
00046
00047 iparm[IPARM_RHS_MAKING] = API_RHS_B;
00048 iparm[IPARM_VERBOSE] = API_VERBOSE_NOT;
00049 }
00050
00051
00053 template<class T>
00054 MatrixPastix<T>::~MatrixPastix()
00055 {
00056 Clear();
00057 }
00058
00059
00061 template<>
00062 void MatrixPastix<double>::
00063 CallPastix(const MPI_Comm& comm, pastix_int_t* colptr, pastix_int_t* row,
00064 double* val, double* b, pastix_int_t nrhs)
00065 {
00066 if (distributed)
00067 d_dpastix(&pastix_data, comm, n, colptr, row, val,
00068 col_num.GetData(), perm.GetData(), invp.GetData(),
00069 b, nrhs, iparm, dparm);
00070 else
00071 d_pastix(&pastix_data, comm, n, colptr, row, val,
00072 perm.GetData(), invp.GetData(), b, nrhs, iparm, dparm);
00073 }
00074
00075
00077 template<>
00078 void MatrixPastix<complex<double> >::
00079 CallPastix(const MPI_Comm& comm, pastix_int_t* colptr, pastix_int_t* row,
00080 complex<double>* val, complex<double>* b, pastix_int_t nrhs)
00081 {
00082 if (distributed)
00083 z_dpastix(&pastix_data, comm, n, colptr, row,
00084 reinterpret_cast<DCOMPLEX*>(val),
00085 col_num.GetData(), perm.GetData(), invp.GetData(),
00086 reinterpret_cast<DCOMPLEX*>(b), nrhs, iparm, dparm);
00087 else
00088 z_pastix(&pastix_data, comm, n, colptr, row,
00089 reinterpret_cast<DCOMPLEX*>(val),
00090 perm.GetData(), invp.GetData(),
00091 reinterpret_cast<DCOMPLEX*>(b), nrhs, iparm, dparm);
00092 }
00093
00094
00096 template<class T>
00097 void MatrixPastix<T>::Clear()
00098 {
00099 if (n > 0)
00100 {
00101 pastix_int_t nrhs = 1;
00102 iparm[IPARM_START_TASK] = API_TASK_CLEAN;
00103 iparm[IPARM_END_TASK] = API_TASK_CLEAN;
00104
00105 CallPastix(MPI_COMM_WORLD, NULL, NULL, NULL, NULL, nrhs);
00106
00107 perm.Clear();
00108 invp.Clear();
00109 col_num.Clear();
00110 n = 0;
00111 pastix_data = NULL;
00112 distributed = false;
00113 }
00114 }
00115
00116
00118 template<class T>
00119 void MatrixPastix<T>::HideMessages()
00120 {
00121 iparm[IPARM_VERBOSE] = API_VERBOSE_NOT;
00122 }
00123
00124
00126 template<class T>
00127 void MatrixPastix<T>::ShowMessages()
00128 {
00129 iparm[IPARM_VERBOSE] = API_VERBOSE_NO;
00130 }
00131
00132
00134 template<class T>
00135 void MatrixPastix<T>::ShowFullHistory()
00136 {
00137 iparm[IPARM_VERBOSE] = API_VERBOSE_YES;
00138 }
00139
00140
00141 template<class T>
00142 void MatrixPastix<T>::SelectOrdering(int type)
00143 {
00144 iparm[IPARM_ORDERING] = type;
00145 }
00146
00147
00148 template<class T>
00149 void MatrixPastix<T>::SetPermutation(const IVect& permut)
00150 {
00151 iparm[IPARM_ORDERING] = API_ORDER_PERSONAL;
00152 perm.Reallocate(permut.GetM());
00153 invp.Reallocate(permut.GetM());
00154 for (int i = 0; i < perm.GetM(); i++)
00155 {
00156 perm(i) = permut(i) + 1;
00157 invp(permut(i)) = i+1;
00158 }
00159 }
00160
00161
00163 template<class T>
00164 void MatrixPastix<T>::RefineSolution()
00165 {
00166 refine_solution = true;
00167 }
00168
00169
00171 template<class T>
00172 void MatrixPastix<T>::DoNotRefineSolution()
00173 {
00174 refine_solution = false;
00175 }
00176
00177
00179 template<class T>
00180 template<class T0, class Prop, class Storage, class Allocator, class Tint>
00181 void MatrixPastix<T>::
00182 FindOrdering(Matrix<T0, Prop, Storage, Allocator> & mat,
00183 Vector<Tint>& numbers, bool keep_matrix)
00184 {
00185
00186 Clear();
00187
00188 distributed = false;
00189
00190 n = mat.GetN();
00191 if (n <= 0)
00192 return;
00193
00194 pastix_int_t nrhs = 1, nnz = 0;
00195 pastix_int_t* ptr_ = NULL;
00196 pastix_int_t* ind_ = NULL;
00197 Vector<pastix_int_t> Ptr, Ind;
00198
00199 iparm[IPARM_SYM] = API_SYM_YES;
00200 iparm[IPARM_FACTORIZATION] = API_FACT_LDLT;
00201 GetSymmetricPattern(mat, Ptr, Ind);
00202 if (!keep_matrix)
00203 mat.Clear();
00204
00205 ptr_ = Ptr.GetData();
00206
00207 for (int i = 0; i <= n; i++)
00208 ptr_[i]++;
00209
00210 nnz = Ind.GetM();
00211 ind_ = Ind.GetData();
00212 for (int i = 0; i < nnz; i++)
00213 ind_[i]++;
00214
00215 perm.Reallocate(n); invp.Reallocate(n);
00216 perm.Fill(); invp.Fill();
00217
00218
00219 iparm[IPARM_START_TASK] = API_TASK_ORDERING;
00220 iparm[IPARM_END_TASK] = API_TASK_ORDERING;
00221
00222 CallPastix(MPI_COMM_SELF, ptr_, ind_, NULL, NULL, nrhs);
00223
00224 numbers.Reallocate(perm.GetM());
00225 for (int i = 0; i < perm.GetM(); i ++)
00226 numbers(i) = perm(i);
00227 }
00228
00229
00231 template<class T> template<class Storage, class Allocator>
00232 void MatrixPastix<T>
00233 ::FactorizeMatrix(Matrix<T, General, Storage, Allocator> & mat,
00234 bool keep_matrix)
00235 {
00236
00237 Clear();
00238
00239 distributed = false;
00240 n = mat.GetN();
00241 if (n <= 0)
00242 return;
00243
00244 pastix_int_t nrhs = 1, nnz = 0;
00245 pastix_int_t* ptr_ = NULL;
00246 pastix_int_t* ind_ = NULL;
00247 T* values_ = NULL;
00248 Vector<pastix_int_t, VectFull, CallocAlloc<pastix_int_t> > Ptr, IndRow;
00249 Vector<T, VectFull, CallocAlloc<T> > Val;
00250
00251 General prop;
00252 ConvertToCSC(mat, prop, Ptr, IndRow, Val, true);
00253 if (!keep_matrix)
00254 mat.Clear();
00255
00256 ptr_ = Ptr.GetData();
00257
00258 for (int i = 0; i <= n; i++)
00259 ptr_[i]++;
00260
00261 nnz = IndRow.GetM();
00262 ind_ = IndRow.GetData();
00263 for (int i = 0; i < nnz; i++)
00264 ind_[i]++;
00265
00266 values_ = Val.GetData();
00267
00268 if (iparm[IPARM_ORDERING] != API_ORDER_PERSONAL)
00269 {
00270 perm.Reallocate(n); invp.Reallocate(n);
00271 perm.Fill(); invp.Fill();
00272 }
00273
00274 iparm[IPARM_SYM] = API_SYM_NO;
00275 iparm[IPARM_FACTORIZATION] = API_FACT_LU;
00276
00277 iparm[IPARM_START_TASK] = API_TASK_ORDERING;
00278 iparm[IPARM_END_TASK] = API_TASK_ANALYSE;
00279
00280 CallPastix(MPI_COMM_SELF, ptr_, ind_, values_, NULL, nrhs);
00281
00282
00283 IVect proc_num(iparm[IPARM_THREAD_NBR]);
00284 proc_num.Fill(MPI::COMM_WORLD.Get_rank());
00285 pastix_setBind(pastix_data, iparm[IPARM_THREAD_NBR], proc_num.GetData());
00286
00287 iparm[IPARM_START_TASK] = API_TASK_NUMFACT;
00288 iparm[IPARM_END_TASK] = API_TASK_NUMFACT;
00289
00290 CallPastix(MPI_COMM_SELF, ptr_, ind_, values_, NULL, nrhs);
00291
00292 if (iparm[IPARM_VERBOSE] != API_VERBOSE_NOT)
00293 cout << "Factorization successful" << endl;
00294 }
00295
00296
00298 template<class T> template<class Storage, class Allocator>
00299 void MatrixPastix<T>::
00300 FactorizeMatrix(Matrix<T, Symmetric, Storage, Allocator> & mat,
00301 bool keep_matrix)
00302 {
00303
00304 Clear();
00305
00306 distributed = false;
00307 n = mat.GetN();
00308 if (n <= 0)
00309 return;
00310
00311 pastix_int_t nrhs = 1, nnz = 0;
00312 pastix_int_t* ptr_ = NULL;
00313 pastix_int_t* ind_ = NULL;
00314
00315 T* values_ = NULL;
00316 Vector<pastix_int_t, VectFull, MallocAlloc<pastix_int_t> > Ptr, IndRow;
00317 Vector<T, VectFull, MallocAlloc<T> > Val;
00318
00319 Symmetric prop;
00320 ConvertToCSR(mat, prop, Ptr, IndRow, Val);
00321
00322 iparm[IPARM_SYM] = API_SYM_YES;
00323 iparm[IPARM_FACTORIZATION] = API_FACT_LDLT;
00324 if (!keep_matrix)
00325 mat.Clear();
00326
00327 ptr_ = Ptr.GetData();
00328
00329 for (int i = 0; i <= n; i++)
00330 ptr_[i]++;
00331
00332 nnz = IndRow.GetM();
00333 ind_ = IndRow.GetData();
00334 for (int i = 0; i < nnz; i++)
00335 ind_[i]++;
00336
00337 values_ = Val.GetData();
00338
00339 perm.Reallocate(n); invp.Reallocate(n);
00340 perm.Fill(); invp.Fill();
00341
00342
00343 iparm[IPARM_START_TASK] = API_TASK_ORDERING;
00344 iparm[IPARM_END_TASK] = API_TASK_ANALYSE;
00345
00346 CallPastix(MPI_COMM_SELF, ptr_, ind_, values_, NULL, nrhs);
00347
00348 IVect proc_num(iparm[IPARM_THREAD_NBR]);
00349 proc_num.Fill(MPI::COMM_WORLD.Get_rank());
00350 pastix_setBind(pastix_data, iparm[IPARM_THREAD_NBR], proc_num.GetData());
00351
00352
00353 iparm[IPARM_START_TASK] = API_TASK_NUMFACT;
00354 iparm[IPARM_END_TASK] = API_TASK_NUMFACT;
00355
00356 CallPastix(MPI_COMM_SELF, ptr_, ind_, values_, NULL, nrhs);
00357 }
00358
00359
00361 template<class T> template<class Allocator2>
00362 void MatrixPastix<T>::Solve(Vector<T, VectFull, Allocator2>& x)
00363 {
00364 Solve(SeldonNoTrans, x);
00365 }
00366
00367
00369 template<class T> template<class Allocator2, class Transpose_status>
00370 void MatrixPastix<T>::Solve(const Transpose_status& TransA,
00371 Vector<T, VectFull, Allocator2>& x)
00372 {
00373 pastix_int_t nrhs = 1;
00374 T* rhs_ = x.GetData();
00375
00376 iparm[IPARM_START_TASK] = API_TASK_SOLVE;
00377 if (refine_solution)
00378 iparm[IPARM_END_TASK] = API_TASK_REFINE;
00379 else
00380 iparm[IPARM_END_TASK] = API_TASK_SOLVE;
00381
00382 CallPastix(MPI_COMM_SELF, NULL, NULL, NULL, rhs_, nrhs);
00383 }
00384
00385
00387 template<class T>
00388 void MatrixPastix<T>::SetNumberThreadPerNode(int num_thread)
00389 {
00390 iparm[IPARM_THREAD_NBR] = num_thread;
00391 }
00392
00393
00395 template<class T>
00396 template<class Alloc1, class Alloc2, class Alloc3, class Tint>
00397 void MatrixPastix<T>::
00398 FactorizeDistributedMatrix(MPI::Comm& comm_facto,
00399 Vector<pastix_int_t, VectFull, Alloc1>& Ptr,
00400 Vector<pastix_int_t, VectFull, Alloc2>& IndRow,
00401 Vector<T, VectFull, Alloc3>& Val,
00402 const Vector<Tint>& glob_number,
00403 bool sym, bool keep_matrix)
00404 {
00405
00406 Clear();
00407
00408 n = Ptr.GetM() - 1;
00409 if (n <= 0)
00410 return;
00411
00412 distributed = true;
00413
00414 if (sym)
00415 {
00416 iparm[IPARM_SYM] = API_SYM_YES;
00417 iparm[IPARM_FACTORIZATION] = API_FACT_LDLT;
00418 }
00419 else
00420 {
00421 iparm[IPARM_SYM] = API_SYM_NO;
00422 iparm[IPARM_FACTORIZATION] = API_FACT_LU;
00423 }
00424
00425 iparm[IPARM_GRAPHDIST] = API_YES;
00426
00427 pastix_int_t* ptr_ = Ptr.GetData();
00428 pastix_int_t nrhs = 1;
00429
00430 for (int i = 0; i <= n; i++)
00431 ptr_[i]++;
00432
00433 pastix_int_t nnz = IndRow.GetM();
00434 pastix_int_t* ind_ = IndRow.GetData();
00435 for (int i = 0; i < nnz; i++)
00436 ind_[i]++;
00437
00438 T* values_ = Val.GetData();
00439
00440 col_num.Reallocate(n);
00441 perm.Reallocate(n); invp.Reallocate(n);
00442 perm.Fill(); invp.Fill();
00443 for (int i = 0; i < n; i++)
00444 col_num(i) = glob_number(i)+1;
00445
00446
00447 iparm[IPARM_START_TASK] = API_TASK_ORDERING;
00448 iparm[IPARM_END_TASK] = API_TASK_NUMFACT;
00449
00450 CallPastix(comm_facto, ptr_, ind_, values_, NULL, nrhs);
00451 }
00452
00453
00454 template<class T> template<class Allocator2, class Tint>
00455 void MatrixPastix<T>::SolveDistributed(MPI::Comm& comm_facto,
00456 Vector<T, Vect_Full, Allocator2>& x,
00457 const Vector<Tint>& glob_num)
00458 {
00459 SolveDistributed(comm_facto, SeldonNoTrans, x, glob_num);
00460 }
00461
00462
00463 template<class T>
00464 template<class Allocator2, class Transpose_status, class Tint>
00465 void MatrixPastix<T>::SolveDistributed(MPI::Comm& comm_facto,
00466 const Transpose_status& TransA,
00467 Vector<T, Vect_Full, Allocator2>& x,
00468 const Vector<Tint>& glob_num)
00469 {
00470 pastix_int_t nrhs = 1;
00471 T* rhs_ = x.GetData();
00472
00473 iparm[IPARM_START_TASK] = API_TASK_SOLVE;
00474 if (refine_solution)
00475 iparm[IPARM_END_TASK] = API_TASK_REFINE;
00476 else
00477 iparm[IPARM_END_TASK] = API_TASK_SOLVE;
00478
00479 CallPastix(comm_facto, NULL, NULL, NULL, rhs_, nrhs);
00480 }
00481
00482
00483 template<class T, class Prop, class Storage, class Allocator>
00484 void GetLU(Matrix<T, Prop, Storage, Allocator>& A, MatrixPastix<T>& mat_lu,
00485 bool keep_matrix = false)
00486 {
00487 mat_lu.FactorizeMatrix(A, keep_matrix);
00488 }
00489
00490
00491 template<class T, class Allocator>
00492 void SolveLU(MatrixPastix<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00493 {
00494 mat_lu.Solve(x);
00495 }
00496
00497
00498 template<class T, class Allocator, class Transpose_status>
00499 void SolveLU(const Transpose_status& TransA,
00500 MatrixPastix<T>& mat_lu, Vector<T, VectFull, Allocator>& x)
00501 {
00502 mat_lu.Solve(TransA, x);
00503 }
00504
00505 }
00506
00507 #define SELDON_FILE_PASTIX_CXX
00508 #endif