1*be1d678aSKris Buschelman #define PETSCMAT_DLL 2e8aa55a4SKris Buschelman 3e8aa55a4SKris Buschelman /* 4e8aa55a4SKris Buschelman Provides an interface to the IBM RS6000 Essl sparse solver 5e8aa55a4SKris Buschelman 6e8aa55a4SKris Buschelman */ 7e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h" 8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work! */ 9e8aa55a4SKris Buschelman 10e8aa55a4SKris Buschelman typedef struct { 11e8aa55a4SKris Buschelman int n,nz; 12e8aa55a4SKris Buschelman PetscScalar *a; 13e8aa55a4SKris Buschelman int *ia; 14e8aa55a4SKris Buschelman int *ja; 15e8aa55a4SKris Buschelman int lna; 16e8aa55a4SKris Buschelman int iparm[5]; 17e8aa55a4SKris Buschelman PetscReal rparm[5]; 18e8aa55a4SKris Buschelman PetscReal oparm[5]; 19e8aa55a4SKris Buschelman PetscScalar *aux; 20e8aa55a4SKris Buschelman int naux; 21e8aa55a4SKris Buschelman 226849ba73SBarry Smith PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 236849ba73SBarry Smith PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 246849ba73SBarry Smith PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 256849ba73SBarry Smith PetscErrorCode (*MatDestroy)(Mat); 262f71e704SKris Buschelman PetscTruth CleanUpESSL; 27f0c56d0fSKris Buschelman } Mat_Essl; 28f0c56d0fSKris Buschelman 29dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*); 30e8aa55a4SKris Buschelman 31460c4903SKris Buschelman EXTERN_C_BEGIN 32460c4903SKris Buschelman #undef __FUNCT__ 33460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ" 34*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Essl_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat) { 35dfbe8321SBarry Smith PetscErrorCode ierr; 36460c4903SKris Buschelman Mat B=*newmat; 37f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 38460c4903SKris Buschelman 39460c4903SKris Buschelman PetscFunctionBegin; 40ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 41460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); 42f0c56d0fSKris Buschelman } 43f0c56d0fSKris Buschelman B->ops->duplicate = essl->MatDuplicate; 44f0c56d0fSKris Buschelman B->ops->assemblyend = essl->MatAssemblyEnd; 452f71e704SKris Buschelman B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic; 462f71e704SKris Buschelman B->ops->destroy = essl->MatDestroy; 472f71e704SKris Buschelman 48460c4903SKris Buschelman /* free the Essl datastructures */ 49460c4903SKris Buschelman ierr = PetscFree(essl);CHKERRQ(ierr); 50901853e0SKris Buschelman 51901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr); 52901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 53901853e0SKris Buschelman 54460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 55460c4903SKris Buschelman *newmat = B; 56460c4903SKris Buschelman PetscFunctionReturn(0); 57460c4903SKris Buschelman } 58460c4903SKris Buschelman EXTERN_C_END 59460c4903SKris Buschelman 60e8aa55a4SKris Buschelman #undef __FUNCT__ 61f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl" 62dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A) 63dfbe8321SBarry Smith { 64dfbe8321SBarry Smith PetscErrorCode ierr; 65f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 66e8aa55a4SKris Buschelman 67e8aa55a4SKris Buschelman PetscFunctionBegin; 682f71e704SKris Buschelman if (essl->CleanUpESSL) { 692f71e704SKris Buschelman ierr = PetscFree(essl->a);CHKERRQ(ierr); 70e8aa55a4SKris Buschelman } 71ceb03754SKris Buschelman ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A); 722f71e704SKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 73460c4903SKris Buschelman PetscFunctionReturn(0); 74460c4903SKris Buschelman } 75460c4903SKris Buschelman 76460c4903SKris Buschelman #undef __FUNCT__ 77f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl" 78dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) { 79f0c56d0fSKris Buschelman Mat_Essl *essl = (Mat_Essl*)A->spptr; 80e8aa55a4SKris Buschelman PetscScalar *xx; 81dfbe8321SBarry Smith PetscErrorCode ierr; 82dfbe8321SBarry Smith int m,zero = 0; 83e8aa55a4SKris Buschelman 84e8aa55a4SKris Buschelman PetscFunctionBegin; 85e8aa55a4SKris Buschelman ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr); 86e8aa55a4SKris Buschelman ierr = VecCopy(b,x);CHKERRQ(ierr); 87e8aa55a4SKris Buschelman ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 88e8aa55a4SKris Buschelman dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 89e8aa55a4SKris Buschelman ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 90e8aa55a4SKris Buschelman PetscFunctionReturn(0); 91e8aa55a4SKris Buschelman } 92e8aa55a4SKris Buschelman 93e8aa55a4SKris Buschelman #undef __FUNCT__ 94f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl" 95af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) { 96e8aa55a4SKris Buschelman Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data; 97f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(*F)->spptr; 986849ba73SBarry Smith PetscErrorCode ierr; 996849ba73SBarry Smith int i,one = 1; 100e8aa55a4SKris Buschelman 101e8aa55a4SKris Buschelman PetscFunctionBegin; 102e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 103e8aa55a4SKris Buschelman for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1; 104e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 105e8aa55a4SKris Buschelman 106e8aa55a4SKris Buschelman ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr); 107e8aa55a4SKris Buschelman 108e8aa55a4SKris Buschelman /* set Essl options */ 109e8aa55a4SKris Buschelman essl->iparm[0] = 1; 110e8aa55a4SKris Buschelman essl->iparm[1] = 5; 111e8aa55a4SKris Buschelman essl->iparm[2] = 1; 112e8aa55a4SKris Buschelman essl->iparm[3] = 0; 113e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 11462331464SKris Buschelman essl->rparm[1] = 1.0; 11562331464SKris Buschelman ierr = PetscOptionsGetReal(A->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr); 116e8aa55a4SKris Buschelman 117e8aa55a4SKris Buschelman dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 118e8aa55a4SKris Buschelman essl->rparm,essl->oparm,essl->aux,&essl->naux); 119e8aa55a4SKris Buschelman 120e8aa55a4SKris Buschelman PetscFunctionReturn(0); 121e8aa55a4SKris Buschelman } 122e8aa55a4SKris Buschelman 123e8aa55a4SKris Buschelman #undef __FUNCT__ 124f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl" 125dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 126e8aa55a4SKris Buschelman Mat B; 127eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 128dfbe8321SBarry Smith PetscErrorCode ierr; 129dfbe8321SBarry Smith int len; 130f0c56d0fSKris Buschelman Mat_Essl *essl; 131e8aa55a4SKris Buschelman PetscReal f = 1.0; 132e8aa55a4SKris Buschelman 133e8aa55a4SKris Buschelman PetscFunctionBegin; 134e8aa55a4SKris Buschelman if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 135e8aa55a4SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr); 136be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 137e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 138e8aa55a4SKris Buschelman 139f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 140f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 141e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 142e8aa55a4SKris Buschelman 143f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 144e8aa55a4SKris Buschelman 145e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 146e8aa55a4SKris Buschelman f = info->fill; 147e8aa55a4SKris Buschelman essl->nz = a->nz; 148e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 149e8aa55a4SKris Buschelman essl->naux = 100 + 10*A->m; 150e8aa55a4SKris Buschelman 151e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 152e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 153e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 154e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 155e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 156e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1572f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 158e8aa55a4SKris Buschelman 15952e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr); 160e8aa55a4SKris Buschelman *F = B; 161e8aa55a4SKris Buschelman PetscFunctionReturn(0); 162e8aa55a4SKris Buschelman } 163e8aa55a4SKris Buschelman 1642f71e704SKris Buschelman #undef __FUNCT__ 165f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 166dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) { 167dfbe8321SBarry Smith PetscErrorCode ierr; 168f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1692f71e704SKris Buschelman 1702f71e704SKris Buschelman PetscFunctionBegin; 1712f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1722f71e704SKris Buschelman 1732f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 174f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 17563ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAssemblyEnd_Essl:Using ESSL for LU factorization and solves\n"));CHKERRQ(ierr); 1762f71e704SKris Buschelman PetscFunctionReturn(0); 1772f71e704SKris Buschelman } 1782f71e704SKris Buschelman 179460c4903SKris Buschelman EXTERN_C_BEGIN 180e8aa55a4SKris Buschelman #undef __FUNCT__ 181460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 182*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Essl(Mat A,const MatType type,MatReuse reuse,Mat *newmat) 183521d7252SBarry Smith { 184460c4903SKris Buschelman Mat B=*newmat; 185dfbe8321SBarry Smith PetscErrorCode ierr; 186f0c56d0fSKris Buschelman Mat_Essl *essl; 187460c4903SKris Buschelman 188e8aa55a4SKris Buschelman PetscFunctionBegin; 189ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 190460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 191460c4903SKris Buschelman } 192460c4903SKris Buschelman 193f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 194f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 195460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 196460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 197460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 1982f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 199460c4903SKris Buschelman 2002f71e704SKris Buschelman B->spptr = (void*)essl; 201f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 202f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 203f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 204f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 205460c4903SKris Buschelman 206460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 207460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 208460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 209460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 210460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 21162331464SKris Buschelman 212460c4903SKris Buschelman *newmat = B; 213e8aa55a4SKris Buschelman PetscFunctionReturn(0); 214e8aa55a4SKris Buschelman } 215460c4903SKris Buschelman EXTERN_C_END 216e8aa55a4SKris Buschelman 217f0c56d0fSKris Buschelman #undef __FUNCT__ 218f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 219dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) { 220dfbe8321SBarry Smith PetscErrorCode ierr; 22113ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2228f340917SKris Buschelman 223f0c56d0fSKris Buschelman PetscFunctionBegin; 2248f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 2253f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 226f0c56d0fSKris Buschelman PetscFunctionReturn(0); 227f0c56d0fSKris Buschelman } 228f0c56d0fSKris Buschelman 2292f71e704SKris Buschelman /*MC 230fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2312f71e704SKris Buschelman via the external package ESSL. 2322f71e704SKris Buschelman 2332f71e704SKris Buschelman If ESSL is installed (see the manual for 2342f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2352f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2362f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2372f71e704SKris Buschelman This matrix type is only supported for double precision real. 2382f71e704SKris Buschelman 2392f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 24028b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 24128b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2422f71e704SKris Buschelman 2432f71e704SKris Buschelman Options Database Keys: 2440bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2452f71e704SKris Buschelman 2462f71e704SKris Buschelman Level: beginner 2472f71e704SKris Buschelman 2482f71e704SKris Buschelman .seealso: PCLU 2492f71e704SKris Buschelman M*/ 2502f71e704SKris Buschelman 251e8aa55a4SKris Buschelman EXTERN_C_BEGIN 252e8aa55a4SKris Buschelman #undef __FUNCT__ 253f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 254*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Essl(Mat A) 255dfbe8321SBarry Smith { 256dfbe8321SBarry Smith PetscErrorCode ierr; 257e8aa55a4SKris Buschelman 258e8aa55a4SKris Buschelman PetscFunctionBegin; 2595441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2605441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 261e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 262ceb03754SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 263e8aa55a4SKris Buschelman PetscFunctionReturn(0); 264e8aa55a4SKris Buschelman } 2654eb8e494SKris Buschelman EXTERN_C_END 266