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" 33dfbe8321SBarry Smith PetscErrorCode MatConvert_Essl_SeqAIJ(Mat A,const MatType type,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; 39460c4903SKris Buschelman if (B != A) { 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); 49*901853e0SKris Buschelman 50*901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr); 51*901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 52*901853e0SKris 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 } 702f71e704SKris Buschelman ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,&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" 94dfbe8321SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat A,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; 113e8aa55a4SKris Buschelman essl->rparm[1] = A->lupivotthreshold; 114e8aa55a4SKris Buschelman 115e8aa55a4SKris Buschelman dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 116e8aa55a4SKris Buschelman essl->rparm,essl->oparm,essl->aux,&essl->naux); 117e8aa55a4SKris Buschelman 118e8aa55a4SKris Buschelman PetscFunctionReturn(0); 119e8aa55a4SKris Buschelman } 120e8aa55a4SKris Buschelman 121e8aa55a4SKris Buschelman #undef __FUNCT__ 122f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl" 123dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 124e8aa55a4SKris Buschelman Mat B; 125eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 126dfbe8321SBarry Smith PetscErrorCode ierr; 127dfbe8321SBarry Smith int len; 128f0c56d0fSKris Buschelman Mat_Essl *essl; 129e8aa55a4SKris Buschelman PetscReal f = 1.0; 130e8aa55a4SKris Buschelman 131e8aa55a4SKris Buschelman PetscFunctionBegin; 132e8aa55a4SKris Buschelman if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 133e8aa55a4SKris Buschelman ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr); 134be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 135e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 136e8aa55a4SKris Buschelman 137f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 138f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 139e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 140e8aa55a4SKris Buschelman 141f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 142e8aa55a4SKris Buschelman 143e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 144e8aa55a4SKris Buschelman f = info->fill; 145e8aa55a4SKris Buschelman essl->nz = a->nz; 146e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 147e8aa55a4SKris Buschelman essl->naux = 100 + 10*A->m; 148e8aa55a4SKris Buschelman 149e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 150e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 151e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 152e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 153e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 154e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1552f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 156e8aa55a4SKris Buschelman 157f0c56d0fSKris Buschelman PetscLogObjectMemory(B,len+sizeof(Mat_Essl)); 158e8aa55a4SKris Buschelman *F = B; 159e8aa55a4SKris Buschelman PetscFunctionReturn(0); 160e8aa55a4SKris Buschelman } 161e8aa55a4SKris Buschelman 1622f71e704SKris Buschelman #undef __FUNCT__ 163f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 164dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) { 165dfbe8321SBarry Smith PetscErrorCode ierr; 166f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1672f71e704SKris Buschelman 1682f71e704SKris Buschelman PetscFunctionBegin; 1692f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1702f71e704SKris Buschelman 1712f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 172f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 173f0c56d0fSKris Buschelman PetscLogInfo(0,"Using ESSL for LU factorization and solves"); 1742f71e704SKris Buschelman PetscFunctionReturn(0); 1752f71e704SKris Buschelman } 1762f71e704SKris Buschelman 177460c4903SKris Buschelman EXTERN_C_BEGIN 178e8aa55a4SKris Buschelman #undef __FUNCT__ 179460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 180dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,Mat *newmat) { 181460c4903SKris Buschelman Mat B=*newmat; 182dfbe8321SBarry Smith PetscErrorCode ierr; 183f0c56d0fSKris Buschelman Mat_Essl *essl; 184460c4903SKris Buschelman 185e8aa55a4SKris Buschelman PetscFunctionBegin; 186460c4903SKris Buschelman 187460c4903SKris Buschelman if (B != A) { 188460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 189460c4903SKris Buschelman } 190460c4903SKris Buschelman 191f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 192f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 193460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 194460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 195460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 1962f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 197460c4903SKris Buschelman 1982f71e704SKris Buschelman B->spptr = (void*)essl; 199f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 200f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 201f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 202f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 203460c4903SKris Buschelman 204460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 205460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 206460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 207460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 208460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 209460c4903SKris Buschelman *newmat = B; 210e8aa55a4SKris Buschelman PetscFunctionReturn(0); 211e8aa55a4SKris Buschelman } 212460c4903SKris Buschelman EXTERN_C_END 213e8aa55a4SKris Buschelman 214f0c56d0fSKris Buschelman #undef __FUNCT__ 215f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 216dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) { 217dfbe8321SBarry Smith PetscErrorCode ierr; 21813ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2198f340917SKris Buschelman 220f0c56d0fSKris Buschelman PetscFunctionBegin; 2218f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 2223f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 223f0c56d0fSKris Buschelman PetscFunctionReturn(0); 224f0c56d0fSKris Buschelman } 225f0c56d0fSKris Buschelman 2262f71e704SKris Buschelman /*MC 227fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2282f71e704SKris Buschelman via the external package ESSL. 2292f71e704SKris Buschelman 2302f71e704SKris Buschelman If ESSL is installed (see the manual for 2312f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2322f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2332f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2342f71e704SKris Buschelman This matrix type is only supported for double precision real. 2352f71e704SKris Buschelman 2362f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 23728b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 23828b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2392f71e704SKris Buschelman 2402f71e704SKris Buschelman Options Database Keys: 2410bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2422f71e704SKris Buschelman 2432f71e704SKris Buschelman Level: beginner 2442f71e704SKris Buschelman 2452f71e704SKris Buschelman .seealso: PCLU 2462f71e704SKris Buschelman M*/ 2472f71e704SKris Buschelman 248e8aa55a4SKris Buschelman EXTERN_C_BEGIN 249e8aa55a4SKris Buschelman #undef __FUNCT__ 250f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 251dfbe8321SBarry Smith PetscErrorCode MatCreate_Essl(Mat A) 252dfbe8321SBarry Smith { 253dfbe8321SBarry Smith PetscErrorCode ierr; 254e8aa55a4SKris Buschelman 255e8aa55a4SKris Buschelman PetscFunctionBegin; 2565441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2575441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 258e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 259460c4903SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,&A);CHKERRQ(ierr); 260e8aa55a4SKris Buschelman PetscFunctionReturn(0); 261e8aa55a4SKris Buschelman } 2624eb8e494SKris Buschelman EXTERN_C_END 263