1be1d678aSKris 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" 34be1d678aSKris 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"); 135f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&B);CHKERRQ(ierr); 136f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n);CHKERRQ(ierr); 137be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 138e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 139e8aa55a4SKris Buschelman 140f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 141f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 142e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 143e8aa55a4SKris Buschelman 144f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 145e8aa55a4SKris Buschelman 146e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 147e8aa55a4SKris Buschelman f = info->fill; 148e8aa55a4SKris Buschelman essl->nz = a->nz; 149e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 150e8aa55a4SKris Buschelman essl->naux = 100 + 10*A->m; 151e8aa55a4SKris Buschelman 152e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 153e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 154e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 155e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 156e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 157e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1582f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 159e8aa55a4SKris Buschelman 16052e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr); 161e8aa55a4SKris Buschelman *F = B; 162e8aa55a4SKris Buschelman PetscFunctionReturn(0); 163e8aa55a4SKris Buschelman } 164e8aa55a4SKris Buschelman 1652f71e704SKris Buschelman #undef __FUNCT__ 166f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 167*1153da11SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) 168*1153da11SBarry Smith { 169dfbe8321SBarry Smith PetscErrorCode ierr; 170f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1712f71e704SKris Buschelman 1722f71e704SKris Buschelman PetscFunctionBegin; 1732f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1742f71e704SKris Buschelman 1752f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 176f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 17763ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAssemblyEnd_Essl:Using ESSL for LU factorization and solves\n"));CHKERRQ(ierr); 1782f71e704SKris Buschelman PetscFunctionReturn(0); 1792f71e704SKris Buschelman } 1802f71e704SKris Buschelman 181460c4903SKris Buschelman EXTERN_C_BEGIN 182e8aa55a4SKris Buschelman #undef __FUNCT__ 183460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 184be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Essl(Mat A,const MatType type,MatReuse reuse,Mat *newmat) 185521d7252SBarry Smith { 186460c4903SKris Buschelman Mat B=*newmat; 187dfbe8321SBarry Smith PetscErrorCode ierr; 188f0c56d0fSKris Buschelman Mat_Essl *essl; 189460c4903SKris Buschelman 190e8aa55a4SKris Buschelman PetscFunctionBegin; 191ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 192460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 193460c4903SKris Buschelman } 194460c4903SKris Buschelman 195f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 196f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 197460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 198460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 199460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 2002f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 201460c4903SKris Buschelman 2022f71e704SKris Buschelman B->spptr = (void*)essl; 203f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 204f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 205f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 206f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 207460c4903SKris Buschelman 208460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 209460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 210460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 211460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 212460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 21362331464SKris Buschelman 214460c4903SKris Buschelman *newmat = B; 215e8aa55a4SKris Buschelman PetscFunctionReturn(0); 216e8aa55a4SKris Buschelman } 217460c4903SKris Buschelman EXTERN_C_END 218e8aa55a4SKris Buschelman 219f0c56d0fSKris Buschelman #undef __FUNCT__ 220f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 221*1153da11SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) 222*1153da11SBarry Smith { 223dfbe8321SBarry Smith PetscErrorCode ierr; 22413ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2258f340917SKris Buschelman 226f0c56d0fSKris Buschelman PetscFunctionBegin; 2278f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 2283f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 229f0c56d0fSKris Buschelman PetscFunctionReturn(0); 230f0c56d0fSKris Buschelman } 231f0c56d0fSKris Buschelman 2322f71e704SKris Buschelman /*MC 233fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2342f71e704SKris Buschelman via the external package ESSL. 2352f71e704SKris Buschelman 2362f71e704SKris Buschelman If ESSL is installed (see the manual for 2372f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2382f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2392f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2402f71e704SKris Buschelman This matrix type is only supported for double precision real. 2412f71e704SKris Buschelman 2422f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 24328b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 24428b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2452f71e704SKris Buschelman 2462f71e704SKris Buschelman Options Database Keys: 2470bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2482f71e704SKris Buschelman 2492f71e704SKris Buschelman Level: beginner 2502f71e704SKris Buschelman 2512f71e704SKris Buschelman .seealso: PCLU 2522f71e704SKris Buschelman M*/ 2532f71e704SKris Buschelman 254e8aa55a4SKris Buschelman EXTERN_C_BEGIN 255e8aa55a4SKris Buschelman #undef __FUNCT__ 256f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 257be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Essl(Mat A) 258dfbe8321SBarry Smith { 259dfbe8321SBarry Smith PetscErrorCode ierr; 260e8aa55a4SKris Buschelman 261e8aa55a4SKris Buschelman PetscFunctionBegin; 2625441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2635441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 264e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 265ceb03754SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 266e8aa55a4SKris Buschelman PetscFunctionReturn(0); 267e8aa55a4SKris Buschelman } 2684eb8e494SKris Buschelman EXTERN_C_END 269