NeoPZ
TPZPardisoControl.cpp
Go to the documentation of this file.
1 //
2 // TPZPardisoControl.cpp
3 // PZ
4 //
5 // Created by Philippe Devloo on 5/5/16.
6 //
7 //
8 
9 #include "TPZPardisoControl.h"
10 
11 #ifdef USING_MKL
12 
13 #include "mkl_pardiso.h"
14 #include "pzsysmp.h"
15 #include "pzysmp.h"
16 #include "pzlog.h"
17 
18 //#define Release_Memory_Q
19 
21 template<class TVar>
22 TPZPardisoControl<TVar>::TPZPardisoControl() : fSystemType(ENonSymmetric),
23 fStructure(EStructureSymmetric), fProperty(EIndefinite), fPardisoControl(), fHandle(0),
24 fParam(64,0), fMax_num_factors(1), fMatrix_num(1), fMessageLevel(0), fError(0), fPermutation(), fMatrixType(0),
25 fNonSymmetricSystem(0), fSymmetricSystem(0)
26 {
27  fPardisoControl = new TPZManVector<long long,64>(64,0);
28  fHandle = &fPardisoControl.operator->()->operator[](0);
29 // fMatrixType = MatrixType();
30 }
31 
32 
33 template<class TVar>
34 TPZPardisoControl<TVar>::TPZPardisoControl(MSystemType systemtype, MProperty prop) : fSystemType(systemtype),
35  fStructure(EStructureSymmetric), fProperty(prop), fPardisoControl(), fHandle(0),
36  fParam(64,0), fMax_num_factors(1), fMatrix_num(1), fMessageLevel(0), fError(0), fPermutation(), fMatrixType(0),
37  fNonSymmetricSystem(0), fSymmetricSystem(0)
38 
39 {
40  fPardisoControl = new TPZManVector<long long,64>(64,0);
41  fHandle = &fPardisoControl.operator->()->operator[](0);
42 // fMatrixType = MatrixType();
43 }
44 
46 // this method should only be called if the pardiso control is zero (non initialized)
47 template<class TVar>
48 void TPZPardisoControl<TVar>::SetMatrixType(MSystemType systemtype, MProperty prop)
49 {
50  fSystemType = systemtype;
51  fProperty = prop;
52  fMatrixType = MatrixType();
53 }
54 
55 //fSystemType(systemtype),
56 //fStructure(EStructureSymmetric), fProperty(prop), fPardisoControl(), fHandle(0),
57 //fParam(64,0), fMax_num_factors(1), fMatrix_num(1), fMessageLevel(0), fError(0), fPermutation(), fMatrixType(0)
58 
59 template<class TVar>
60 TPZPardisoControl<TVar>::TPZPardisoControl(const TPZPardisoControl<TVar> &copy) : fSystemType(copy.fSystemType),
61 fStructure(copy.fStructure), fProperty(copy.fProperty), fPardisoControl(copy.fPardisoControl), fHandle(copy.fHandle),
62 fParam(copy.fParam), fMax_num_factors(copy.fMax_num_factors), fMatrix_num(copy.fMatrix_num), fMessageLevel(copy.fMessageLevel),
63 fError(copy.fError), fPermutation(copy.fPermutation), fMatrixType(copy.fMatrixType),
64 fSymmetricSystem(copy.fSymmetricSystem), fNonSymmetricSystem(copy.fNonSymmetricSystem)
65 {
66 
67 }
68 
69 template<class TVar>
70 TPZPardisoControl<TVar> &TPZPardisoControl<TVar>::operator=(const TPZPardisoControl &copy)
71 {
72  fSystemType = copy.fSystemType;
73  fStructure = copy.fStructure;
74  fProperty = copy.fProperty;
75  fPardisoControl = copy.fPardisoControl;
76  fHandle = copy.fHandle;
77  fParam = copy.fParam;
78  fMax_num_factors = copy.fMax_num_factors;
79  fMatrix_num = copy.fMatrix_num;
80  fMessageLevel = copy.fMessageLevel;
81  fError = copy.fError;
82  fPermutation = copy.fPermutation;
83  fMatrixType = copy.fMatrixType;
84  fSymmetricSystem = copy.fSymmetricSystem;
85  fNonSymmetricSystem = copy.fNonSymmetricSystem;
86  return *this;
87 }
88 
89 
90 //enum MSystemType {ESymmetric, EHermitian, EnonSymmetric};
91 //
92 //enum MStructure {EStructureSymmetric, EStructureNonSymmetric};
93 //
94 //enum MProperty {EPositiveDefinite, EIndefinite};
95 
96 template<class TVar>
97 int DataType(TVar a)
98 {
99  DebugStop();
100  return 0;
101 }
102 
103 
104 template<>
105 int DataType(double a)
106 {
107  return 0;
108 }
109 
110 template<>
111 int DataType(float a)
112 {
113  return 1;
114 }
115 
116 
117 template<class TVar>
118 long long TPZPardisoControl<TVar>::MatrixType()
119 {
120  // should not happen
121  if (fStructure == EStructureNonSymmetric) {
122  DebugStop();
123  }
124  if (fSystemType == ESymmetric && fProperty == EIndefinite) {
125  if(fMatrixType != 0 && fMatrixType != -2)
126  {
127  DebugStop();
128  }
129  else if(fMatrixType == -2)
130  {
131  return -2;
132  }
133  fMatrixType = -2;
134  }
135  if (fSystemType == ESymmetric && fProperty == EPositiveDefinite) {
136  if(fMatrixType != 0 && fMatrixType != 2)
137  {
138  DebugStop();
139  }
140  else if(fMatrixType == 2)
141  {
142  return 2;
143  }
144  fMatrixType = 2;
145  }
146  if (fSystemType == ENonSymmetric && fStructure == EStructureSymmetric) {
147  fMatrixType = 11;
148  }
149  if (fSystemType == ENonSymmetric && fProperty == EPositiveDefinite) {
150  DebugStop();
151  }
152 
153 // for (long long i=0; i<64; i++) {
154 // long long val = fHandle[i];
155 // if (val) {
156 // DebugStop();
157 // }
158 // }
159 
160  int param[64] = {0};
161  int matrixtype = fMatrixType;
162  pardisoinit(fHandle,&matrixtype,param);
163  for (int i=0; i<64; i++) {
164  fParam[i] = param[i];
165  }
166 
167  fParam[34] = 1;
168  return fMatrixType;
169 }
170 
171 
172 template<class TVar>
173 void TPZPardisoControl<TVar>::Decompose()
174 {
175  long long n=0;
176  TVar bval = 0., xval = 0.;
177  TVar *a,*b = &bval, *x = &xval;
178  long long *ia,*ja;
179  if (fSymmetricSystem) {
180  if (fSymmetricSystem->Rows()==0) {
181  return;
182  }
183  a = &(fSymmetricSystem->fA[0]);
184  ia = (long long *) &(fSymmetricSystem->fIA[0]);
185  ja = (long long *) &(fSymmetricSystem->fJA[0]);
186  n = fSymmetricSystem->Rows();
187  }
188  if (fNonSymmetricSystem) {
189  a = &(fNonSymmetricSystem->fA[0]);
190  ia = (long long *) &(fNonSymmetricSystem->fIA[0]);
191  ja = (long long *) &(fNonSymmetricSystem->fJA[0]);
192  n = fNonSymmetricSystem->Rows();
193 
194  }
195 
196  long long *perm = 0,nrhs = 0;
197  long long Error = 0;
198  nrhs = 0;
199  fPermutation.resize(n);
200  perm = &fPermutation[0];
201  fParam[34] = 1;
202  // Do not use OOC
203  fParam[59] = 0;
205  long long phase = 12;
206  fPermutation.resize(n);
207  for (long long i=0; i<n; i++) {
208  fPermutation[i] = i;
209  }
210  perm = &fPermutation[0];
211 
213  // LU preconditioned CGS (10*L+K) where K={1:CGS,2:CG} and L=10^-L stopping threshold
214  if (fProperty == EIndefinite) {
215  fParam[4] = 1;
216  if(fSystemType == ESymmetric){ // The factorization is always computed as required by phase.
217  fParam[3 ] = 10*6+2;
218  }else{ // CGS iteration replaces the computation of LU. The preconditioner is LU that was computed at a previous step (the first step or last step with a failure) in a sequence of solutions needed for identical sparsity patterns.
219  fParam[3 ] = 10*6+1;
220  fParam[10] = 1;
221  fParam[12] = 1;
222  }
223  }else{
224 
225  if(fSystemType == ESymmetric){ // CGS iteration for symmetric positive definite matrices replaces the computation of LLT. The preconditioner is LLT that was computed at a previous step (the first step or last step with a failure) in a sequence of solutions needed for identical sparsity patterns.
226  fParam[3 ] = 10*6+2;
227  }else{
228  fParam[3 ] = 10*6+1;
229  fParam[10] = 1;
230  fParam[12] = 1;
231  }
232  }
233 
234  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, ia, ja, perm,
235  &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
236  if (Error) {
237  Error_check(int(Error));
238  std::cout << __PRETTY_FUNCTION__ << " error code " << Error << std::endl;
239  DebugStop();
240  }
241 #ifdef PZDEBUG
242  std::cout << "Pardiso:: decomposition complete. \n";
243 #endif
244 }
245 
247 template<class TVar>
248 void TPZPardisoControl<TVar>::Solve(TPZFMatrix<TVar> &rhs, TPZFMatrix<TVar> &sol) const
249 {
250  long long n=0;
251  TVar *a,*b, *x;
252  long long *ia,*ja;
253  if (fSymmetricSystem) {
254  if(fSymmetricSystem->Rows() == 0)
255  {
256  return;
257  }
258  a = &(fSymmetricSystem->fA[0]);
259  ia = (long long *) &(fSymmetricSystem->fIA[0]);
260  ja = (long long *) &(fSymmetricSystem->fJA[0]);
261  n = fSymmetricSystem->Rows();
262  }
263  if (fNonSymmetricSystem) {
264  a = &(fNonSymmetricSystem->fA[0]);
265  ia = (long long *) &(fNonSymmetricSystem->fIA[0]);
266  ja = (long long *) &(fNonSymmetricSystem->fJA[0]);
267  n = fNonSymmetricSystem->Rows();
268  }
269 
270  long long *perm,nrhs;
271  long long Error = 0;
272  nrhs = rhs.Cols();
273  n = rhs.Rows();
274  b = &rhs(0,0);
275  x = &sol(0,0);
276  perm = &fPermutation[0];
278  long long phase = 33;
279 
280  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, ia, ja, perm,
281  &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
282 
283  if(fParam[19]>150){
284  std::cout << "Pardiso:: Number of iterations " << fParam[19] << " > 150, calling numerical factorization... " << std::endl;
285  phase = 23;
286  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, ia, ja, perm,
287  &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
288  }
289 
290  int rest = abs(fParam[19]%10); // CG/CGS error report
291  if(fParam[19] <= 0){
292  switch (rest) {
293  case 1:{
294  std::cout << "Pardiso:: fluctuations of the residuum are too large. " << std::endl;
295  }
296  break;
297 
298  case 2:{
299  std::cout << "Pardiso:: Slow convergence - Main matrix and matrix for preconditioner differ a lot. " << std::endl;
300  }
301  break;
302 
303  case 4:{
304  std::cout << "Pardiso:: perturbed pivots caused iterative refinement. " << std::endl;
305  }
306  break;
307 
308  case 5:{
309  std::cout << "Pardiso:: factorization is too fast for this matrix. It is better to use the factorization method with iparm[3] = 0 " << std::endl;
310  fParam[3] = 0;
311  }
312  break;
313  case 6:{
314  std::cout << "Pardiso:: There is not a diagnostig. " << std::endl;
315  }
316  break;
317  default:
318  break;
319  }
320 
321  }
322 
323 
324  if (Error<0) {
325  Error_check(int(Error));
326  std::cout << "Pardiso:: Calling a numerical factorization. \n";
327  phase = 22;
328  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, ia, ja, perm,
329  &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
330  }
331 
332  if (Error) {
333  Error_check(int(Error));
334  DebugStop();
335  }
336 
337 #ifdef PZDEBUG
338  std::cout << "Pardiso:: linear solve complete. \n";
339 #endif
340 
341 #ifdef Release_Memory_Q
342  phase = -1;
343  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, ia, ja, perm, &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
344  if (fSymmetricSystem) {
345  fSymmetricSystem->SetIsDecomposed(0);
346  }
347  if (fNonSymmetricSystem) {
348  fNonSymmetricSystem->SetIsDecomposed(0);
349  }
350 #ifdef PZDEBUG
351  std::cout << "Pardiso:: release memory complete. \n";
352 #endif
353 #endif
354 }
355 
356 template<class TVar>
357 TPZPardisoControl<TVar>::~TPZPardisoControl()
358 {
359  long long phase = -1;
360  long long n=1;
361  long long av,bv,xv;
362  void *a= &av,*b = &bv, *x = &xv;
363  long long ia,ja,perm,nrhs = 1;
364  long long Error = 0;
365 
366  pardiso_64 (fHandle, &fMax_num_factors, &fMatrix_num, &fMatrixType, &phase, &n, a, &ia, &ja, &perm,
367  &nrhs, &fParam[0], &fMessageLevel, b, x, &Error);
368 
369  if (Error) {
370  DebugStop();
371  }
372 
373 }
374 
375 template<class TVar>
376 void TPZPardisoControl<TVar>::Error_check(int error) const {
377 
378  switch (error) {
379  case -1:
380  std::cout << "Pardiso:: Input inconsistent." << std::endl;
381  break;
382  case -2:
383  std::cout << "Pardiso:: Not enough memory." << std::endl;
384  break;
385  case -3:
386  std::cout << "Pardiso:: Reordering problem." << std::endl;
387  break;
388  case -4:
389  std::cout << "Pardiso:: Zero pivot, numerical fact. or iterative refinement problem. " << std::endl;
390  break;
391  case -5:
392  std::cout << "Pardiso:: Unclassified (internal) error. " << std::endl;
393  break;
394  case -6:
395  std::cout << "Pardiso:: Preordering failed (matrix types 11, 13 only). " << std::endl;
396  break;
397  case -7:
398  std::cout << "Pardiso:: Diagonal matrix problem. " << std::endl;
399  break;
400  case -8:
401  std::cout << "Pardiso:: 32-bit integer overflow problem. " << std::endl;
402  break;
403  default:
404  std::cout << "Pardiso:: There is not a explanation. " << std::endl;
405  break;
406  }
407 
408 }
409 
410 
411 template class TPZPardisoControl<double>;
412 template class TPZPardisoControl<long double>;
413 template class TPZPardisoControl<float>;
414 
415 
416 
417 #endif
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
Implements a vector class which allows to use external storage provided by the user. Utility.
Definition: pzquad.h:16
av
Definition: test.py:257
TinyFad< 8, T > abs(const TinyFad< 8, T > &in)
Definition: tinyfadeight.h:846
void error(char *string)
Definition: testShape.cc:7
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
Contains the TPZFYsmpMatrix class which implements a non symmetric sparse matrix. ...
Full matrix class. Matrix.
Definition: pzfmatrix.h:32
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
Contains TPZSYsmpMatrix class which implements a symmetric sparse matrix. Purpose: Defines operation...