1e8aa55a4SKris Buschelman 2e8aa55a4SKris Buschelman /* 3e8aa55a4SKris Buschelman Provides an interface to the IBM RS6000 Essl sparse solver 4e8aa55a4SKris Buschelman 5e8aa55a4SKris Buschelman */ 6e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h" 7e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work! */ 8e8aa55a4SKris Buschelman 9e8aa55a4SKris Buschelman typedef struct { 10e8aa55a4SKris Buschelman int n,nz; 11e8aa55a4SKris Buschelman PetscScalar *a; 12e8aa55a4SKris Buschelman int *ia; 13e8aa55a4SKris Buschelman int *ja; 14e8aa55a4SKris Buschelman int lna; 15e8aa55a4SKris Buschelman int iparm[5]; 16e8aa55a4SKris Buschelman PetscReal rparm[5]; 17e8aa55a4SKris Buschelman PetscReal oparm[5]; 18e8aa55a4SKris Buschelman PetscScalar *aux; 19e8aa55a4SKris Buschelman int naux; 20e8aa55a4SKris Buschelman 216849ba73SBarry Smith PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 226849ba73SBarry Smith PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 236849ba73SBarry Smith PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 246849ba73SBarry Smith PetscErrorCode (*MatDestroy)(Mat); 252f71e704SKris Buschelman PetscTruth CleanUpESSL; 26f0c56d0fSKris Buschelman } Mat_Essl; 27f0c56d0fSKris Buschelman 28dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*); 29e8aa55a4SKris Buschelman 30460c4903SKris Buschelman EXTERN_C_BEGIN 31460c4903SKris Buschelman #undef __FUNCT__ 32460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ" 33ceb03754SKris Buschelman PetscErrorCode MatConvert_Essl_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat) { 34dfbe8321SBarry Smith PetscErrorCode ierr; 35460c4903SKris Buschelman Mat B=*newmat; 36f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 37460c4903SKris Buschelman 38460c4903SKris Buschelman PetscFunctionBegin; 39ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 40460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); 41f0c56d0fSKris Buschelman } 42f0c56d0fSKris Buschelman B->ops->duplicate = essl->MatDuplicate; 43f0c56d0fSKris Buschelman B->ops->assemblyend = essl->MatAssemblyEnd; 442f71e704SKris Buschelman B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic; 452f71e704SKris Buschelman B->ops->destroy = essl->MatDestroy; 462f71e704SKris Buschelman 47460c4903SKris Buschelman /* free the Essl datastructures */ 48460c4903SKris Buschelman ierr = PetscFree(essl);CHKERRQ(ierr); 49901853e0SKris Buschelman 50901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr); 51901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 52901853e0SKris Buschelman 53460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 54460c4903SKris Buschelman *newmat = B; 55460c4903SKris Buschelman PetscFunctionReturn(0); 56460c4903SKris Buschelman } 57460c4903SKris Buschelman EXTERN_C_END 58460c4903SKris Buschelman 59e8aa55a4SKris Buschelman #undef __FUNCT__ 60f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl" 61dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A) 62dfbe8321SBarry Smith { 63dfbe8321SBarry Smith PetscErrorCode ierr; 64f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 65e8aa55a4SKris Buschelman 66e8aa55a4SKris Buschelman PetscFunctionBegin; 672f71e704SKris Buschelman if (essl->CleanUpESSL) { 682f71e704SKris Buschelman ierr = PetscFree(essl->a);CHKERRQ(ierr); 69e8aa55a4SKris Buschelman } 70ceb03754SKris Buschelman ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A); 712f71e704SKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 72460c4903SKris Buschelman PetscFunctionReturn(0); 73460c4903SKris Buschelman } 74460c4903SKris Buschelman 75460c4903SKris Buschelman #undef __FUNCT__ 76f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl" 77dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) { 78f0c56d0fSKris Buschelman Mat_Essl *essl = (Mat_Essl*)A->spptr; 79e8aa55a4SKris Buschelman PetscScalar *xx; 80dfbe8321SBarry Smith PetscErrorCode ierr; 81dfbe8321SBarry Smith int m,zero = 0; 82e8aa55a4SKris Buschelman 83e8aa55a4SKris Buschelman PetscFunctionBegin; 84e8aa55a4SKris Buschelman ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr); 85e8aa55a4SKris Buschelman ierr = VecCopy(b,x);CHKERRQ(ierr); 86e8aa55a4SKris Buschelman ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 87e8aa55a4SKris Buschelman dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 88e8aa55a4SKris Buschelman ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 89e8aa55a4SKris Buschelman PetscFunctionReturn(0); 90e8aa55a4SKris Buschelman } 91e8aa55a4SKris Buschelman 92e8aa55a4SKris Buschelman #undef __FUNCT__ 93f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl" 94af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) { 95e8aa55a4SKris Buschelman Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data; 96f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(*F)->spptr; 976849ba73SBarry Smith PetscErrorCode ierr; 986849ba73SBarry Smith int i,one = 1; 99e8aa55a4SKris Buschelman 100e8aa55a4SKris Buschelman PetscFunctionBegin; 101e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 102e8aa55a4SKris Buschelman for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1; 103e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 104e8aa55a4SKris Buschelman 105e8aa55a4SKris Buschelman ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr); 106e8aa55a4SKris Buschelman 107e8aa55a4SKris Buschelman /* set Essl options */ 108e8aa55a4SKris Buschelman essl->iparm[0] = 1; 109e8aa55a4SKris Buschelman essl->iparm[1] = 5; 110e8aa55a4SKris Buschelman essl->iparm[2] = 1; 111e8aa55a4SKris Buschelman essl->iparm[3] = 0; 112e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 113*62331464SKris Buschelman essl->rparm[1] = 1.0; 114*62331464SKris Buschelman ierr = PetscOptionsGetReal(A->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr); 115e8aa55a4SKris Buschelman 116e8aa55a4SKris Buschelman dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 117e8aa55a4SKris Buschelman essl->rparm,essl->oparm,essl->aux,&essl->naux); 118e8aa55a4SKris Buschelman 119e8aa55a4SKris Buschelman PetscFunctionReturn(0); 120e8aa55a4SKris Buschelman } 121e8aa55a4SKris Buschelman 122e8aa55a4SKris Buschelman #undef __FUNCT__ 123f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl" 124dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 125e8aa55a4SKris Buschelman Mat B; 126eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 127dfbe8321SBarry Smith PetscErrorCode ierr; 128dfbe8321SBarry Smith int len; 129f0c56d0fSKris Buschelman Mat_Essl *essl; 130e8aa55a4SKris Buschelman PetscReal f = 1.0; 131e8aa55a4SKris Buschelman 132e8aa55a4SKris Buschelman PetscFunctionBegin; 133e8aa55a4SKris Buschelman if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 134e8aa55a4SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr); 135be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 136e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 137e8aa55a4SKris Buschelman 138f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 139f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 140e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 141e8aa55a4SKris Buschelman 142f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 143e8aa55a4SKris Buschelman 144e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 145e8aa55a4SKris Buschelman f = info->fill; 146e8aa55a4SKris Buschelman essl->nz = a->nz; 147e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 148e8aa55a4SKris Buschelman essl->naux = 100 + 10*A->m; 149e8aa55a4SKris Buschelman 150e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 151e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 152e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 153e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 154e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 155e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1562f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 157e8aa55a4SKris Buschelman 15852e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr); 159e8aa55a4SKris Buschelman *F = B; 160e8aa55a4SKris Buschelman PetscFunctionReturn(0); 161e8aa55a4SKris Buschelman } 162e8aa55a4SKris Buschelman 1632f71e704SKris Buschelman #undef __FUNCT__ 164f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 165dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) { 166dfbe8321SBarry Smith PetscErrorCode ierr; 167f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1682f71e704SKris Buschelman 1692f71e704SKris Buschelman PetscFunctionBegin; 1702f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1712f71e704SKris Buschelman 1722f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 173f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 17452e6d16bSBarry Smith PetscLogInfo(0,"MatAssemblyEnd_Essl:Using ESSL for LU factorization and solves"); 1752f71e704SKris Buschelman PetscFunctionReturn(0); 1762f71e704SKris Buschelman } 1772f71e704SKris Buschelman 178460c4903SKris Buschelman EXTERN_C_BEGIN 179e8aa55a4SKris Buschelman #undef __FUNCT__ 180460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 181ceb03754SKris Buschelman PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,MatReuse reuse,Mat *newmat) 182521d7252SBarry Smith { 183460c4903SKris Buschelman Mat B=*newmat; 184dfbe8321SBarry Smith PetscErrorCode ierr; 185f0c56d0fSKris Buschelman Mat_Essl *essl; 186460c4903SKris Buschelman 187e8aa55a4SKris Buschelman PetscFunctionBegin; 188ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 189460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 190460c4903SKris Buschelman } 191460c4903SKris Buschelman 192f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 193f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 194460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 195460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 196460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 1972f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 198460c4903SKris Buschelman 1992f71e704SKris Buschelman B->spptr = (void*)essl; 200f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 201f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 202f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 203f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 204460c4903SKris Buschelman 205460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 206460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 207460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 208460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 209460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 210*62331464SKris Buschelman 211460c4903SKris Buschelman *newmat = B; 212e8aa55a4SKris Buschelman PetscFunctionReturn(0); 213e8aa55a4SKris Buschelman } 214460c4903SKris Buschelman EXTERN_C_END 215e8aa55a4SKris Buschelman 216f0c56d0fSKris Buschelman #undef __FUNCT__ 217f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 218dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) { 219dfbe8321SBarry Smith PetscErrorCode ierr; 22013ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2218f340917SKris Buschelman 222f0c56d0fSKris Buschelman PetscFunctionBegin; 2238f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 2243f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 225f0c56d0fSKris Buschelman PetscFunctionReturn(0); 226f0c56d0fSKris Buschelman } 227f0c56d0fSKris Buschelman 2282f71e704SKris Buschelman /*MC 229fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2302f71e704SKris Buschelman via the external package ESSL. 2312f71e704SKris Buschelman 2322f71e704SKris Buschelman If ESSL is installed (see the manual for 2332f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2342f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2352f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2362f71e704SKris Buschelman This matrix type is only supported for double precision real. 2372f71e704SKris Buschelman 2382f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 23928b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 24028b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2412f71e704SKris Buschelman 2422f71e704SKris Buschelman Options Database Keys: 2430bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2442f71e704SKris Buschelman 2452f71e704SKris Buschelman Level: beginner 2462f71e704SKris Buschelman 2472f71e704SKris Buschelman .seealso: PCLU 2482f71e704SKris Buschelman M*/ 2492f71e704SKris Buschelman 250e8aa55a4SKris Buschelman EXTERN_C_BEGIN 251e8aa55a4SKris Buschelman #undef __FUNCT__ 252f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 253dfbe8321SBarry Smith PetscErrorCode MatCreate_Essl(Mat A) 254dfbe8321SBarry Smith { 255dfbe8321SBarry Smith PetscErrorCode ierr; 256e8aa55a4SKris Buschelman 257e8aa55a4SKris Buschelman PetscFunctionBegin; 2585441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2595441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 260e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 261ceb03754SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 262e8aa55a4SKris Buschelman PetscFunctionReturn(0); 263e8aa55a4SKris Buschelman } 2644eb8e494SKris Buschelman EXTERN_C_END 265