13bf14a46SMatthew Knepley #define PETSCMAT_DLL 23bf14a46SMatthew Knepley 33bf14a46SMatthew Knepley /* 43bf14a46SMatthew Knepley Provides an interface to the PaStiX sparse solver 53bf14a46SMatthew Knepley */ 63bf14a46SMatthew Knepley #include "../src/mat/impls/aij/seq/aij.h" 73bf14a46SMatthew Knepley #include "../src/mat/impls/aij/mpi/mpiaij.h" 83bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/seq/sbaij.h" 93bf14a46SMatthew Knepley #include "../src/mat/impls/sbaij/mpi/mpisbaij.h" 10*745c78f7SBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat,PetscReal,PetscTruth*); 113bf14a46SMatthew Knepley 123bf14a46SMatthew Knepley EXTERN_C_BEGIN 133bf14a46SMatthew Knepley #include "mpi.h" 143bf14a46SMatthew Knepley #include "pastix.h" 153bf14a46SMatthew Knepley static int iter_print = 0; 163bf14a46SMatthew Knepley static int csr_iter_print = 0; 173bf14a46SMatthew Knepley EXTERN_C_END 183bf14a46SMatthew Knepley 193bf14a46SMatthew Knepley typedef struct Mat_Pastix_ { 203bf14a46SMatthew Knepley pastix_data_t *pastix_data; /* Pastix data storage structure */ 213bf14a46SMatthew Knepley MatStructure matstruc; 223bf14a46SMatthew Knepley PetscInt n; /* Number of columns in the matrix */ 233bf14a46SMatthew Knepley PetscInt *colptr; /* Index of first element of each column in row and val */ 243bf14a46SMatthew Knepley PetscInt *row; /* Row of each element of the matrix */ 253bf14a46SMatthew Knepley PetscScalar *val; /* Value of each element of the matrix */ 263bf14a46SMatthew Knepley PetscInt *perm; /* Permutation tabular */ 273bf14a46SMatthew Knepley PetscInt *invp; /* Reverse permutation tabular */ 283bf14a46SMatthew Knepley PetscScalar *rhs; /* Rhight-hand-side member */ 293bf14a46SMatthew Knepley PetscInt rhsnbr; /* Rhight-hand-side number (must be 1) */ 303bf14a46SMatthew Knepley PetscInt iparm[64]; /* Integer parameters */ 313bf14a46SMatthew Knepley double dparm[64]; /* Floating point parameters */ 323bf14a46SMatthew Knepley MPI_Comm pastix_comm; /* PaStiX MPI communicator */ 333bf14a46SMatthew Knepley PetscMPIInt commRank; /* MPI rank */ 343bf14a46SMatthew Knepley PetscMPIInt commSize; /* MPI communicator size */ 353bf14a46SMatthew Knepley PetscTruth CleanUpPastix; /* Boolean indicating if we call PaStiX clean step */ 363bf14a46SMatthew Knepley VecScatter scat_rhs; 373bf14a46SMatthew Knepley VecScatter scat_sol; 383bf14a46SMatthew Knepley Vec b_seq,x_seq; 393bf14a46SMatthew Knepley PetscTruth isAIJ; 403bf14a46SMatthew Knepley PetscInt nSolve; /* Number of consecutive solve */ 413bf14a46SMatthew Knepley PetscErrorCode (*MatDestroy)(Mat); 423bf14a46SMatthew Knepley } Mat_Pastix; 433bf14a46SMatthew Knepley 443bf14a46SMatthew Knepley EXTERN PetscErrorCode MatDuplicate_Pastix(Mat,MatDuplicateOption,Mat*); 453bf14a46SMatthew Knepley 463bf14a46SMatthew Knepley /* 473bf14a46SMatthew Knepley convert Petsc seqaij matrix to CSC: colptr[n], row[nz], val[nz] 483bf14a46SMatthew Knepley 493bf14a46SMatthew Knepley input: 503bf14a46SMatthew Knepley A - matrix in seqaij or mpisbaij (bs=1) format 513bf14a46SMatthew Knepley valOnly - FALSE: spaces are allocated and values are set for the CSC 523bf14a46SMatthew Knepley TRUE: Only fill values 533bf14a46SMatthew Knepley output: 543bf14a46SMatthew Knepley n - Size of the matrix 553bf14a46SMatthew Knepley colptr - Index of first element of each column in row and val 563bf14a46SMatthew Knepley row - Row of each element of the matrix 573bf14a46SMatthew Knepley values - Value of each element of the matrix 583bf14a46SMatthew Knepley */ 593bf14a46SMatthew Knepley PetscErrorCode MatConvertToCSC(Mat A, 603bf14a46SMatthew Knepley PetscTruth valOnly, 613bf14a46SMatthew Knepley PetscInt *n, 623bf14a46SMatthew Knepley PetscInt **colptr, 633bf14a46SMatthew Knepley PetscInt **row, 643bf14a46SMatthew Knepley PetscScalar **values) { 653bf14a46SMatthew Knepley Mat_SeqAIJ *aa = (Mat_SeqAIJ*)A->data; 663bf14a46SMatthew Knepley PetscInt *rowptr = aa->i; 673bf14a46SMatthew Knepley PetscInt *col = aa->j; 683bf14a46SMatthew Knepley PetscScalar *rvalues = aa->a; 693bf14a46SMatthew Knepley PetscInt m = A->rmap->N; 70*745c78f7SBarry Smith PetscInt nnz; 713bf14a46SMatthew Knepley PetscInt i,j, k; 723bf14a46SMatthew Knepley PetscInt base = 1; 733bf14a46SMatthew Knepley PetscInt idx; 743bf14a46SMatthew Knepley PetscErrorCode ierr; 753bf14a46SMatthew Knepley PetscInt colidx; 763bf14a46SMatthew Knepley PetscInt *colcount; 77*745c78f7SBarry Smith PetscTruth isSym; 783bf14a46SMatthew Knepley 793bf14a46SMatthew Knepley 803bf14a46SMatthew Knepley PetscFunctionBegin; 813bf14a46SMatthew Knepley /* Allocate the CSC */ 823bf14a46SMatthew Knepley 833bf14a46SMatthew Knepley 84*745c78f7SBarry Smith MatIsSymmetric_SeqAIJ(A,0.0,&isSym); 85*745c78f7SBarry Smith *n = A->cmap->N; 86*745c78f7SBarry Smith 87*745c78f7SBarry Smith /* PaStiX only needs triangular matrix if matrix is symmetric 88*745c78f7SBarry Smith */ 89*745c78f7SBarry Smith if (isSym) 90*745c78f7SBarry Smith { 91*745c78f7SBarry Smith nnz = (aa->nz - *n)/2 + *n; 92*745c78f7SBarry Smith } 93*745c78f7SBarry Smith else 94*745c78f7SBarry Smith { 95*745c78f7SBarry Smith nnz = aa->nz; 963bf14a46SMatthew Knepley } 973bf14a46SMatthew Knepley 983bf14a46SMatthew Knepley ierr = PetscMalloc((*n)*sizeof(PetscInt) ,&colcount);CHKERRQ(ierr); 993bf14a46SMatthew Knepley if (!valOnly){ 1003bf14a46SMatthew Knepley ierr = PetscMalloc(((*n)+1) *sizeof(PetscInt) ,colptr );CHKERRQ(ierr); 1013bf14a46SMatthew Knepley ierr = PetscMalloc( nnz *sizeof(PetscInt) ,row);CHKERRQ(ierr); 1023bf14a46SMatthew Knepley ierr = PetscMalloc( nnz *sizeof(PetscScalar),values);CHKERRQ(ierr); 1033bf14a46SMatthew Knepley 1043bf14a46SMatthew Knepley for (i = 0; i < m; i++) 1053bf14a46SMatthew Knepley colcount[i] = 0; 1063bf14a46SMatthew Knepley /* Fill-in colptr */ 1073bf14a46SMatthew Knepley for (i = 0; i < m; i++) 1083bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) 109*745c78f7SBarry Smith if (!isSym || col[j] <= i) 1103bf14a46SMatthew Knepley colcount[col[j]]++; 111*745c78f7SBarry Smith 1123bf14a46SMatthew Knepley (*colptr)[0] = base; 1133bf14a46SMatthew Knepley for (j = 0; j < *n; j++) { 1143bf14a46SMatthew Knepley (*colptr)[j+1] = (*colptr)[j] + colcount[j]; 115*745c78f7SBarry Smith /* in next loop we fill starting from (*colptr)[colidx] - base */ 1163bf14a46SMatthew Knepley colcount[j] = -base; 1173bf14a46SMatthew Knepley } 1183bf14a46SMatthew Knepley 1193bf14a46SMatthew Knepley /* Fill-in rows and values */ 1203bf14a46SMatthew Knepley for (i = 0; i < m; i++) { 1213bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) { 122*745c78f7SBarry Smith if (!isSym || col[j] <= i) 123*745c78f7SBarry Smith { 1243bf14a46SMatthew Knepley colidx = col[j]; 1253bf14a46SMatthew Knepley idx = (*colptr)[colidx] + colcount[colidx]; 1263bf14a46SMatthew Knepley (*row)[idx] = i + base; 1273bf14a46SMatthew Knepley (*values)[idx] = rvalues[j]; 1283bf14a46SMatthew Knepley colcount[colidx]++; 1293bf14a46SMatthew Knepley } 1303bf14a46SMatthew Knepley } 1313bf14a46SMatthew Knepley } 132*745c78f7SBarry Smith } 1333bf14a46SMatthew Knepley else { 134*745c78f7SBarry Smith /* Fill-in only values */ 1353bf14a46SMatthew Knepley for (i = 0; i < m; i++) { 1363bf14a46SMatthew Knepley for (j = rowptr[i]; j < rowptr[i+1]; j++) { 1373bf14a46SMatthew Knepley colidx = col[j]; 138*745c78f7SBarry Smith if (!isSym || col[j] <= i) 139*745c78f7SBarry Smith { 140*745c78f7SBarry Smith /* look for the value to fill */ 141*745c78f7SBarry Smith for (k = (*colptr)[colidx] - base; 142*745c78f7SBarry Smith k < (*colptr)[colidx + 1] - base; 143*745c78f7SBarry Smith k++) { 1443bf14a46SMatthew Knepley if ((*row)[k] == i) { 1453bf14a46SMatthew Knepley (*values)[k] = rvalues[j]; 1463bf14a46SMatthew Knepley break; 1473bf14a46SMatthew Knepley } 1483bf14a46SMatthew Knepley } 149*745c78f7SBarry Smith /* shouldn't happen, overflow */ 1503bf14a46SMatthew Knepley if (k == (*colptr)[colidx + 1] - base) 1513bf14a46SMatthew Knepley PetscFunctionReturn(1); 1523bf14a46SMatthew Knepley } 1533bf14a46SMatthew Knepley } 1543bf14a46SMatthew Knepley } 155*745c78f7SBarry Smith } 1563bf14a46SMatthew Knepley ierr = PetscFree(colcount);CHKERRQ(ierr); 1573bf14a46SMatthew Knepley 1583bf14a46SMatthew Knepley PetscFunctionReturn(0); 1593bf14a46SMatthew Knepley } 1603bf14a46SMatthew Knepley 1613bf14a46SMatthew Knepley 1623bf14a46SMatthew Knepley 1633bf14a46SMatthew Knepley #undef __FUNCT__ 1643bf14a46SMatthew Knepley #define __FUNCT__ "MatDestroy_Pastix" 1653bf14a46SMatthew Knepley /* 1663bf14a46SMatthew Knepley Call clean step of PaStiX if lu->CleanUpPastix == true. 1673bf14a46SMatthew Knepley Free the CSC matrix. 1683bf14a46SMatthew Knepley */ 1693bf14a46SMatthew Knepley PetscErrorCode MatDestroy_Pastix(Mat A) 1703bf14a46SMatthew Knepley { 1713bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 1723bf14a46SMatthew Knepley PetscErrorCode ierr; 1733bf14a46SMatthew Knepley PetscMPIInt size=lu->commSize; 174*745c78f7SBarry Smith 1753bf14a46SMatthew Knepley PetscFunctionBegin; 1763bf14a46SMatthew Knepley if (lu->CleanUpPastix) { 1773bf14a46SMatthew Knepley /* Terminate instance, deallocate memories */ 1783bf14a46SMatthew Knepley if (size > 1){ 1793bf14a46SMatthew Knepley ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr); 1803bf14a46SMatthew Knepley ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr); 1813bf14a46SMatthew Knepley if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);} 1823bf14a46SMatthew Knepley if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);} 1833bf14a46SMatthew Knepley } 1843bf14a46SMatthew Knepley 1853bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK]=API_TASK_CLEAN; 1863bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK]=API_TASK_CLEAN; 1873bf14a46SMatthew Knepley 1883bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 1893bf14a46SMatthew Knepley lu->pastix_comm, 1903bf14a46SMatthew Knepley (pastix_int_t) lu->n, 1913bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 1923bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 1933bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 1943bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 1953bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 1963bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 1973bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 1983bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 1993bf14a46SMatthew Knepley lu->dparm); 2003bf14a46SMatthew Knepley 2013bf14a46SMatthew Knepley ierr = PetscFree(lu->colptr);CHKERRQ(ierr); 2023bf14a46SMatthew Knepley ierr = PetscFree(lu->row); CHKERRQ(ierr); 2033bf14a46SMatthew Knepley ierr = PetscFree(lu->val); CHKERRQ(ierr); 2043bf14a46SMatthew Knepley ierr = PetscFree(lu->perm); CHKERRQ(ierr); 2053bf14a46SMatthew Knepley ierr = PetscFree(lu->invp); CHKERRQ(ierr); 2063bf14a46SMatthew Knepley /* ierr = PetscFree(lu->rhs); CHKERRQ(ierr); */ 2073bf14a46SMatthew Knepley ierr = MPI_Comm_free(&(lu->pastix_comm));CHKERRQ(ierr); 2083bf14a46SMatthew Knepley 2093bf14a46SMatthew Knepley } 2103bf14a46SMatthew Knepley ierr = (lu->MatDestroy)(A);CHKERRQ(ierr); 2113bf14a46SMatthew Knepley PetscFunctionReturn(0); 2123bf14a46SMatthew Knepley } 2133bf14a46SMatthew Knepley 2143bf14a46SMatthew Knepley #undef __FUNCT__ 2153bf14a46SMatthew Knepley #define __FUNCT__ "MatSolve_PaStiX" 2163bf14a46SMatthew Knepley /* 2173bf14a46SMatthew Knepley Gather right-hand-side. 2183bf14a46SMatthew Knepley Call for Solve step. 2193bf14a46SMatthew Knepley Scatter solution. 2203bf14a46SMatthew Knepley */ 2213bf14a46SMatthew Knepley PetscErrorCode MatSolve_PaStiX(Mat A,Vec b,Vec x) 2223bf14a46SMatthew Knepley { 2233bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 2243bf14a46SMatthew Knepley PetscScalar *array; 2253bf14a46SMatthew Knepley Vec x_seq; 2263bf14a46SMatthew Knepley IS is_iden,is_petsc; 2273bf14a46SMatthew Knepley PetscErrorCode ierr; 2283bf14a46SMatthew Knepley PetscInt i,j; 2293bf14a46SMatthew Knepley 2303bf14a46SMatthew Knepley PetscFunctionBegin; 2313bf14a46SMatthew Knepley lu->rhsnbr = 1; 2323bf14a46SMatthew Knepley x_seq = lu->b_seq; 2333bf14a46SMatthew Knepley if (lu->commSize > 1){ 2343bf14a46SMatthew Knepley /* PaStiX only supports centralized rhs. Scatter b into a seqential rhs vector */ 2353bf14a46SMatthew Knepley ierr = VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2363bf14a46SMatthew Knepley ierr = VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2373bf14a46SMatthew Knepley ierr = VecGetArray(x_seq,&array); 2383bf14a46SMatthew Knepley CHKERRQ(ierr); 2393bf14a46SMatthew Knepley } 2403bf14a46SMatthew Knepley else { /* size == 1 */ 2413bf14a46SMatthew Knepley ierr = VecCopy(b,x);CHKERRQ(ierr); 2423bf14a46SMatthew Knepley ierr = VecGetArray(x,&array);CHKERRQ(ierr); 2433bf14a46SMatthew Knepley } 2443bf14a46SMatthew Knepley lu->rhs = array; 2453bf14a46SMatthew Knepley if (lu->commSize == 1){ 2463bf14a46SMatthew Knepley ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); 2473bf14a46SMatthew Knepley } else { 2483bf14a46SMatthew Knepley ierr = VecRestoreArray(x_seq,&array);CHKERRQ(ierr); 2493bf14a46SMatthew Knepley } 2503bf14a46SMatthew Knepley 2513bf14a46SMatthew Knepley /* solve phase */ 2523bf14a46SMatthew Knepley /*-------------*/ 2533bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_SOLVE; 2543bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_REFINE; 255*745c78f7SBarry Smith lu->iparm[IPARM_RHS_MAKING] = API_RHS_B; 2563bf14a46SMatthew Knepley 2573bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 2583bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 2593bf14a46SMatthew Knepley (pastix_int_t) lu->n, 2603bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 2613bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 2623bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 2633bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 2643bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 2653bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 2663bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 2673bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 2683bf14a46SMatthew Knepley (double*) lu->dparm); 2693bf14a46SMatthew Knepley 2703bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 2713bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in solve phase: lu->iparm[IPARM_ERROR_NUMBER] = %d\n", 2723bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER] ); 2733bf14a46SMatthew Knepley } 2743bf14a46SMatthew Knepley 2753bf14a46SMatthew Knepley if (lu->commSize == 1){ 2763bf14a46SMatthew Knepley ierr = VecRestoreArray(x,&(lu->rhs));CHKERRQ(ierr); 2773bf14a46SMatthew Knepley } else { 2783bf14a46SMatthew Knepley ierr = VecRestoreArray(x_seq,&(lu->rhs));CHKERRQ(ierr); 2793bf14a46SMatthew Knepley } 2803bf14a46SMatthew Knepley 2813bf14a46SMatthew Knepley if (lu->commSize > 1) { /* convert PaStiX centralized solution to petsc mpi x */ 2823bf14a46SMatthew Knepley ierr = VecScatterBegin(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2833bf14a46SMatthew Knepley ierr = VecScatterEnd(lu->scat_sol,x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2843bf14a46SMatthew Knepley } 2853bf14a46SMatthew Knepley lu->nSolve++; 2863bf14a46SMatthew Knepley PetscFunctionReturn(0); 2873bf14a46SMatthew Knepley } 2883bf14a46SMatthew Knepley 2893bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX) 2903bf14a46SMatthew Knepley /* 2913bf14a46SMatthew Knepley TODO: Fill this function 2923bf14a46SMatthew Knepley I didn't fill this function 2933bf14a46SMatthew Knepley because I didn't understood its goal. 2943bf14a46SMatthew Knepley */ 2953bf14a46SMatthew Knepley 2963bf14a46SMatthew Knepley /* 2973bf14a46SMatthew Knepley input: 2983bf14a46SMatthew Knepley F: numeric factor 2993bf14a46SMatthew Knepley output: 3003bf14a46SMatthew Knepley nneg: total number of pivots 3013bf14a46SMatthew Knepley nzero: 0 3023bf14a46SMatthew Knepley npos: (global dimension of F) - nneg 3033bf14a46SMatthew Knepley */ 3043bf14a46SMatthew Knepley 3053bf14a46SMatthew Knepley #undef __FUNCT__ 3063bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInertia_SBAIJPASTIX" 3073bf14a46SMatthew Knepley PetscErrorCode MatGetInertia_SBAIJPASTIX(Mat F,int *nneg,int *nzero,int *npos) 3083bf14a46SMatthew Knepley { 3093bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)F->spptr; 3103bf14a46SMatthew Knepley PetscErrorCode ierr; 3113bf14a46SMatthew Knepley PetscMPIInt size; 3123bf14a46SMatthew Knepley 3133bf14a46SMatthew Knepley PetscFunctionBegin; 3143bf14a46SMatthew Knepley /* ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr); */ 3153bf14a46SMatthew Knepley /* /\* PASTIX 4.3.1 calls ScaLAPACK when ICNTL(13)=0 (default), which does not offer the possibility to compute the inertia of a dense matrix. Set ICNTL(13)=1 to skip ScaLAPACK *\/ */ 3163bf14a46SMatthew Knepley /* if (size > 1 && lu->id.ICNTL(13) != 1){ */ 3173bf14a46SMatthew Knepley /* SETERRQ1(PETSC_ERR_ARG_WRONG,"ICNTL(13)=%d. -mat_pastix_icntl_13 must be set as 1 for correct global matrix inertia\n",lu->id.INFOG(13)); */ 3183bf14a46SMatthew Knepley /* } */ 3193bf14a46SMatthew Knepley /* if (nneg){ */ 3203bf14a46SMatthew Knepley /* if (!lu->commSize){ */ 3213bf14a46SMatthew Knepley /* *nneg = lu->id.INFOG(12); */ 3223bf14a46SMatthew Knepley /* } */ 3233bf14a46SMatthew Knepley /* ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_pastix);CHKERRQ(ierr); */ 3243bf14a46SMatthew Knepley /* } */ 3253bf14a46SMatthew Knepley /* if (nzero) *nzero = lu->iparm[IPARM_NNZEROS]; */ 3263bf14a46SMatthew Knepley /* if (npos) *npos = F->rmap->N - (*nneg); */ 3273bf14a46SMatthew Knepley PetscFunctionReturn(0); 3283bf14a46SMatthew Knepley } 3293bf14a46SMatthew Knepley #endif /* !defined(PETSC_USE_COMPLEX) */ 3303bf14a46SMatthew Knepley 3313bf14a46SMatthew Knepley /* 3323bf14a46SMatthew Knepley Numeric factorisation using PaStiX solver. 3333bf14a46SMatthew Knepley 3343bf14a46SMatthew Knepley */ 3353bf14a46SMatthew Knepley #undef __FUNCT__ 3363bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorNumeric_PASTIX" 3373bf14a46SMatthew Knepley PetscErrorCode MatFactorNumeric_PaStiX(Mat F,Mat A,const MatFactorInfo *info) 3383bf14a46SMatthew Knepley { 3393bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)(F)->spptr; 3403bf14a46SMatthew Knepley Mat *tseq,A_seq = PETSC_NULL; 3413bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 3423bf14a46SMatthew Knepley PetscInt rnz,nnz,nz=0,i,*ai,*aj,icntl; 3433bf14a46SMatthew Knepley PetscInt M=A->rmap->N,N=A->cmap->N; 3443bf14a46SMatthew Knepley PetscTruth valOnly,flg, isSym; 3453bf14a46SMatthew Knepley Mat F_diag; 3463bf14a46SMatthew Knepley IS is_iden; 3473bf14a46SMatthew Knepley Vec b; 3483bf14a46SMatthew Knepley IS isrow; 3493bf14a46SMatthew Knepley PetscTruth isSeqAIJ,isSeqSBAIJ; 3503bf14a46SMatthew Knepley Mat_SeqAIJ *aa,*bb; 3513bf14a46SMatthew Knepley 3523bf14a46SMatthew Knepley PetscFunctionBegin; 3533bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)A,MATSEQAIJ,&isSeqAIJ);CHKERRQ(ierr); 3543bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)A,MATSEQSBAIJ,&isSeqSBAIJ);CHKERRQ(ierr); 3553bf14a46SMatthew Knepley if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 3563bf14a46SMatthew Knepley (F)->ops->solve = MatSolve_PaStiX; 3573bf14a46SMatthew Knepley 3583bf14a46SMatthew Knepley /* Initialize a PASTIX instance */ 3593bf14a46SMatthew Knepley ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->pastix_comm));CHKERRQ(ierr); 3603bf14a46SMatthew Knepley ierr = MPI_Comm_rank(lu->pastix_comm, &lu->commRank); CHKERRQ(ierr); 3613bf14a46SMatthew Knepley ierr = MPI_Comm_size(lu->pastix_comm, &lu->commSize); CHKERRQ(ierr); 3623bf14a46SMatthew Knepley 3633bf14a46SMatthew Knepley /* Set pastix options */ 3643bf14a46SMatthew Knepley lu->iparm[IPARM_MODIFY_PARAMETER] = API_NO; 3653bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_INIT; 3663bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_INIT; 3673bf14a46SMatthew Knepley lu->rhsnbr = 1; 3683bf14a46SMatthew Knepley 3693bf14a46SMatthew Knepley /* Call to set default pastix options */ 3703bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 3713bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 3723bf14a46SMatthew Knepley (pastix_int_t) lu->n, 3733bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 3743bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 3753bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 3763bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 3773bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 3783bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 3793bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 3803bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 3813bf14a46SMatthew Knepley (double*) lu->dparm); 3823bf14a46SMatthew Knepley 3833bf14a46SMatthew Knepley ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"PaStiX Options","Mat");CHKERRQ(ierr); 3843bf14a46SMatthew Knepley 3853bf14a46SMatthew Knepley icntl=-1; 3863bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE] = API_VERBOSE_NO; 3873bf14a46SMatthew Knepley ierr = PetscOptionsInt("-mat_pastix_verbose","iparm[IPARM_VERBOSE] : level of printing (0 to 2)","None", 3883bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE],&icntl,&flg);CHKERRQ(ierr); 3893bf14a46SMatthew Knepley if ((flg && icntl > 0) || PetscLogPrintInfo) { 3903bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE] = icntl; 3913bf14a46SMatthew Knepley } 3923bf14a46SMatthew Knepley icntl=-1; 3933bf14a46SMatthew Knepley ierr = PetscOptionsInt("-mat_pastix_threadnbr","iparm[IPARM_THREAD_NBR] : Number of thread by MPI node", 3943bf14a46SMatthew Knepley "None",lu->iparm[IPARM_THREAD_NBR],&icntl,PETSC_NULL);CHKERRQ(ierr); 3953bf14a46SMatthew Knepley if ((flg && icntl > 0)) { 3963bf14a46SMatthew Knepley lu->iparm[IPARM_THREAD_NBR] = icntl; 3973bf14a46SMatthew Knepley } 3983bf14a46SMatthew Knepley PetscOptionsEnd(); 3993bf14a46SMatthew Knepley valOnly = PETSC_FALSE; 4003bf14a46SMatthew Knepley } 4013bf14a46SMatthew Knepley else { 4023bf14a46SMatthew Knepley valOnly = PETSC_TRUE; 4033bf14a46SMatthew Knepley } 4043bf14a46SMatthew Knepley 4053bf14a46SMatthew Knepley lu->iparm[IPARM_MATRIX_VERIFICATION] = API_YES; 4063bf14a46SMatthew Knepley 4073bf14a46SMatthew Knepley /* convert mpi A to seq mat A */ 4083bf14a46SMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);CHKERRQ(ierr); 4093bf14a46SMatthew Knepley ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&tseq);CHKERRQ(ierr); 4103bf14a46SMatthew Knepley ierr = ISDestroy(isrow);CHKERRQ(ierr); 4113bf14a46SMatthew Knepley A_seq = *tseq; 4123bf14a46SMatthew Knepley ierr = PetscFree(tseq);CHKERRQ(ierr); 4133bf14a46SMatthew Knepley 4143bf14a46SMatthew Knepley ierr = MatConvertToCSC(A_seq,valOnly, &lu->n, &lu->colptr, &lu->row, &lu->val); CHKERRQ(ierr); 4153bf14a46SMatthew Knepley ierr = PetscMalloc((lu->n)*sizeof(PetscInt) ,&(lu->perm));CHKERRQ(ierr); 4163bf14a46SMatthew Knepley ierr = PetscMalloc((lu->n)*sizeof(PetscInt) ,&(lu->invp));CHKERRQ(ierr); 4173bf14a46SMatthew Knepley 4183bf14a46SMatthew Knepley MatIsSymmetric_SeqAIJ(A_seq,0.0,&isSym); 4193bf14a46SMatthew Knepley 4203bf14a46SMatthew Knepley if (isSym) { 421*745c78f7SBarry Smith /* On symmetric matrix, LLT */ 4223bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_YES; 4233bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LLT; 4243bf14a46SMatthew Knepley } 4253bf14a46SMatthew Knepley else { 426*745c78f7SBarry Smith /* On unsymmetric matrix, LU */ 4273bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_NO; 4283bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU; 4293bf14a46SMatthew Knepley } 4303bf14a46SMatthew Knepley 4313bf14a46SMatthew Knepley /*----------------*/ 4323bf14a46SMatthew Knepley if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 4333bf14a46SMatthew Knepley if (!(isSeqAIJ || isSeqSBAIJ)) { 4343bf14a46SMatthew Knepley /* PaStiX only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */ 4353bf14a46SMatthew Knepley ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap->N,&lu->b_seq);CHKERRQ(ierr); 4363bf14a46SMatthew Knepley ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,&is_iden);CHKERRQ(ierr); 4373bf14a46SMatthew Knepley ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr); 4383bf14a46SMatthew Knepley ierr = VecSetSizes(b,A->rmap->n,PETSC_DECIDE);CHKERRQ(ierr); 4393bf14a46SMatthew Knepley ierr = VecSetFromOptions(b);CHKERRQ(ierr); 4403bf14a46SMatthew Knepley 4413bf14a46SMatthew Knepley ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr); 4423bf14a46SMatthew Knepley ierr = VecScatterCreate(lu->b_seq,is_iden,b,is_iden,&lu->scat_sol);CHKERRQ(ierr); 4433bf14a46SMatthew Knepley ierr = ISDestroy(is_iden);CHKERRQ(ierr); 4443bf14a46SMatthew Knepley ierr = VecDestroy(b);CHKERRQ(ierr); 4453bf14a46SMatthew Knepley } 4463bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_ORDERING; 4473bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_NUMFACT; 4483bf14a46SMatthew Knepley 4493bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 4503bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 4513bf14a46SMatthew Knepley (pastix_int_t) lu->n, 4523bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 4533bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 4543bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 4553bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 4563bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 4573bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 4583bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 4593bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 4603bf14a46SMatthew Knepley (double*) lu->dparm); 4613bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 4623bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n", 4633bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER]); 4643bf14a46SMatthew Knepley } 4653bf14a46SMatthew Knepley } 4663bf14a46SMatthew Knepley else { 4673bf14a46SMatthew Knepley lu->iparm[IPARM_START_TASK] = API_TASK_NUMFACT; 4683bf14a46SMatthew Knepley lu->iparm[IPARM_END_TASK] = API_TASK_NUMFACT; 4693bf14a46SMatthew Knepley pastix((pastix_data_t **)&(lu->pastix_data), 4703bf14a46SMatthew Knepley (MPI_Comm) lu->pastix_comm, 4713bf14a46SMatthew Knepley (pastix_int_t) lu->n, 4723bf14a46SMatthew Knepley (pastix_int_t*) lu->colptr, 4733bf14a46SMatthew Knepley (pastix_int_t*) lu->row, 4743bf14a46SMatthew Knepley (pastix_float_t*) lu->val, 4753bf14a46SMatthew Knepley (pastix_int_t*) lu->perm, 4763bf14a46SMatthew Knepley (pastix_int_t*) lu->invp, 4773bf14a46SMatthew Knepley (pastix_float_t*) lu->rhs, 4783bf14a46SMatthew Knepley (pastix_int_t) lu->rhsnbr, 4793bf14a46SMatthew Knepley (pastix_int_t*) lu->iparm, 4803bf14a46SMatthew Knepley (double*) lu->dparm); 4813bf14a46SMatthew Knepley 4823bf14a46SMatthew Knepley if (lu->iparm[IPARM_ERROR_NUMBER] < 0) { 4833bf14a46SMatthew Knepley SETERRQ1(PETSC_ERR_LIB,"Error reported by PaStiX in analysis phase: ipparm(IPARM_ERROR_NUMBER)=%d\n", 4843bf14a46SMatthew Knepley lu->iparm[IPARM_ERROR_NUMBER]); 4853bf14a46SMatthew Knepley } 4863bf14a46SMatthew Knepley } 4873bf14a46SMatthew Knepley 4883bf14a46SMatthew Knepley if (lu->commSize > 1){ 4893bf14a46SMatthew Knepley if ((F)->factor == MAT_FACTOR_LU){ 4903bf14a46SMatthew Knepley F_diag = ((Mat_MPIAIJ *)(F)->data)->A; 4913bf14a46SMatthew Knepley } else { 4923bf14a46SMatthew Knepley F_diag = ((Mat_MPISBAIJ *)(F)->data)->A; 4933bf14a46SMatthew Knepley } 4943bf14a46SMatthew Knepley F_diag->assembled = PETSC_TRUE; 4953bf14a46SMatthew Knepley if (lu->nSolve){ 4963bf14a46SMatthew Knepley ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr); 4973bf14a46SMatthew Knepley ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr); 4983bf14a46SMatthew Knepley } 4993bf14a46SMatthew Knepley } 5003bf14a46SMatthew Knepley (F)->assembled = PETSC_TRUE; 5013bf14a46SMatthew Knepley lu->matstruc = SAME_NONZERO_PATTERN; 5023bf14a46SMatthew Knepley lu->CleanUpPastix = PETSC_TRUE; 5033bf14a46SMatthew Knepley lu->nSolve = 0; 5043bf14a46SMatthew Knepley PetscFunctionReturn(0); 5053bf14a46SMatthew Knepley } 5063bf14a46SMatthew Knepley 5073bf14a46SMatthew Knepley 5083bf14a46SMatthew Knepley /* Note the Petsc r and c permutations are ignored */ 5093bf14a46SMatthew Knepley #undef __FUNCT__ 5103bf14a46SMatthew Knepley #define __FUNCT__ "MatLUFactorSymbolic_AIJPASTIX" 5113bf14a46SMatthew Knepley PetscErrorCode MatLUFactorSymbolic_AIJPASTIX(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 5123bf14a46SMatthew Knepley { 5133bf14a46SMatthew Knepley Mat_Pastix *lu = (Mat_Pastix*)F->spptr; 5143bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 5153bf14a46SMatthew Knepley 5163bf14a46SMatthew Knepley PetscFunctionBegin; 5173bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LU; 5183bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_YES; 5193bf14a46SMatthew Knepley lu->matstruc = DIFFERENT_NONZERO_PATTERN; 5203bf14a46SMatthew Knepley F->ops->lufactornumeric = MatFactorNumeric_PaStiX; 5213bf14a46SMatthew Knepley PetscFunctionReturn(0); 5223bf14a46SMatthew Knepley } 5233bf14a46SMatthew Knepley 5243bf14a46SMatthew Knepley 5253bf14a46SMatthew Knepley /* Note the Petsc r permutation is ignored */ 5263bf14a46SMatthew Knepley #undef __FUNCT__ 5273bf14a46SMatthew Knepley #define __FUNCT__ "MatCholeskyFactorSymbolic_SBAIJPASTIX" 5283bf14a46SMatthew Knepley PetscErrorCode MatCholeskyFactorSymbolic_SBAIJPASTIX(Mat F,Mat A,IS r,const MatFactorInfo *info) 5293bf14a46SMatthew Knepley { 5303bf14a46SMatthew Knepley Mat_Pastix *lu = (Mat_Pastix*)(F)->spptr; 5313bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 5323bf14a46SMatthew Knepley 5333bf14a46SMatthew Knepley PetscFunctionBegin; 5343bf14a46SMatthew Knepley lu->iparm[IPARM_FACTORIZATION] = API_FACT_LLT; 5353bf14a46SMatthew Knepley lu->iparm[IPARM_SYM] = API_SYM_NO; 5363bf14a46SMatthew Knepley lu->matstruc = DIFFERENT_NONZERO_PATTERN; 5373bf14a46SMatthew Knepley (F)->ops->choleskyfactornumeric = MatFactorNumeric_PaStiX; 5383bf14a46SMatthew Knepley #if !defined(PETSC_USE_COMPLEX) 5393bf14a46SMatthew Knepley (F)->ops->getinertia = MatGetInertia_SBAIJPASTIX; 5403bf14a46SMatthew Knepley #endif 5413bf14a46SMatthew Knepley PetscFunctionReturn(0); 5423bf14a46SMatthew Knepley } 5433bf14a46SMatthew Knepley 5443bf14a46SMatthew Knepley #undef __FUNCT__ 5453bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorInfo_PaStiX" 5463bf14a46SMatthew Knepley PetscErrorCode MatFactorInfo_PaStiX(Mat A,PetscViewer viewer) { 5473bf14a46SMatthew Knepley Mat_Pastix *lu=(Mat_Pastix*)A->spptr; 5483bf14a46SMatthew Knepley PetscErrorCode ierr; 5493bf14a46SMatthew Knepley 5503bf14a46SMatthew Knepley PetscFunctionBegin; 5513bf14a46SMatthew Knepley /* check if matrix is pastix type */ 5523bf14a46SMatthew Knepley if (A->ops->solve != MatSolve_PaStiX) PetscFunctionReturn(0); 5533bf14a46SMatthew Knepley 5543bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"PaStiX run parameters:\n");CHKERRQ(ierr); 5553bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Matrix type : %s \n", 556*745c78f7SBarry Smith ((lu->iparm[IPARM_SYM] == API_SYM_YES)?"Symmetric":"Unsymmetric"));CHKERRQ(ierr); 5573bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Level of printing (0,1,2): %d \n", 5583bf14a46SMatthew Knepley lu->iparm[IPARM_VERBOSE]);CHKERRQ(ierr); 5593bf14a46SMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer," Number of refinements iterations : %d \n", 5603bf14a46SMatthew Knepley lu->iparm[IPARM_NBITER]);CHKERRQ(ierr); 5613bf14a46SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF," Error : %g \n", 5623bf14a46SMatthew Knepley lu->dparm[DPARM_RELATIVE_ERROR]);CHKERRQ(ierr); 5633bf14a46SMatthew Knepley PetscFunctionReturn(0); 5643bf14a46SMatthew Knepley } 5653bf14a46SMatthew Knepley 5663bf14a46SMatthew Knepley #undef __FUNCT__ 5673bf14a46SMatthew Knepley #define __FUNCT__ "MatView_PaStiX" 5683bf14a46SMatthew Knepley PetscErrorCode MatView_PaStiX(Mat A,PetscViewer viewer) 5693bf14a46SMatthew Knepley { 5703bf14a46SMatthew Knepley PetscErrorCode ierr; 5713bf14a46SMatthew Knepley PetscTruth iascii; 5723bf14a46SMatthew Knepley PetscViewerFormat format; 5733bf14a46SMatthew Knepley 5743bf14a46SMatthew Knepley PetscFunctionBegin; 5753bf14a46SMatthew Knepley ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 5763bf14a46SMatthew Knepley if (iascii) { 5773bf14a46SMatthew Knepley ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 5783bf14a46SMatthew Knepley if (format == PETSC_VIEWER_ASCII_INFO){ 5793bf14a46SMatthew Knepley ierr = MatFactorInfo_PaStiX(A,viewer);CHKERRQ(ierr); 5803bf14a46SMatthew Knepley } 5813bf14a46SMatthew Knepley } 5823bf14a46SMatthew Knepley PetscFunctionReturn(0); 5833bf14a46SMatthew Knepley } 5843bf14a46SMatthew Knepley 5853bf14a46SMatthew Knepley 5863bf14a46SMatthew Knepley /*MC 5873bf14a46SMatthew Knepley MATAIJPASTIX - MATAIJPASTIX = "aijpastix" - A matrix type providing direct solvers (LU) for distributed 5883bf14a46SMatthew Knepley and sequential matrices via the external package PaStiX. 5893bf14a46SMatthew Knepley 5903bf14a46SMatthew Knepley If PaStiX is installed (see the manual for instructions 5913bf14a46SMatthew Knepley on how to declare the existence of external packages), 5923bf14a46SMatthew Knepley a matrix type can be constructed which invokes PaStiX solvers. 5933bf14a46SMatthew Knepley After calling MatCreate(...,A), simply call MatSetType(A,MATAIJPASTIX), then 5943bf14a46SMatthew Knepley optionally call MatSeqAIJSetPreallocation() or MatMPIAIJSetPreallocation() etc DO NOT 5953bf14a46SMatthew Knepley call MatCreateSeqAIJ/MPIAIJ() directly or the preallocation information will be LOST! 5963bf14a46SMatthew Knepley 5973bf14a46SMatthew Knepley If created with a single process communicator, this matrix type inherits from MATSEQAIJ. 5983bf14a46SMatthew Knepley Otherwise, this matrix type inherits from MATMPIAIJ. Hence for single process communicators, 5993bf14a46SMatthew Knepley MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 6003bf14a46SMatthew Knepley for communicators controlling multiple processes. It is recommended that you call both of 6013bf14a46SMatthew Knepley the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 6023bf14a46SMatthew Knepley conversion to or from the MATSEQAIJ or MATMPIAIJ type (depending on the communicator size) 6033bf14a46SMatthew Knepley without data copy AFTER the matrix values are set. 6043bf14a46SMatthew Knepley 6053bf14a46SMatthew Knepley Options Database Keys: 6063bf14a46SMatthew Knepley + -mat_type sbaijpastix - sets the matrix type to "sbaijpastix" during a call to MatSetFromOptions() 6073bf14a46SMatthew Knepley . -mat_pastix_sym <0,1> - 0 the matrix is symmetric, 1 unsymmetric 6083bf14a46SMatthew Knepley . -mat_pastix_verbose <0,1,2> - print level 6093bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task. 6103bf14a46SMatthew Knepley 6113bf14a46SMatthew Knepley Level: beginner 6123bf14a46SMatthew Knepley 6133bf14a46SMatthew Knepley .seealso: MATSBAIJPASTIX 6143bf14a46SMatthew Knepley M*/ 6153bf14a46SMatthew Knepley 6163bf14a46SMatthew Knepley 6173bf14a46SMatthew Knepley #undef __FUNCT__ 6183bf14a46SMatthew Knepley #define __FUNCT__ "MatGetInfo_PaStiX" 6193bf14a46SMatthew Knepley PetscErrorCode MatGetInfo_PaStiX(Mat A,MatInfoType flag,MatInfo *info) 6203bf14a46SMatthew Knepley { 6213bf14a46SMatthew Knepley Mat_Pastix *lu =(Mat_Pastix*)A->spptr; 6223bf14a46SMatthew Knepley PetscErrorCode ierr; 6233bf14a46SMatthew Knepley 6243bf14a46SMatthew Knepley PetscFunctionBegin; 6253bf14a46SMatthew Knepley info->block_size = 1.0; 6263bf14a46SMatthew Knepley info->nz_allocated = lu->iparm[IPARM_NNZEROS]; 6273bf14a46SMatthew Knepley info->nz_used = lu->iparm[IPARM_NNZEROS]; 6283bf14a46SMatthew Knepley info->nz_unneeded = 0.0; 6293bf14a46SMatthew Knepley info->assemblies = 0.0; 6303bf14a46SMatthew Knepley info->mallocs = 0.0; 6313bf14a46SMatthew Knepley info->memory = 0.0; 6323bf14a46SMatthew Knepley info->fill_ratio_given = 0; 6333bf14a46SMatthew Knepley info->fill_ratio_needed = 0; 6343bf14a46SMatthew Knepley info->factor_mallocs = 0; 6353bf14a46SMatthew Knepley PetscFunctionReturn(0); 6363bf14a46SMatthew Knepley } 6373bf14a46SMatthew Knepley 6383bf14a46SMatthew Knepley /*MC 6393bf14a46SMatthew Knepley MATSBAIJPASTIX - MATSBAIJPASTIX = "sbaijpastix" - A symmetric matrix type providing direct solvers (Cholesky) for 6403bf14a46SMatthew Knepley distributed and sequential matrices via the external package PaStiX. 6413bf14a46SMatthew Knepley 6423bf14a46SMatthew Knepley If PaStiX is installed (see the manual for instructions 6433bf14a46SMatthew Knepley on how to declare the existence of external packages), 6443bf14a46SMatthew Knepley a matrix type can be constructed which invokes PaStiX solvers. 6453bf14a46SMatthew Knepley After calling MatCreate(...,A), simply call MatSetType(A,MATSBAIJPASTIX), then 6463bf14a46SMatthew Knepley optionally call MatSeqSBAIJSetPreallocation() or MatMPISBAIJSetPreallocation() DO NOT 6473bf14a46SMatthew Knepley call MatCreateSeqSBAIJ/MPISBAIJ() directly or the preallocation information will be LOST! 6483bf14a46SMatthew Knepley 6493bf14a46SMatthew Knepley If created with a single process communicator, this matrix type inherits from MATSEQSBAIJ. 6503bf14a46SMatthew Knepley Otherwise, this matrix type inherits from MATMPISBAIJ. Hence for single process communicators, 6513bf14a46SMatthew Knepley MatSeqSBAIJSetPreallocation() is supported, and similarly MatMPISBAIJSetPreallocation() is supported 6523bf14a46SMatthew Knepley for communicators controlling multiple processes. It is recommended that you call both of 6533bf14a46SMatthew Knepley the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 6543bf14a46SMatthew Knepley conversion to or from the MATSEQSBAIJ or MATMPISBAIJ type (depending on the communicator size) 6553bf14a46SMatthew Knepley without data copy AFTER the matrix values have been set. 6563bf14a46SMatthew Knepley 6573bf14a46SMatthew Knepley Options Database Keys: 6583bf14a46SMatthew Knepley + -mat_type aijpastix - sets the matrix type to "aijpastix" during a call to MatSetFromOptions() 6593bf14a46SMatthew Knepley . -mat_pastix_sym <0,1> - 0 the matrix is symmetric, 1 unsymmetric 6603bf14a46SMatthew Knepley . -mat_pastix_verbose <0,1,2> - print level 6613bf14a46SMatthew Knepley . -mat_pastix_threadnbr <integer> - Set the thread number by MPI task. 6623bf14a46SMatthew Knepley Level: beginner 6633bf14a46SMatthew Knepley 6643bf14a46SMatthew Knepley .seealso: MATAIJPASTIX 6653bf14a46SMatthew Knepley M*/ 6663bf14a46SMatthew Knepley 6673bf14a46SMatthew Knepley EXTERN_C_BEGIN 6683bf14a46SMatthew Knepley #undef __FUNCT__ 6693bf14a46SMatthew Knepley #define __FUNCT__ "MatFactorGetSolverPackage_pastix" 6703bf14a46SMatthew Knepley PetscErrorCode MatFactorGetSolverPackage_pastix(Mat A,const MatSolverPackage *type) 6713bf14a46SMatthew Knepley { 6723bf14a46SMatthew Knepley PetscErrorCode ierr = 0; 6733bf14a46SMatthew Knepley 6743bf14a46SMatthew Knepley PetscFunctionBegin; 6753bf14a46SMatthew Knepley *type = MAT_SOLVER_PASTIX; 6763bf14a46SMatthew Knepley PetscFunctionReturn(0); 6773bf14a46SMatthew Knepley } 6783bf14a46SMatthew Knepley EXTERN_C_END 6793bf14a46SMatthew Knepley 6803bf14a46SMatthew Knepley EXTERN_C_BEGIN 6813bf14a46SMatthew Knepley /* 6823bf14a46SMatthew Knepley The seq and mpi versions of this function are the same 6833bf14a46SMatthew Knepley */ 6843bf14a46SMatthew Knepley #undef __FUNCT__ 6853bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqaij_pastix" 6863bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqaij_pastix(Mat A,MatFactorType ftype,Mat *F) 6873bf14a46SMatthew Knepley { 6883bf14a46SMatthew Knepley Mat B; 6893bf14a46SMatthew Knepley PetscErrorCode ierr; 6903bf14a46SMatthew Knepley Mat_Pastix *pastix; 6913bf14a46SMatthew Knepley 6923bf14a46SMatthew Knepley PetscFunctionBegin; 6933bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_LU) { 6943bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix"); 6953bf14a46SMatthew Knepley } 6963bf14a46SMatthew Knepley /* Create the factorization matrix */ 6973bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 6983bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 6993bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 7003bf14a46SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 7013bf14a46SMatthew Knepley 7023bf14a46SMatthew Knepley B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX; 7033bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 7043bf14a46SMatthew Knepley B->ops->getinfo = MatGetInfo_PaStiX; 7053bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C", 7063bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 7073bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 7083bf14a46SMatthew Knepley B->factor = MAT_FACTOR_LU; 7093bf14a46SMatthew Knepley 7103bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 7113bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 7123bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 7133bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 7143bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 7153bf14a46SMatthew Knepley pastix->nSolve = 0; 7163bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 7173bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 7183bf14a46SMatthew Knepley B->spptr = (void*)pastix; 7193bf14a46SMatthew Knepley 7203bf14a46SMatthew Knepley *F = B; 7213bf14a46SMatthew Knepley PetscFunctionReturn(0); 7223bf14a46SMatthew Knepley } 7233bf14a46SMatthew Knepley EXTERN_C_END 7243bf14a46SMatthew Knepley 7253bf14a46SMatthew Knepley EXTERN_C_BEGIN 7263bf14a46SMatthew Knepley #undef __FUNCT__ 7273bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpiaij_pastix" 7283bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpiaij_pastix(Mat A,MatFactorType ftype,Mat *F) 7293bf14a46SMatthew Knepley { 7303bf14a46SMatthew Knepley Mat B; 7313bf14a46SMatthew Knepley PetscErrorCode ierr; 7323bf14a46SMatthew Knepley Mat_Pastix *pastix; 7333bf14a46SMatthew Knepley 7343bf14a46SMatthew Knepley PetscFunctionBegin; 7353bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_LU) { 7363bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc AIJ matrices with PaStiX Cholesky, use SBAIJ matrix"); 7373bf14a46SMatthew Knepley } 7383bf14a46SMatthew Knepley /* Create the factorization matrix */ 7393bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 7403bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 7413bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 7423bf14a46SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 7433bf14a46SMatthew Knepley ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 7443bf14a46SMatthew Knepley 7453bf14a46SMatthew Knepley B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJPASTIX; 7463bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 7473bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 7483bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 7493bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 7503bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 7513bf14a46SMatthew Knepley B->factor = MAT_FACTOR_LU; 7523bf14a46SMatthew Knepley 7533bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 7543bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 7553bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 7563bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 7573bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 7583bf14a46SMatthew Knepley pastix->nSolve = 0; 7593bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 7603bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 7613bf14a46SMatthew Knepley B->spptr = (void*)pastix; 7623bf14a46SMatthew Knepley 7633bf14a46SMatthew Knepley *F = B; 7643bf14a46SMatthew Knepley PetscFunctionReturn(0); 7653bf14a46SMatthew Knepley } 7663bf14a46SMatthew Knepley EXTERN_C_END 7673bf14a46SMatthew Knepley 7683bf14a46SMatthew Knepley EXTERN_C_BEGIN 7693bf14a46SMatthew Knepley #undef __FUNCT__ 7703bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_seqsbaij_pastix" 7713bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat A,MatFactorType ftype,Mat *F) 7723bf14a46SMatthew Knepley { 7733bf14a46SMatthew Knepley Mat B; 7743bf14a46SMatthew Knepley PetscErrorCode ierr; 7753bf14a46SMatthew Knepley Mat_Pastix *pastix; 7763bf14a46SMatthew Knepley 7773bf14a46SMatthew Knepley PetscFunctionBegin; 7783bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_CHOLESKY) { 7793bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix"); 7803bf14a46SMatthew Knepley } 7813bf14a46SMatthew Knepley /* Create the factorization matrix */ 7823bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 7833bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 7843bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 7853bf14a46SMatthew Knepley ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr); 7863bf14a46SMatthew Knepley ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 7873bf14a46SMatthew Knepley 7883bf14a46SMatthew Knepley B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX; 7893bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 7903bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 7913bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 7923bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 7933bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 7943bf14a46SMatthew Knepley 7953bf14a46SMatthew Knepley B->factor = MAT_FACTOR_CHOLESKY; 7963bf14a46SMatthew Knepley 7973bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 7983bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 7993bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 8003bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 8013bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 8023bf14a46SMatthew Knepley pastix->nSolve = 0; 8033bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 8043bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 8053bf14a46SMatthew Knepley B->spptr = (void*)pastix; 8063bf14a46SMatthew Knepley 8073bf14a46SMatthew Knepley *F = B; 8083bf14a46SMatthew Knepley PetscFunctionReturn(0); 8093bf14a46SMatthew Knepley } 8103bf14a46SMatthew Knepley EXTERN_C_END 8113bf14a46SMatthew Knepley 8123bf14a46SMatthew Knepley EXTERN_C_BEGIN 8133bf14a46SMatthew Knepley #undef __FUNCT__ 8143bf14a46SMatthew Knepley #define __FUNCT__ "MatGetFactor_mpisbaij_pastix" 8153bf14a46SMatthew Knepley PetscErrorCode MatGetFactor_mpisbaij_pastix(Mat A,MatFactorType ftype,Mat *F) 8163bf14a46SMatthew Knepley { 8173bf14a46SMatthew Knepley Mat B; 8183bf14a46SMatthew Knepley PetscErrorCode ierr; 8193bf14a46SMatthew Knepley Mat_Pastix *pastix; 8203bf14a46SMatthew Knepley 8213bf14a46SMatthew Knepley PetscFunctionBegin; 8223bf14a46SMatthew Knepley if (ftype != MAT_FACTOR_CHOLESKY) { 8233bf14a46SMatthew Knepley SETERRQ(PETSC_ERR_SUP,"Cannot use PETSc SBAIJ matrices with PaStiX LU, use AIJ matrix"); 8243bf14a46SMatthew Knepley } 8253bf14a46SMatthew Knepley /* Create the factorization matrix */ 8263bf14a46SMatthew Knepley ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 8273bf14a46SMatthew Knepley ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 8283bf14a46SMatthew Knepley ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 8293bf14a46SMatthew Knepley ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr); 8303bf14a46SMatthew Knepley ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 8313bf14a46SMatthew Knepley 8323bf14a46SMatthew Knepley B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJPASTIX; 8333bf14a46SMatthew Knepley B->ops->view = MatView_PaStiX; 8343bf14a46SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)B, 8353bf14a46SMatthew Knepley "MatFactorGetSolverPackage_C", 8363bf14a46SMatthew Knepley "MatFactorGetSolverPackage_pastix", 8373bf14a46SMatthew Knepley MatFactorGetSolverPackage_pastix);CHKERRQ(ierr); 8383bf14a46SMatthew Knepley B->factor = MAT_FACTOR_CHOLESKY; 8393bf14a46SMatthew Knepley 8403bf14a46SMatthew Knepley ierr = PetscNewLog(B,Mat_Pastix,&pastix);CHKERRQ(ierr); 8413bf14a46SMatthew Knepley pastix->CleanUpPastix = PETSC_FALSE; 8423bf14a46SMatthew Knepley pastix->isAIJ = PETSC_TRUE; 8433bf14a46SMatthew Knepley pastix->scat_rhs = PETSC_NULL; 8443bf14a46SMatthew Knepley pastix->scat_sol = PETSC_NULL; 8453bf14a46SMatthew Knepley pastix->nSolve = 0; 8463bf14a46SMatthew Knepley pastix->MatDestroy = B->ops->destroy; 8473bf14a46SMatthew Knepley B->ops->destroy = MatDestroy_Pastix; 8483bf14a46SMatthew Knepley B->spptr = (void*)pastix; 8493bf14a46SMatthew Knepley 8503bf14a46SMatthew Knepley *F = B; 8513bf14a46SMatthew Knepley PetscFunctionReturn(0); 8523bf14a46SMatthew Knepley } 8533bf14a46SMatthew Knepley EXTERN_C_END 854