xref: /petsc/src/mat/impls/aij/mpi/pastix/pastix.c (revision 2e956fe4fc852fabc23b437482e1fb7b77fddb0d)
13bf14a46SMatthew Knepley /*
23bf14a46SMatthew Knepley  Provides an interface to the PaStiX sparse solver
33bf14a46SMatthew Knepley  */
4c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
5c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h>
6c6db04a5SJed Brown #include <../src/mat/impls/sbaij/seq/sbaij.h>
7c6db04a5SJed Brown #include <../src/mat/impls/sbaij/mpi/mpisbaij.h>
83bf14a46SMatthew Knepley 
9dbbbd53dSSatish Balay #if defined(PETSC_USE_COMPLEX)
105ec454cfSSatish Balay #define _H_COMPLEX
115ec454cfSSatish Balay #endif
125ec454cfSSatish Balay 
133bf14a46SMatthew Knepley EXTERN_C_BEGIN
14c6db04a5SJed Brown #include <pastix.h>
153bf14a46SMatthew Knepley EXTERN_C_END
163bf14a46SMatthew Knepley 
17519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX)
18519f805aSKarl Rupp #if defined(PETSC_USE_REAL_SINGLE)
195ec454cfSSatish Balay #define PASTIX_CALL c_pastix
205ec454cfSSatish Balay #else
215ec454cfSSatish Balay #define PASTIX_CALL z_pastix
225ec454cfSSatish Balay #endif
23d41469e0Sxavier lacoste 
24d41469e0Sxavier lacoste #else /* PETSC_USE_COMPLEX */
25d41469e0Sxavier lacoste 
26519f805aSKarl Rupp #if defined(PETSC_USE_REAL_SINGLE)
275ec454cfSSatish Balay #define PASTIX_CALL s_pastix
285ec454cfSSatish Balay #else
295ec454cfSSatish Balay #define PASTIX_CALL d_pastix
305ec454cfSSatish Balay #endif
31d41469e0Sxavier lacoste 
32d41469e0Sxavier lacoste #endif /* PETSC_USE_COMPLEX */
33d41469e0Sxavier lacoste 
34dbbbd53dSSatish Balay typedef PetscScalar PastixScalar;
35dbbbd53dSSatish Balay 
363bf14a46SMatthew Knepley typedef struct Mat_Pastix_ {
373bf14a46SMatthew Knepley   pastix_data_t *pastix_data;    /* Pastix data storage structure                        */
383bf14a46SMatthew Knepley   MatStructure  matstruc;
393bf14a46SMatthew Knepley   PetscInt      n;               /* Number of columns in the matrix                      */
403bf14a46SMatthew Knepley   PetscInt      *colptr;         /* Index of first element of each column in row and val */
413bf14a46SMatthew Knepley   PetscInt      *row;            /* Row of each element of the matrix                    */
423bf14a46SMatthew Knepley   PetscScalar   *val;            /* Value of each element of the matrix                  */
433bf14a46SMatthew Knepley   PetscInt      *perm;           /* Permutation tabular                                  */
443bf14a46SMatthew Knepley   PetscInt      *invp;           /* Reverse permutation tabular                          */
453bf14a46SMatthew Knepley   PetscScalar   *rhs;            /* Rhight-hand-side member                              */
463bf14a46SMatthew Knepley   PetscInt      rhsnbr;          /* Rhight-hand-side number (must be 1)                  */
47baed9decSBarry Smith   PetscInt      iparm[IPARM_SIZE];       /* Integer parameters                                   */
48baed9decSBarry Smith   double        dparm[DPARM_SIZE];       /* Floating point parameters                            */
493bf14a46SMatthew Knepley   MPI_Comm      pastix_comm;     /* PaStiX MPI communicator                              */
503bf14a46SMatthew Knepley   PetscMPIInt   commRank;        /* MPI rank                                             */
513bf14a46SMatthew Knepley   PetscMPIInt   commSize;        /* MPI communicator size                                */
52ace3abfcSBarry Smith   PetscBool     CleanUpPastix;   /* Boolean indicating if we call PaStiX clean step      */
533bf14a46SMatthew Knepley   VecScatter    scat_rhs;
543bf14a46SMatthew Knepley   VecScatter    scat_sol;
55f31ce8a6SBarry Smith   Vec           b_seq;
563bf14a46SMatthew Knepley } Mat_Pastix;
573bf14a46SMatthew Knepley 
5809573ac7SBarry Smith extern PetscErrorCode MatDuplicate_Pastix(Mat,MatDuplicateOption,Mat*);
593bf14a46SMatthew Knepley 
603bf14a46SMatthew Knepley /*
613bf14a46SMatthew Knepley    convert Petsc seqaij matrix to CSC: colptr[n], row[nz], val[nz]
623bf14a46SMatthew Knepley 
633bf14a46SMatthew Knepley   input:
643bf14a46SMatthew Knepley     A       - matrix in seqaij or mpisbaij (bs=1) format
653bf14a46SMatthew Knepley     valOnly - FALSE: spaces are allocated and values are set for the CSC
663bf14a46SMatthew Knepley               TRUE:  Only fill values
673bf14a46SMatthew Knepley   output:
683bf14a46SMatthew Knepley     n       - Size of the matrix
693bf14a46SMatthew Knepley     colptr  - Index of first element of each column in row and val
703bf14a46SMatthew Knepley     row     - Row of each element of the matrix
713bf14a46SMatthew Knepley     values  - Value of each element of the matrix
723bf14a46SMatthew Knepley  */
73ace3abfcSBarry Smith PetscErrorCode MatConvertToCSC(Mat A,PetscBool valOnly,PetscInt *n,PetscInt **colptr,PetscInt **row,PetscScalar **values)
7441c8de11SBarry Smith {
753bf14a46SMatthew Knepley   Mat_SeqAIJ  *aa      = (Mat_SeqAIJ*)A->data;
763bf14a46SMatthew Knepley   PetscInt    *rowptr  = aa->i;
773bf14a46SMatthew Knepley   PetscInt    *col     = aa->j;
783bf14a46SMatthew Knepley   PetscScalar *rvalues = aa->a;
793bf14a46SMatthew Knepley   PetscInt     m       = A->rmap->N;
80745c78f7SBarry Smith   PetscInt     nnz;
813bf14a46SMatthew Knepley   PetscInt     i,j, k;
823bf14a46SMatthew Knepley   PetscInt     base    = 1;
833bf14a46SMatthew Knepley   PetscInt     idx;
843bf14a46SMatthew Knepley   PetscInt     colidx;
853bf14a46SMatthew Knepley   PetscInt    *colcount;
86ace3abfcSBarry Smith   PetscBool    isSBAIJ;
87ace3abfcSBarry Smith   PetscBool    isSeqSBAIJ;
88ace3abfcSBarry Smith   PetscBool    isMpiSBAIJ;
89ace3abfcSBarry Smith   PetscBool    isSym;
903bf14a46SMatthew Knepley 
913bf14a46SMatthew Knepley   PetscFunctionBegin;
929566063dSJacob Faibussowitsch   PetscCall(MatIsSymmetric(A,0.0,&isSym));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATSBAIJ,&isSBAIJ));
949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ));
959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMPISBAIJ,&isMpiSBAIJ));
963bf14a46SMatthew Knepley 
97745c78f7SBarry Smith   *n = A->cmap->N;
98745c78f7SBarry Smith 
99745c78f7SBarry Smith   /* PaStiX only needs triangular matrix if matrix is symmetric
100745c78f7SBarry Smith    */
1012205254eSKarl Rupp   if (isSym && !(isSBAIJ || isSeqSBAIJ || isMpiSBAIJ)) nnz = (aa->nz - *n)/2 + *n;
1022205254eSKarl Rupp   else nnz = aa->nz;
1033bf14a46SMatthew Knepley 
1043bf14a46SMatthew Knepley   if (!valOnly) {
1059566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((*n)+1,colptr));
1069566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,row));
1079566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,values));
1083bf14a46SMatthew Knepley 
10941c8de11SBarry Smith     if (isSBAIJ || isSeqSBAIJ || isMpiSBAIJ) {
1109566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy (*colptr, rowptr, (*n)+1));
1112205254eSKarl Rupp       for (i = 0; i < *n+1; i++) (*colptr)[i] += base;
1129566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy (*row, col, nnz));
1132205254eSKarl Rupp       for (i = 0; i < nnz; i++) (*row)[i] += base;
1149566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy (*values, rvalues, nnz));
11541c8de11SBarry Smith     } else {
1169566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(*n,&colcount));
11741c8de11SBarry Smith 
118f31ce8a6SBarry Smith       for (i = 0; i < m; i++) colcount[i] = 0;
1193bf14a46SMatthew Knepley       /* Fill-in colptr */
120f31ce8a6SBarry Smith       for (i = 0; i < m; i++) {
121f31ce8a6SBarry Smith         for (j = rowptr[i]; j < rowptr[i+1]; j++) {
122f31ce8a6SBarry Smith           if (!isSym || col[j] <= i)  colcount[col[j]]++;
123f31ce8a6SBarry Smith         }
124f31ce8a6SBarry Smith       }
125745c78f7SBarry Smith 
1263bf14a46SMatthew Knepley       (*colptr)[0] = base;
1273bf14a46SMatthew Knepley       for (j = 0; j < *n; j++) {
1283bf14a46SMatthew Knepley         (*colptr)[j+1] = (*colptr)[j] + colcount[j];
129745c78f7SBarry Smith         /* in next loop we fill starting from (*colptr)[colidx] - base */
1303bf14a46SMatthew Knepley         colcount[j] = -base;
1313bf14a46SMatthew Knepley       }
1323bf14a46SMatthew Knepley 
1333bf14a46SMatthew Knepley       /* Fill-in rows and values */
1343bf14a46SMatthew Knepley       for (i = 0; i < m; i++) {
1353bf14a46SMatthew Knepley         for (j = rowptr[i]; j < rowptr[i+1]; j++) {
13641c8de11SBarry Smith           if (!isSym || col[j] <= i) {
1373bf14a46SMatthew Knepley             colidx         = col[j];
1383bf14a46SMatthew Knepley             idx            = (*colptr)[colidx] + colcount[colidx];
1393bf14a46SMatthew Knepley             (*row)[idx]    = i + base;
1403bf14a46SMatthew Knepley             (*values)[idx] = rvalues[j];
1413bf14a46SMatthew Knepley             colcount[colidx]++;
1423bf14a46SMatthew Knepley           }
1433bf14a46SMatthew Knepley         }
1443bf14a46SMatthew Knepley       }
1459566063dSJacob Faibussowitsch       PetscCall(PetscFree(colcount));
146745c78f7SBarry Smith     }
14741c8de11SBarry Smith   } else {
148745c78f7SBarry Smith     /* Fill-in only values */
1493bf14a46SMatthew Knepley     for (i = 0; i < m; i++) {
1503bf14a46SMatthew Knepley       for (j = rowptr[i]; j < rowptr[i+1]; j++) {
1513bf14a46SMatthew Knepley         colidx = col[j];
1522205254eSKarl Rupp         if ((isSBAIJ || isSeqSBAIJ || isMpiSBAIJ) ||!isSym || col[j] <= i) {
153745c78f7SBarry Smith           /* look for the value to fill */
154f31ce8a6SBarry Smith           for (k = (*colptr)[colidx] - base; k < (*colptr)[colidx + 1] - base; k++) {
155eb1f6c34SBarry Smith             if (((*row)[k]-base) == i) {
1563bf14a46SMatthew Knepley               (*values)[k] = rvalues[j];
1573bf14a46SMatthew Knepley               break;
1583bf14a46SMatthew Knepley             }
1593bf14a46SMatthew Knepley           }
160f31ce8a6SBarry Smith           /* data structure of sparse matrix has changed */
161aed4548fSBarry Smith           PetscCheck(k != (*colptr)[colidx + 1] - base,PETSC_COMM_SELF,PETSC_ERR_PLIB,"overflow on k %" PetscInt_FMT,k);
1623bf14a46SMatthew Knepley         }
1633bf14a46SMatthew Knepley       }
1643bf14a46SMatthew Knepley     }
165745c78f7SBarry Smith   }
1663bf14a46SMatthew Knepley   PetscFunctionReturn(0);
1673bf14a46SMatthew Knepley }
1683bf14a46SMatthew Knepley 
1693bf14a46SMatthew Knepley /*
1703bf14a46SMatthew Knepley   Call clean step of PaStiX if lu->CleanUpPastix == true.
1713bf14a46SMatthew Knepley   Free the CSC matrix.
1723bf14a46SMatthew Knepley  */
1733bf14a46SMatthew Knepley PetscErrorCode MatDestroy_Pastix(Mat A)
1743bf14a46SMatthew Knepley {
17558c95f1bSBarry Smith   Mat_Pastix *lu = (Mat_Pastix*)A->data;
176745c78f7SBarry Smith 
1773bf14a46SMatthew Knepley   PetscFunctionBegin;
17858c95f1bSBarry Smith   if (lu->CleanUpPastix) {
1793bf14a46SMatthew Knepley     /* Terminate instance, deallocate memories */
1809566063dSJacob Faibussowitsch     PetscCall(VecScatterDestroy(&lu->scat_rhs));
1819566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&lu->b_seq));
1829566063dSJacob Faibussowitsch     PetscCall(VecScatterDestroy(&lu->scat_sol));
1833bf14a46SMatthew Knepley 
1843bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK]=API_TASK_CLEAN;
1853bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]  =API_TASK_CLEAN;
1863bf14a46SMatthew Knepley 
187d41469e0Sxavier lacoste     PASTIX_CALL(&(lu->pastix_data),
1883bf14a46SMatthew Knepley                 lu->pastix_comm,
189d41469e0Sxavier lacoste                 lu->n,
190d41469e0Sxavier lacoste                 lu->colptr,
191d41469e0Sxavier lacoste                 lu->row,
1925ec454cfSSatish Balay                 (PastixScalar*)lu->val,
193d41469e0Sxavier lacoste                 lu->perm,
194d41469e0Sxavier lacoste                 lu->invp,
1955ec454cfSSatish Balay                 (PastixScalar*)lu->rhs,
196d41469e0Sxavier lacoste                 lu->rhsnbr,
197d41469e0Sxavier lacoste                 lu->iparm,
1983bf14a46SMatthew Knepley                 lu->dparm);
19908401ef6SPierre Jolivet     PetscCheck(lu->iparm[IPARM_ERROR_NUMBER] == 0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by PaStiX in destroy: iparm(IPARM_ERROR_NUMBER)=%" PetscInt_FMT,lu->iparm[IPARM_ERROR_NUMBER]);
2009566063dSJacob Faibussowitsch     PetscCall(PetscFree(lu->colptr));
2019566063dSJacob Faibussowitsch     PetscCall(PetscFree(lu->row));
2029566063dSJacob Faibussowitsch     PetscCall(PetscFree(lu->val));
2039566063dSJacob Faibussowitsch     PetscCall(PetscFree(lu->perm));
2049566063dSJacob Faibussowitsch     PetscCall(PetscFree(lu->invp));
2059566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_free(&(lu->pastix_comm)));
2063bf14a46SMatthew Knepley   }
207*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSolverType_C",NULL));
2089566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->data));
2093bf14a46SMatthew Knepley   PetscFunctionReturn(0);
2103bf14a46SMatthew Knepley }
2113bf14a46SMatthew Knepley 
2123bf14a46SMatthew Knepley /*
2133bf14a46SMatthew Knepley   Gather right-hand-side.
2143bf14a46SMatthew Knepley   Call for Solve step.
2153bf14a46SMatthew Knepley   Scatter solution.
2163bf14a46SMatthew Knepley  */
2173bf14a46SMatthew Knepley PetscErrorCode MatSolve_PaStiX(Mat A,Vec b,Vec x)
2183bf14a46SMatthew Knepley {
21958c95f1bSBarry Smith   Mat_Pastix  *lu = (Mat_Pastix*)A->data;
2203bf14a46SMatthew Knepley   PetscScalar *array;
2213bf14a46SMatthew Knepley   Vec          x_seq;
2223bf14a46SMatthew Knepley 
2233bf14a46SMatthew Knepley   PetscFunctionBegin;
2243bf14a46SMatthew Knepley   lu->rhsnbr = 1;
2253bf14a46SMatthew Knepley   x_seq      = lu->b_seq;
2263bf14a46SMatthew Knepley   if (lu->commSize > 1) {
22741ffd417SStefano Zampini     /* PaStiX only supports centralized rhs. Scatter b into a sequential rhs vector */
2289566063dSJacob Faibussowitsch     PetscCall(VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD));
2299566063dSJacob Faibussowitsch     PetscCall(VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD));
2309566063dSJacob Faibussowitsch     PetscCall(VecGetArray(x_seq,&array));
23141c8de11SBarry Smith   } else {  /* size == 1 */
2329566063dSJacob Faibussowitsch     PetscCall(VecCopy(b,x));
2339566063dSJacob Faibussowitsch     PetscCall(VecGetArray(x,&array));
2343bf14a46SMatthew Knepley   }
2353bf14a46SMatthew Knepley   lu->rhs = array;
2363bf14a46SMatthew Knepley   if (lu->commSize == 1) {
2379566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(x,&array));
2383bf14a46SMatthew Knepley   } else {
2399566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(x_seq,&array));
2403bf14a46SMatthew Knepley   }
2413bf14a46SMatthew Knepley 
2423bf14a46SMatthew Knepley   /* solve phase */
2433bf14a46SMatthew Knepley   /*-------------*/
2443bf14a46SMatthew Knepley   lu->iparm[IPARM_START_TASK] = API_TASK_SOLVE;
2453bf14a46SMatthew Knepley   lu->iparm[IPARM_END_TASK]   = API_TASK_REFINE;
246745c78f7SBarry Smith   lu->iparm[IPARM_RHS_MAKING] = API_RHS_B;
2473bf14a46SMatthew Knepley 
248d41469e0Sxavier lacoste   PASTIX_CALL(&(lu->pastix_data),
249d41469e0Sxavier lacoste               lu->pastix_comm,
250d41469e0Sxavier lacoste               lu->n,
251d41469e0Sxavier lacoste               lu->colptr,
252d41469e0Sxavier lacoste               lu->row,
2535ec454cfSSatish Balay               (PastixScalar*)lu->val,
254d41469e0Sxavier lacoste               lu->perm,
255d41469e0Sxavier lacoste               lu->invp,
2565ec454cfSSatish Balay               (PastixScalar*)lu->rhs,
257d41469e0Sxavier lacoste               lu->rhsnbr,
258d41469e0Sxavier lacoste               lu->iparm,
259d41469e0Sxavier lacoste               lu->dparm);
26008401ef6SPierre Jolivet   PetscCheck(lu->iparm[IPARM_ERROR_NUMBER] == 0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by PaStiX in solve phase: lu->iparm[IPARM_ERROR_NUMBER] = %" PetscInt_FMT,lu->iparm[IPARM_ERROR_NUMBER]);
2613bf14a46SMatthew Knepley 
2623bf14a46SMatthew Knepley   if (lu->commSize == 1) {
2639566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(x,&(lu->rhs)));
2643bf14a46SMatthew Knepley   } else {
2659566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(x_seq,&(lu->rhs)));
2663bf14a46SMatthew Knepley   }
2673bf14a46SMatthew Knepley 
2683bf14a46SMatthew Knepley   if (lu->commSize > 1) { /* convert PaStiX centralized solution to petsc mpi x */
2699566063dSJacob Faibussowitsch     PetscCall(VecScatterBegin(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD));
2709566063dSJacob Faibussowitsch     PetscCall(VecScatterEnd(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD));
2713bf14a46SMatthew Knepley   }
2723bf14a46SMatthew Knepley   PetscFunctionReturn(0);
2733bf14a46SMatthew Knepley }
2743bf14a46SMatthew Knepley 
2753bf14a46SMatthew Knepley /*
2763bf14a46SMatthew Knepley   Numeric factorisation using PaStiX solver.
2773bf14a46SMatthew Knepley 
2783bf14a46SMatthew Knepley  */
2793bf14a46SMatthew Knepley PetscErrorCode MatFactorNumeric_PaStiX(Mat F,Mat A,const MatFactorInfo *info)
2803bf14a46SMatthew Knepley {
28158c95f1bSBarry Smith   Mat_Pastix     *lu =(Mat_Pastix*)(F)->data;
28241c8de11SBarry Smith   Mat            *tseq;
283b5e56a35SBarry Smith   PetscInt       icntl;
284b5e56a35SBarry Smith   PetscInt       M=A->rmap->N;
285ace3abfcSBarry Smith   PetscBool      valOnly,flg, isSym;
2863bf14a46SMatthew Knepley   IS             is_iden;
2873bf14a46SMatthew Knepley   Vec            b;
2883bf14a46SMatthew Knepley   IS             isrow;
28951a30905SBarry Smith   PetscBool      isSeqAIJ,isSeqSBAIJ,isMPIAIJ;
2903bf14a46SMatthew Knepley 
2913bf14a46SMatthew Knepley   PetscFunctionBegin;
2929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ));
2939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&isMPIAIJ));
2949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ));
2953bf14a46SMatthew Knepley   if (lu->matstruc == DIFFERENT_NONZERO_PATTERN) {
2963bf14a46SMatthew Knepley     (F)->ops->solve = MatSolve_PaStiX;
2973bf14a46SMatthew Knepley 
2983bf14a46SMatthew Knepley     /* Initialize a PASTIX instance */
2999566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_dup(PetscObjectComm((PetscObject)A),&(lu->pastix_comm)));
3009566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(lu->pastix_comm, &lu->commRank));
3019566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_size(lu->pastix_comm, &lu->commSize));
3023bf14a46SMatthew Knepley 
3033bf14a46SMatthew Knepley     /* Set pastix options */
3043bf14a46SMatthew Knepley     lu->iparm[IPARM_MODIFY_PARAMETER] = API_NO;
3053bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK]       = API_TASK_INIT;
3063bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]         = API_TASK_INIT;
3072205254eSKarl Rupp 
3083bf14a46SMatthew Knepley     lu->rhsnbr = 1;
3093bf14a46SMatthew Knepley 
3103bf14a46SMatthew Knepley     /* Call to set default pastix options */
311d41469e0Sxavier lacoste     PASTIX_CALL(&(lu->pastix_data),
312d41469e0Sxavier lacoste                 lu->pastix_comm,
313d41469e0Sxavier lacoste                 lu->n,
314d41469e0Sxavier lacoste                 lu->colptr,
315d41469e0Sxavier lacoste                 lu->row,
3165ec454cfSSatish Balay                 (PastixScalar*)lu->val,
317d41469e0Sxavier lacoste                 lu->perm,
318d41469e0Sxavier lacoste                 lu->invp,
3195ec454cfSSatish Balay                 (PastixScalar*)lu->rhs,
320d41469e0Sxavier lacoste                 lu->rhsnbr,
321d41469e0Sxavier lacoste                 lu->iparm,
322d41469e0Sxavier lacoste                 lu->dparm);
32308401ef6SPierre Jolivet     PetscCheck(lu->iparm[IPARM_ERROR_NUMBER] == 0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by PaStiX in MatFactorNumeric: iparm(IPARM_ERROR_NUMBER)=%" PetscInt_FMT,lu->iparm[IPARM_ERROR_NUMBER]);
3243bf14a46SMatthew Knepley 
325d0609cedSBarry Smith     PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"PaStiX Options","Mat");
3263bf14a46SMatthew Knepley     icntl = -1;
32741c8de11SBarry Smith     lu->iparm[IPARM_VERBOSE] = API_VERBOSE_NOT;
3289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-mat_pastix_verbose","iparm[IPARM_VERBOSE] : level of printing (0 to 2)","None",lu->iparm[IPARM_VERBOSE],&icntl,&flg));
329d41469e0Sxavier lacoste     if ((flg && icntl >= 0) || PetscLogPrintInfo) {
3303bf14a46SMatthew Knepley       lu->iparm[IPARM_VERBOSE] =  icntl;
3313bf14a46SMatthew Knepley     }
3323bf14a46SMatthew Knepley     icntl=-1;
3339566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-mat_pastix_threadnbr","iparm[IPARM_THREAD_NBR] : Number of thread by MPI node","None",lu->iparm[IPARM_THREAD_NBR],&icntl,&flg));
3343bf14a46SMatthew Knepley     if ((flg && icntl > 0)) {
3353bf14a46SMatthew Knepley       lu->iparm[IPARM_THREAD_NBR] = icntl;
3363bf14a46SMatthew Knepley     }
337d0609cedSBarry Smith     PetscOptionsEnd();
3383bf14a46SMatthew Knepley     valOnly = PETSC_FALSE;
33941c8de11SBarry Smith   } else {
3405d6241c8SBarry Smith     if (isSeqAIJ || isMPIAIJ) {
3419566063dSJacob Faibussowitsch       PetscCall(PetscFree(lu->colptr));
3429566063dSJacob Faibussowitsch       PetscCall(PetscFree(lu->row));
3439566063dSJacob Faibussowitsch       PetscCall(PetscFree(lu->val));
3445d6241c8SBarry Smith       valOnly = PETSC_FALSE;
3455d6241c8SBarry Smith     } else valOnly = PETSC_TRUE;
3463bf14a46SMatthew Knepley   }
3473bf14a46SMatthew Knepley 
3483bf14a46SMatthew Knepley   lu->iparm[IPARM_MATRIX_VERIFICATION] = API_YES;
3493bf14a46SMatthew Knepley 
3503bf14a46SMatthew Knepley   /* convert mpi A to seq mat A */
3519566063dSJacob Faibussowitsch   PetscCall(ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow));
3529566063dSJacob Faibussowitsch   PetscCall(MatCreateSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq));
3539566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isrow));
3543bf14a46SMatthew Knepley 
3559566063dSJacob Faibussowitsch   PetscCall(MatConvertToCSC(*tseq,valOnly, &lu->n, &lu->colptr, &lu->row, &lu->val));
3569566063dSJacob Faibussowitsch   PetscCall(MatIsSymmetric(*tseq,0.0,&isSym));
3579566063dSJacob Faibussowitsch   PetscCall(MatDestroyMatrices(1,&tseq));
35841c8de11SBarry Smith 
3595d6241c8SBarry Smith   if (!lu->perm) {
3609566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lu->n,&(lu->perm)));
3619566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(lu->n,&(lu->invp)));
3625d6241c8SBarry Smith   }
3633bf14a46SMatthew Knepley 
3643bf14a46SMatthew Knepley   if (isSym) {
365745c78f7SBarry Smith     /* On symmetric matrix, LLT */
3663bf14a46SMatthew Knepley     lu->iparm[IPARM_SYM]           = API_SYM_YES;
36741c8de11SBarry Smith     lu->iparm[IPARM_FACTORIZATION] = API_FACT_LDLT;
368f31ce8a6SBarry Smith   } else {
369745c78f7SBarry Smith     /* On unsymmetric matrix, LU */
3703bf14a46SMatthew Knepley     lu->iparm[IPARM_SYM]           = API_SYM_NO;
3713bf14a46SMatthew Knepley     lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU;
3723bf14a46SMatthew Knepley   }
3733bf14a46SMatthew Knepley 
3743bf14a46SMatthew Knepley   /*----------------*/
3753bf14a46SMatthew Knepley   if (lu->matstruc == DIFFERENT_NONZERO_PATTERN) {
37658c95f1bSBarry Smith     if (!(isSeqAIJ || isSeqSBAIJ) && !lu->b_seq) {
3773bf14a46SMatthew Knepley       /* PaStiX only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */
3789566063dSJacob Faibussowitsch       PetscCall(VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq));
3799566063dSJacob Faibussowitsch       PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden));
3809566063dSJacob Faibussowitsch       PetscCall(MatCreateVecs(A,NULL,&b));
3819566063dSJacob Faibussowitsch       PetscCall(VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs));
3829566063dSJacob Faibussowitsch       PetscCall(VecScatterCreate(lu->b_seq,is_iden,b,is_iden,&lu->scat_sol));
3839566063dSJacob Faibussowitsch       PetscCall(ISDestroy(&is_iden));
3849566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&b));
3853bf14a46SMatthew Knepley     }
3863bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK] = API_TASK_ORDERING;
3873bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]   = API_TASK_NUMFACT;
3883bf14a46SMatthew Knepley 
389d41469e0Sxavier lacoste     PASTIX_CALL(&(lu->pastix_data),
390d41469e0Sxavier lacoste                 lu->pastix_comm,
391d41469e0Sxavier lacoste                 lu->n,
392d41469e0Sxavier lacoste                 lu->colptr,
393d41469e0Sxavier lacoste                 lu->row,
3945ec454cfSSatish Balay                 (PastixScalar*)lu->val,
395d41469e0Sxavier lacoste                 lu->perm,
396d41469e0Sxavier lacoste                 lu->invp,
3975ec454cfSSatish Balay                 (PastixScalar*)lu->rhs,
398d41469e0Sxavier lacoste                 lu->rhsnbr,
399d41469e0Sxavier lacoste                 lu->iparm,
400d41469e0Sxavier lacoste                 lu->dparm);
40108401ef6SPierre Jolivet     PetscCheck(lu->iparm[IPARM_ERROR_NUMBER] == 0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: iparm(IPARM_ERROR_NUMBER)=%" PetscInt_FMT,lu->iparm[IPARM_ERROR_NUMBER]);
40241c8de11SBarry Smith   } else {
4033bf14a46SMatthew Knepley     lu->iparm[IPARM_START_TASK] = API_TASK_NUMFACT;
4043bf14a46SMatthew Knepley     lu->iparm[IPARM_END_TASK]   = API_TASK_NUMFACT;
405d41469e0Sxavier lacoste     PASTIX_CALL(&(lu->pastix_data),
406d41469e0Sxavier lacoste                 lu->pastix_comm,
407d41469e0Sxavier lacoste                 lu->n,
408d41469e0Sxavier lacoste                 lu->colptr,
409d41469e0Sxavier lacoste                 lu->row,
4105ec454cfSSatish Balay                 (PastixScalar*)lu->val,
411d41469e0Sxavier lacoste                 lu->perm,
412d41469e0Sxavier lacoste                 lu->invp,
4135ec454cfSSatish Balay                 (PastixScalar*)lu->rhs,
414d41469e0Sxavier lacoste                 lu->rhsnbr,
415d41469e0Sxavier lacoste                 lu->iparm,
416d41469e0Sxavier lacoste                 lu->dparm);
41708401ef6SPierre Jolivet     PetscCheck(lu->iparm[IPARM_ERROR_NUMBER] == 0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: iparm(IPARM_ERROR_NUMBER)=%" PetscInt_FMT,lu->iparm[IPARM_ERROR_NUMBER]);
4183bf14a46SMatthew Knepley   }
4193bf14a46SMatthew Knepley 
4203bf14a46SMatthew Knepley   (F)->assembled    = PETSC_TRUE;
4213bf14a46SMatthew Knepley   lu->matstruc      = SAME_NONZERO_PATTERN;
4223bf14a46SMatthew Knepley   lu->CleanUpPastix = PETSC_TRUE;
4233bf14a46SMatthew Knepley   PetscFunctionReturn(0);
4243bf14a46SMatthew Knepley }
4253bf14a46SMatthew Knepley 
4263bf14a46SMatthew Knepley /* Note the Petsc r and c permutations are ignored */
4273bf14a46SMatthew Knepley PetscErrorCode MatLUFactorSymbolic_AIJPASTIX(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
4283bf14a46SMatthew Knepley {
42958c95f1bSBarry Smith   Mat_Pastix *lu = (Mat_Pastix*)F->data;
4303bf14a46SMatthew Knepley 
4313bf14a46SMatthew Knepley   PetscFunctionBegin;
4323bf14a46SMatthew Knepley   lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU;
4333bf14a46SMatthew Knepley   lu->iparm[IPARM_SYM]           = API_SYM_YES;
4343bf14a46SMatthew Knepley   lu->matstruc                   = DIFFERENT_NONZERO_PATTERN;
4353bf14a46SMatthew Knepley   F->ops->lufactornumeric        = MatFactorNumeric_PaStiX;
4363bf14a46SMatthew Knepley   PetscFunctionReturn(0);
4373bf14a46SMatthew Knepley }
4383bf14a46SMatthew Knepley 
4393bf14a46SMatthew Knepley PetscErrorCode MatCholeskyFactorSymbolic_SBAIJPASTIX(Mat F,Mat A,IS r,const MatFactorInfo *info)
4403bf14a46SMatthew Knepley {
44158c95f1bSBarry Smith   Mat_Pastix *lu = (Mat_Pastix*)(F)->data;
4423bf14a46SMatthew Knepley 
4433bf14a46SMatthew Knepley   PetscFunctionBegin;
4443bf14a46SMatthew Knepley   lu->iparm[IPARM_FACTORIZATION]  = API_FACT_LLT;
4453bf14a46SMatthew Knepley   lu->iparm[IPARM_SYM]            = API_SYM_NO;
4463bf14a46SMatthew Knepley   lu->matstruc                    = DIFFERENT_NONZERO_PATTERN;
4473bf14a46SMatthew Knepley   (F)->ops->choleskyfactornumeric = MatFactorNumeric_PaStiX;
4483bf14a46SMatthew Knepley   PetscFunctionReturn(0);
4493bf14a46SMatthew Knepley }
4503bf14a46SMatthew Knepley 
4513bf14a46SMatthew Knepley PetscErrorCode MatView_PaStiX(Mat A,PetscViewer viewer)
4523bf14a46SMatthew Knepley {
453ace3abfcSBarry Smith   PetscBool         iascii;
4543bf14a46SMatthew Knepley   PetscViewerFormat format;
4553bf14a46SMatthew Knepley 
4563bf14a46SMatthew Knepley   PetscFunctionBegin;
4579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
4583bf14a46SMatthew Knepley   if (iascii) {
4599566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(viewer,&format));
4603bf14a46SMatthew Knepley     if (format == PETSC_VIEWER_ASCII_INFO) {
46158c95f1bSBarry Smith       Mat_Pastix *lu=(Mat_Pastix*)A->data;
462b5e56a35SBarry Smith 
4639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"PaStiX run parameters:\n"));
4649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Matrix type :                      %s \n",((lu->iparm[IPARM_SYM] == API_SYM_YES) ? "Symmetric" : "Unsymmetric")));
4659566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Level of printing (0,1,2):         %" PetscInt_FMT " \n",lu->iparm[IPARM_VERBOSE]));
4669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Number of refinements iterations : %" PetscInt_FMT " \n",lu->iparm[IPARM_NBITER]));
4679566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_SELF,"  Error :                        %g \n",lu->dparm[DPARM_RELATIVE_ERROR]));
4683bf14a46SMatthew Knepley     }
4693bf14a46SMatthew Knepley   }
4703bf14a46SMatthew Knepley   PetscFunctionReturn(0);
4713bf14a46SMatthew Knepley }
4723bf14a46SMatthew Knepley 
4733bf14a46SMatthew Knepley /*MC
4742692d6eeSBarry Smith      MATSOLVERPASTIX  - A solver package providing direct solvers (LU) for distributed
4753bf14a46SMatthew Knepley   and sequential matrices via the external package PaStiX.
4763bf14a46SMatthew Knepley 
47790b3b921SSatish Balay   Use ./configure --download-pastix --download-ptscotch  to have PETSc installed with PasTiX
478c2b89b5dSBarry Smith 
4793ca39a21SBarry Smith   Use -pc_type lu -pc_factor_mat_solver_type pastix to use this direct solver
4803bf14a46SMatthew Knepley 
4813bf14a46SMatthew Knepley   Options Database Keys:
482b5e56a35SBarry Smith + -mat_pastix_verbose   <0,1,2>   - print level
483b5e56a35SBarry Smith - -mat_pastix_threadnbr <integer> - Set the thread number by MPI task.
4843bf14a46SMatthew Knepley 
48595452b02SPatrick Sanan   Notes:
48695452b02SPatrick Sanan     This only works for matrices with symmetric nonzero structure, if you pass it a matrix with
487baed9decSBarry Smith    nonsymmetric structure PasTiX and hence PETSc return with an error.
488baed9decSBarry Smith 
4893bf14a46SMatthew Knepley   Level: beginner
4903bf14a46SMatthew Knepley 
491db781477SPatrick Sanan .seealso: `PCFactorSetMatSolverType()`, `MatSolverType`
49241c8de11SBarry Smith 
4933bf14a46SMatthew Knepley M*/
4943bf14a46SMatthew Knepley 
4953bf14a46SMatthew Knepley PetscErrorCode MatGetInfo_PaStiX(Mat A,MatInfoType flag,MatInfo *info)
4963bf14a46SMatthew Knepley {
49758c95f1bSBarry Smith   Mat_Pastix *lu =(Mat_Pastix*)A->data;
4983bf14a46SMatthew Knepley 
4993bf14a46SMatthew Knepley   PetscFunctionBegin;
5003bf14a46SMatthew Knepley   info->block_size        = 1.0;
5013bf14a46SMatthew Knepley   info->nz_allocated      = lu->iparm[IPARM_NNZEROS];
5023bf14a46SMatthew Knepley   info->nz_used           = lu->iparm[IPARM_NNZEROS];
5033bf14a46SMatthew Knepley   info->nz_unneeded       = 0.0;
5043bf14a46SMatthew Knepley   info->assemblies        = 0.0;
5053bf14a46SMatthew Knepley   info->mallocs           = 0.0;
5063bf14a46SMatthew Knepley   info->memory            = 0.0;
5073bf14a46SMatthew Knepley   info->fill_ratio_given  = 0;
5083bf14a46SMatthew Knepley   info->fill_ratio_needed = 0;
5093bf14a46SMatthew Knepley   info->factor_mallocs    = 0;
5103bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5113bf14a46SMatthew Knepley }
5123bf14a46SMatthew Knepley 
513ea799195SBarry Smith static PetscErrorCode MatFactorGetSolverType_pastix(Mat A,MatSolverType *type)
5143bf14a46SMatthew Knepley {
5153bf14a46SMatthew Knepley   PetscFunctionBegin;
5162692d6eeSBarry Smith   *type = MATSOLVERPASTIX;
5173bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5183bf14a46SMatthew Knepley }
5193bf14a46SMatthew Knepley 
5203bf14a46SMatthew Knepley /*
5213bf14a46SMatthew Knepley     The seq and mpi versions of this function are the same
5223bf14a46SMatthew Knepley */
523cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_seqaij_pastix(Mat A,MatFactorType ftype,Mat *F)
5243bf14a46SMatthew Knepley {
5253bf14a46SMatthew Knepley   Mat         B;
5263bf14a46SMatthew Knepley   Mat_Pastix *pastix;
5273bf14a46SMatthew Knepley 
5283bf14a46SMatthew Knepley   PetscFunctionBegin;
5295f80ce2aSJacob Faibussowitsch   PetscCheck(ftype == MAT_FACTOR_LU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix");
5303bf14a46SMatthew Knepley   /* Create the factorization matrix */
5319566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
5329566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
5339566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("pastix",&((PetscObject)B)->type_name));
5349566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
5353bf14a46SMatthew Knepley 
53666e17bc3SBarry Smith   B->trivialsymbolic       = PETSC_TRUE;
5373bf14a46SMatthew Knepley   B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX;
5383bf14a46SMatthew Knepley   B->ops->view             = MatView_PaStiX;
5393bf14a46SMatthew Knepley   B->ops->getinfo          = MatGetInfo_PaStiX;
5402205254eSKarl Rupp 
5419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_pastix));
5422205254eSKarl Rupp 
543d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
5443bf14a46SMatthew Knepley 
54500c67f3bSHong Zhang   /* set solvertype */
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
5479566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPASTIX,&B->solvertype));
54800c67f3bSHong Zhang 
5499566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&pastix));
5502205254eSKarl Rupp 
5513bf14a46SMatthew Knepley   pastix->CleanUpPastix = PETSC_FALSE;
5520298fd71SBarry Smith   pastix->scat_rhs      = NULL;
5530298fd71SBarry Smith   pastix->scat_sol      = NULL;
55458c95f1bSBarry Smith   B->ops->getinfo       = MatGetInfo_External;
5553bf14a46SMatthew Knepley   B->ops->destroy       = MatDestroy_Pastix;
55658c95f1bSBarry Smith   B->data               = (void*)pastix;
5573bf14a46SMatthew Knepley 
5583bf14a46SMatthew Knepley   *F = B;
5593bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5603bf14a46SMatthew Knepley }
5613bf14a46SMatthew Knepley 
562cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_mpiaij_pastix(Mat A,MatFactorType ftype,Mat *F)
5633bf14a46SMatthew Knepley {
5643bf14a46SMatthew Knepley   Mat         B;
5653bf14a46SMatthew Knepley   Mat_Pastix *pastix;
5663bf14a46SMatthew Knepley 
5673bf14a46SMatthew Knepley   PetscFunctionBegin;
5685f80ce2aSJacob Faibussowitsch   PetscCheck(ftype == MAT_FACTOR_LU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix");
5693bf14a46SMatthew Knepley   /* Create the factorization matrix */
5709566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
5719566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
5729566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("pastix",&((PetscObject)B)->type_name));
5739566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
5743bf14a46SMatthew Knepley 
57566e17bc3SBarry Smith   B->trivialsymbolic       = PETSC_TRUE;
5763bf14a46SMatthew Knepley   B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX;
5773bf14a46SMatthew Knepley   B->ops->view             = MatView_PaStiX;
57858c95f1bSBarry Smith   B->ops->getinfo          = MatGetInfo_PaStiX;
5799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_pastix));
5802205254eSKarl Rupp 
581d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
5823bf14a46SMatthew Knepley 
58300c67f3bSHong Zhang   /* set solvertype */
5849566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
5859566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPASTIX,&B->solvertype));
58600c67f3bSHong Zhang 
5879566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&pastix));
5882205254eSKarl Rupp 
5893bf14a46SMatthew Knepley   pastix->CleanUpPastix = PETSC_FALSE;
5900298fd71SBarry Smith   pastix->scat_rhs      = NULL;
5910298fd71SBarry Smith   pastix->scat_sol      = NULL;
59258c95f1bSBarry Smith   B->ops->getinfo       = MatGetInfo_External;
5933bf14a46SMatthew Knepley   B->ops->destroy       = MatDestroy_Pastix;
59458c95f1bSBarry Smith   B->data               = (void*)pastix;
5953bf14a46SMatthew Knepley 
5963bf14a46SMatthew Knepley   *F = B;
5973bf14a46SMatthew Knepley   PetscFunctionReturn(0);
5983bf14a46SMatthew Knepley }
5993bf14a46SMatthew Knepley 
600cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat A,MatFactorType ftype,Mat *F)
6013bf14a46SMatthew Knepley {
6023bf14a46SMatthew Knepley   Mat         B;
6033bf14a46SMatthew Knepley   Mat_Pastix *pastix;
6043bf14a46SMatthew Knepley 
6053bf14a46SMatthew Knepley   PetscFunctionBegin;
6065f80ce2aSJacob Faibussowitsch   PetscCheck(ftype == MAT_FACTOR_CHOLESKY,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix");
6073bf14a46SMatthew Knepley   /* Create the factorization matrix */
6089566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
6099566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
6109566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("pastix",&((PetscObject)B)->type_name));
6119566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
6123bf14a46SMatthew Knepley 
61366e17bc3SBarry Smith   B->trivialsymbolic             = PETSC_TRUE;
6143bf14a46SMatthew Knepley   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX;
6153bf14a46SMatthew Knepley   B->ops->view                   = MatView_PaStiX;
61658c95f1bSBarry Smith   B->ops->getinfo                = MatGetInfo_PaStiX;
6179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_pastix));
6182205254eSKarl Rupp 
619d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_CHOLESKY;
6203bf14a46SMatthew Knepley 
62100c67f3bSHong Zhang   /* set solvertype */
6229566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
6239566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPASTIX,&B->solvertype));
62400c67f3bSHong Zhang 
6259566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&pastix));
6262205254eSKarl Rupp 
6273bf14a46SMatthew Knepley   pastix->CleanUpPastix = PETSC_FALSE;
6280298fd71SBarry Smith   pastix->scat_rhs      = NULL;
6290298fd71SBarry Smith   pastix->scat_sol      = NULL;
63058c95f1bSBarry Smith   B->ops->getinfo       = MatGetInfo_External;
6313bf14a46SMatthew Knepley   B->ops->destroy       = MatDestroy_Pastix;
63258c95f1bSBarry Smith   B->data               = (void*)pastix;
6333bf14a46SMatthew Knepley   *F = B;
6343bf14a46SMatthew Knepley   PetscFunctionReturn(0);
6353bf14a46SMatthew Knepley }
6363bf14a46SMatthew Knepley 
637cc2e6a90SBarry Smith static PetscErrorCode MatGetFactor_mpisbaij_pastix(Mat A,MatFactorType ftype,Mat *F)
6383bf14a46SMatthew Knepley {
6393bf14a46SMatthew Knepley   Mat         B;
6403bf14a46SMatthew Knepley   Mat_Pastix *pastix;
6413bf14a46SMatthew Knepley 
6423bf14a46SMatthew Knepley   PetscFunctionBegin;
6435f80ce2aSJacob Faibussowitsch   PetscCheck(ftype == MAT_FACTOR_CHOLESKY,PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix");
64441c8de11SBarry Smith 
6453bf14a46SMatthew Knepley   /* Create the factorization matrix */
6469566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
6479566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
6489566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("pastix",&((PetscObject)B)->type_name));
6499566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
6503bf14a46SMatthew Knepley 
6513bf14a46SMatthew Knepley   B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX;
6523bf14a46SMatthew Knepley   B->ops->view                   = MatView_PaStiX;
65358c95f1bSBarry Smith   B->ops->getinfo                = MatGetInfo_PaStiX;
65458c95f1bSBarry Smith   B->ops->destroy                = MatDestroy_Pastix;
6559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_pastix));
6562205254eSKarl Rupp 
657d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_CHOLESKY;
6583bf14a46SMatthew Knepley 
65900c67f3bSHong Zhang   /* set solvertype */
6609566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
6619566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPASTIX,&B->solvertype));
66200c67f3bSHong Zhang 
6639566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&pastix));
6642205254eSKarl Rupp 
6653bf14a46SMatthew Knepley   pastix->CleanUpPastix = PETSC_FALSE;
6660298fd71SBarry Smith   pastix->scat_rhs      = NULL;
6670298fd71SBarry Smith   pastix->scat_sol      = NULL;
66858c95f1bSBarry Smith   B->data               = (void*)pastix;
6693bf14a46SMatthew Knepley 
6703bf14a46SMatthew Knepley   *F = B;
6713bf14a46SMatthew Knepley   PetscFunctionReturn(0);
6723bf14a46SMatthew Knepley }
673f7a08781SBarry Smith 
6743ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Pastix(void)
67542c9c57cSBarry Smith {
67642c9c57cSBarry Smith   PetscFunctionBegin;
6779566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERPASTIX,MATMPIAIJ,        MAT_FACTOR_LU,MatGetFactor_mpiaij_pastix));
6789566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERPASTIX,MATSEQAIJ,        MAT_FACTOR_LU,MatGetFactor_seqaij_pastix));
6799566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERPASTIX,MATMPISBAIJ,      MAT_FACTOR_CHOLESKY,MatGetFactor_mpisbaij_pastix));
6809566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERPASTIX,MATSEQSBAIJ,      MAT_FACTOR_CHOLESKY,MatGetFactor_seqsbaij_pastix));
68142c9c57cSBarry Smith   PetscFunctionReturn(0);
68242c9c57cSBarry Smith }
683