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 10d3bad8c4SBarry Smith EXTERN_C_BEGIN 11d3bad8c4SBarry Smith void dgss(int*,int*,double*,int*,int*,int*,double*,double*,int*); 12d3bad8c4SBarry Smith void dgsf(int*,int*,int*,double*,int*,int*,int*,int*,double*,double*,double*,int*); 13d3bad8c4SBarry Smith EXTERN_C_END 14d3bad8c4SBarry Smith 15e8aa55a4SKris Buschelman typedef struct { 16e8aa55a4SKris Buschelman int n,nz; 17e8aa55a4SKris Buschelman PetscScalar *a; 18e8aa55a4SKris Buschelman int *ia; 19e8aa55a4SKris Buschelman int *ja; 20e8aa55a4SKris Buschelman int lna; 21e8aa55a4SKris Buschelman int iparm[5]; 22e8aa55a4SKris Buschelman PetscReal rparm[5]; 23e8aa55a4SKris Buschelman PetscReal oparm[5]; 24e8aa55a4SKris Buschelman PetscScalar *aux; 25e8aa55a4SKris Buschelman int naux; 26e8aa55a4SKris Buschelman 276849ba73SBarry Smith PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 286849ba73SBarry Smith PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 296849ba73SBarry Smith PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 306849ba73SBarry Smith PetscErrorCode (*MatDestroy)(Mat); 312f71e704SKris Buschelman PetscTruth CleanUpESSL; 32f0c56d0fSKris Buschelman } Mat_Essl; 33f0c56d0fSKris Buschelman 34dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*); 35e8aa55a4SKris Buschelman 36460c4903SKris Buschelman EXTERN_C_BEGIN 37460c4903SKris Buschelman #undef __FUNCT__ 38460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ" 39d3bad8c4SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Essl_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat) { 40dfbe8321SBarry Smith PetscErrorCode ierr; 41460c4903SKris Buschelman Mat B=*newmat; 42f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 43460c4903SKris Buschelman 44460c4903SKris Buschelman PetscFunctionBegin; 45ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 46460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); 47f0c56d0fSKris Buschelman } 48f0c56d0fSKris Buschelman B->ops->duplicate = essl->MatDuplicate; 49f0c56d0fSKris Buschelman B->ops->assemblyend = essl->MatAssemblyEnd; 502f71e704SKris Buschelman B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic; 512f71e704SKris Buschelman B->ops->destroy = essl->MatDestroy; 522f71e704SKris Buschelman 53460c4903SKris Buschelman /* free the Essl datastructures */ 54460c4903SKris Buschelman ierr = PetscFree(essl);CHKERRQ(ierr); 55901853e0SKris Buschelman 56901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr); 57901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 58901853e0SKris Buschelman 59460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 60460c4903SKris Buschelman *newmat = B; 61460c4903SKris Buschelman PetscFunctionReturn(0); 62460c4903SKris Buschelman } 63460c4903SKris Buschelman EXTERN_C_END 64460c4903SKris Buschelman 65e8aa55a4SKris Buschelman #undef __FUNCT__ 66f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl" 67dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A) 68dfbe8321SBarry Smith { 69dfbe8321SBarry Smith PetscErrorCode ierr; 70f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)A->spptr; 71e8aa55a4SKris Buschelman 72e8aa55a4SKris Buschelman PetscFunctionBegin; 732f71e704SKris Buschelman if (essl->CleanUpESSL) { 742f71e704SKris Buschelman ierr = PetscFree(essl->a);CHKERRQ(ierr); 75e8aa55a4SKris Buschelman } 76ceb03754SKris Buschelman ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A); 772f71e704SKris Buschelman ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 78460c4903SKris Buschelman PetscFunctionReturn(0); 79460c4903SKris Buschelman } 80460c4903SKris Buschelman 81460c4903SKris Buschelman #undef __FUNCT__ 82f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl" 83dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) { 84f0c56d0fSKris Buschelman Mat_Essl *essl = (Mat_Essl*)A->spptr; 85e8aa55a4SKris Buschelman PetscScalar *xx; 86dfbe8321SBarry Smith PetscErrorCode ierr; 87dfbe8321SBarry Smith int m,zero = 0; 88e8aa55a4SKris Buschelman 89e8aa55a4SKris Buschelman PetscFunctionBegin; 90e8aa55a4SKris Buschelman ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr); 91e8aa55a4SKris Buschelman ierr = VecCopy(b,x);CHKERRQ(ierr); 92e8aa55a4SKris Buschelman ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 93*2a4c71feSBarry Smith dgss(&zero,&A->cmap.n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 94e8aa55a4SKris Buschelman ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 95e8aa55a4SKris Buschelman PetscFunctionReturn(0); 96e8aa55a4SKris Buschelman } 97e8aa55a4SKris Buschelman 98e8aa55a4SKris Buschelman #undef __FUNCT__ 99f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl" 100af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) { 101e8aa55a4SKris Buschelman Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(A)->data; 102f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(*F)->spptr; 1036849ba73SBarry Smith PetscErrorCode ierr; 1046849ba73SBarry Smith int i,one = 1; 105e8aa55a4SKris Buschelman 106e8aa55a4SKris Buschelman PetscFunctionBegin; 107e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 108*2a4c71feSBarry Smith for (i=0; i<A->rmap.n+1; i++) essl->ia[i] = aa->i[i] + 1; 109e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 110e8aa55a4SKris Buschelman 111e8aa55a4SKris Buschelman ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr); 112e8aa55a4SKris Buschelman 113e8aa55a4SKris Buschelman /* set Essl options */ 114e8aa55a4SKris Buschelman essl->iparm[0] = 1; 115e8aa55a4SKris Buschelman essl->iparm[1] = 5; 116e8aa55a4SKris Buschelman essl->iparm[2] = 1; 117e8aa55a4SKris Buschelman essl->iparm[3] = 0; 118e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 11962331464SKris Buschelman essl->rparm[1] = 1.0; 12062331464SKris Buschelman ierr = PetscOptionsGetReal(A->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr); 121e8aa55a4SKris Buschelman 122*2a4c71feSBarry Smith dgsf(&one,&A->rmap.n,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm, 123e8aa55a4SKris Buschelman essl->rparm,essl->oparm,essl->aux,&essl->naux); 124e8aa55a4SKris Buschelman 125d3bad8c4SBarry Smith (*F)->assembled = PETSC_TRUE; 126e8aa55a4SKris Buschelman PetscFunctionReturn(0); 127e8aa55a4SKris Buschelman } 128e8aa55a4SKris Buschelman 129e8aa55a4SKris Buschelman #undef __FUNCT__ 130f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl" 131dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) { 132e8aa55a4SKris Buschelman Mat B; 133eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 134dfbe8321SBarry Smith PetscErrorCode ierr; 135dfbe8321SBarry Smith int len; 136f0c56d0fSKris Buschelman Mat_Essl *essl; 137e8aa55a4SKris Buschelman PetscReal f = 1.0; 138e8aa55a4SKris Buschelman 139e8aa55a4SKris Buschelman PetscFunctionBegin; 140*2a4c71feSBarry Smith if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 141f69a0ea3SMatthew Knepley ierr = MatCreate(A->comm,&B);CHKERRQ(ierr); 142*2a4c71feSBarry Smith ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap.n,A->cmap.n);CHKERRQ(ierr); 143be5d1d56SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 144e8aa55a4SKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 145e8aa55a4SKris Buschelman 146f0c56d0fSKris Buschelman B->ops->solve = MatSolve_Essl; 147f0c56d0fSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 148e8aa55a4SKris Buschelman B->factor = FACTOR_LU; 149e8aa55a4SKris Buschelman 150f0c56d0fSKris Buschelman essl = (Mat_Essl *)(B->spptr); 151e8aa55a4SKris Buschelman 152e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 153e8aa55a4SKris Buschelman f = info->fill; 154e8aa55a4SKris Buschelman essl->nz = a->nz; 155e8aa55a4SKris Buschelman essl->lna = (int)a->nz*f; 156*2a4c71feSBarry Smith essl->naux = 100 + 10*A->rmap.n; 157e8aa55a4SKris Buschelman 158e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 159e8aa55a4SKris Buschelman len = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar); 160e8aa55a4SKris Buschelman ierr = PetscMalloc(len,&essl->a);CHKERRQ(ierr); 161e8aa55a4SKris Buschelman essl->aux = essl->a + essl->lna; 162e8aa55a4SKris Buschelman essl->ia = (int*)(essl->aux + essl->naux); 163e8aa55a4SKris Buschelman essl->ja = essl->ia + essl->lna; 1642f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 165e8aa55a4SKris Buschelman 16652e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr); 167e8aa55a4SKris Buschelman *F = B; 168e8aa55a4SKris Buschelman PetscFunctionReturn(0); 169e8aa55a4SKris Buschelman } 170e8aa55a4SKris Buschelman 1712f71e704SKris Buschelman #undef __FUNCT__ 172f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl" 1731153da11SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) 1741153da11SBarry Smith { 175dfbe8321SBarry Smith PetscErrorCode ierr; 176f0c56d0fSKris Buschelman Mat_Essl *essl=(Mat_Essl*)(A->spptr); 1772f71e704SKris Buschelman 1782f71e704SKris Buschelman PetscFunctionBegin; 1792f71e704SKris Buschelman ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 1802f71e704SKris Buschelman 1812f71e704SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 182f0c56d0fSKris Buschelman A->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 183ae15b995SBarry Smith ierr = PetscInfo(0,"Using ESSL for LU factorization and solves\n");CHKERRQ(ierr); 1842f71e704SKris Buschelman PetscFunctionReturn(0); 1852f71e704SKris Buschelman } 1862f71e704SKris Buschelman 187460c4903SKris Buschelman EXTERN_C_BEGIN 188e8aa55a4SKris Buschelman #undef __FUNCT__ 189460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl" 190d3bad8c4SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Essl(Mat A,MatType type,MatReuse reuse,Mat *newmat) 191521d7252SBarry Smith { 192460c4903SKris Buschelman Mat B=*newmat; 193dfbe8321SBarry Smith PetscErrorCode ierr; 194f0c56d0fSKris Buschelman Mat_Essl *essl; 195460c4903SKris Buschelman 196e8aa55a4SKris Buschelman PetscFunctionBegin; 197ceb03754SKris Buschelman if (reuse == MAT_INITIAL_MATRIX) { 198460c4903SKris Buschelman ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 199460c4903SKris Buschelman } 200460c4903SKris Buschelman 201f0c56d0fSKris Buschelman ierr = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr); 202f0c56d0fSKris Buschelman essl->MatDuplicate = A->ops->duplicate; 203460c4903SKris Buschelman essl->MatAssemblyEnd = A->ops->assemblyend; 204460c4903SKris Buschelman essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 205460c4903SKris Buschelman essl->MatDestroy = A->ops->destroy; 2062f71e704SKris Buschelman essl->CleanUpESSL = PETSC_FALSE; 207460c4903SKris Buschelman 2082f71e704SKris Buschelman B->spptr = (void*)essl; 209f0c56d0fSKris Buschelman B->ops->duplicate = MatDuplicate_Essl; 210f0c56d0fSKris Buschelman B->ops->assemblyend = MatAssemblyEnd_Essl; 211f0c56d0fSKris Buschelman B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 212f0c56d0fSKris Buschelman B->ops->destroy = MatDestroy_Essl; 213460c4903SKris Buschelman 214460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C", 215460c4903SKris Buschelman "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr); 216460c4903SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C", 217460c4903SKris Buschelman "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr); 218460c4903SKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr); 21962331464SKris Buschelman 220460c4903SKris Buschelman *newmat = B; 221e8aa55a4SKris Buschelman PetscFunctionReturn(0); 222e8aa55a4SKris Buschelman } 223460c4903SKris Buschelman EXTERN_C_END 224e8aa55a4SKris Buschelman 225f0c56d0fSKris Buschelman #undef __FUNCT__ 226f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl" 2271153da11SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) 2281153da11SBarry Smith { 229dfbe8321SBarry Smith PetscErrorCode ierr; 23013ee22deSSatish Balay Mat_Essl *lu = (Mat_Essl *)A->spptr; 2318f340917SKris Buschelman 232f0c56d0fSKris Buschelman PetscFunctionBegin; 2338f340917SKris Buschelman ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 2343f953163SKris Buschelman ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr); 235f0c56d0fSKris Buschelman PetscFunctionReturn(0); 236f0c56d0fSKris Buschelman } 237f0c56d0fSKris Buschelman 2382f71e704SKris Buschelman /*MC 239fafad747SKris Buschelman MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices 2402f71e704SKris Buschelman via the external package ESSL. 2412f71e704SKris Buschelman 2422f71e704SKris Buschelman If ESSL is installed (see the manual for 2432f71e704SKris Buschelman instructions on how to declare the existence of external packages), 2442f71e704SKris Buschelman a matrix type can be constructed which invokes ESSL solvers. 2452f71e704SKris Buschelman After calling MatCreate(...,A), simply call MatSetType(A,MATESSL). 2462f71e704SKris Buschelman This matrix type is only supported for double precision real. 2472f71e704SKris Buschelman 2482f71e704SKris Buschelman This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 24928b08bd3SKris Buschelman supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 25028b08bd3SKris Buschelman the MATSEQAIJ type without data copy. 2512f71e704SKris Buschelman 2522f71e704SKris Buschelman Options Database Keys: 2530bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions() 2542f71e704SKris Buschelman 2552f71e704SKris Buschelman Level: beginner 2562f71e704SKris Buschelman 2572f71e704SKris Buschelman .seealso: PCLU 2582f71e704SKris Buschelman M*/ 2592f71e704SKris Buschelman 260e8aa55a4SKris Buschelman EXTERN_C_BEGIN 261e8aa55a4SKris Buschelman #undef __FUNCT__ 262f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl" 263be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Essl(Mat A) 264dfbe8321SBarry Smith { 265dfbe8321SBarry Smith PetscErrorCode ierr; 266e8aa55a4SKris Buschelman 267e8aa55a4SKris Buschelman PetscFunctionBegin; 2685441df8eSKris Buschelman /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */ 2695441df8eSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr); 270e8aa55a4SKris Buschelman ierr = MatSetType(A,MATSEQAIJ); 271ceb03754SKris Buschelman ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 272e8aa55a4SKris Buschelman PetscFunctionReturn(0); 273e8aa55a4SKris Buschelman } 2744eb8e494SKris Buschelman EXTERN_C_END 275