1e8aa55a4SKris Buschelman 2e8aa55a4SKris Buschelman /* 3e8aa55a4SKris Buschelman Provides an interface to the IBM RS6000 Essl sparse solver 4e8aa55a4SKris Buschelman 5e8aa55a4SKris Buschelman */ 6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 7b24902e0SBarry Smith 8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work! */ 9e8aa55a4SKris Buschelman 108cc058d9SJed Brown PETSC_EXTERN void dgss(int*,int*,double*,int*,int*,int*,double*,double*,int*); 118cc058d9SJed Brown PETSC_EXTERN void dgsf(int*,int*,int*,double*,int*,int*,int*,int*,double*,double*,double*,int*); 12d3bad8c4SBarry Smith 13e8aa55a4SKris Buschelman typedef struct { 14e8aa55a4SKris Buschelman int n,nz; 15e8aa55a4SKris Buschelman PetscScalar *a; 16e8aa55a4SKris Buschelman int *ia; 17e8aa55a4SKris Buschelman int *ja; 18e8aa55a4SKris Buschelman int lna; 19e8aa55a4SKris Buschelman int iparm[5]; 20e8aa55a4SKris Buschelman PetscReal rparm[5]; 21e8aa55a4SKris Buschelman PetscReal oparm[5]; 22e8aa55a4SKris Buschelman PetscScalar *aux; 23e8aa55a4SKris Buschelman int naux; 24e8aa55a4SKris Buschelman 25ace3abfcSBarry Smith PetscBool CleanUpESSL; 26f0c56d0fSKris Buschelman } Mat_Essl; 27f0c56d0fSKris Buschelman 28dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A) 29dfbe8321SBarry Smith { 30dfbe8321SBarry Smith PetscErrorCode ierr; 31ac913495SBarry Smith Mat_Essl *essl=(Mat_Essl*)A->data; 32e8aa55a4SKris Buschelman 33e8aa55a4SKris Buschelman PetscFunctionBegin; 34ac913495SBarry Smith if (essl->CleanUpESSL) { 35*9566063dSJacob Faibussowitsch PetscCall(PetscFree4(essl->a,essl->aux,essl->ia,essl->ja)); 36e8aa55a4SKris Buschelman } 37*9566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 38460c4903SKris Buschelman PetscFunctionReturn(0); 39460c4903SKris Buschelman } 40460c4903SKris Buschelman 41b24902e0SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) 42b24902e0SBarry Smith { 43ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl*)A->data; 44e8aa55a4SKris Buschelman PetscScalar *xx; 45dfbe8321SBarry Smith PetscErrorCode ierr; 46c5c20521SJed Brown int nessl,zero = 0; 47e8aa55a4SKris Buschelman 48e8aa55a4SKris Buschelman PetscFunctionBegin; 49*9566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&nessl)); 50*9566063dSJacob Faibussowitsch PetscCall(VecCopy(b,x)); 51*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(x,&xx)); 52c5c20521SJed Brown dgss(&zero,&nessl,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 53*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x,&xx)); 54e8aa55a4SKris Buschelman PetscFunctionReturn(0); 55e8aa55a4SKris Buschelman } 56e8aa55a4SKris Buschelman 570481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat F,Mat A,const MatFactorInfo *info) 58b24902e0SBarry Smith { 59e8aa55a4SKris Buschelman Mat_SeqAIJ *aa =(Mat_SeqAIJ*)(A)->data; 60ac913495SBarry Smith Mat_Essl *essl=(Mat_Essl*)(F)->data; 616849ba73SBarry Smith PetscErrorCode ierr; 62c5c20521SJed Brown int nessl,i,one = 1; 63e8aa55a4SKris Buschelman 64e8aa55a4SKris Buschelman PetscFunctionBegin; 65*9566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&nessl)); 66e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 67d0f46423SBarry Smith for (i=0; i<A->rmap->n+1; i++) essl->ia[i] = aa->i[i] + 1; 68e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 69e8aa55a4SKris Buschelman 70*9566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(essl->a,aa->a,aa->nz)); 71e8aa55a4SKris Buschelman 72e8aa55a4SKris Buschelman /* set Essl options */ 73e8aa55a4SKris Buschelman essl->iparm[0] = 1; 74e8aa55a4SKris Buschelman essl->iparm[1] = 5; 75e8aa55a4SKris Buschelman essl->iparm[2] = 1; 76e8aa55a4SKris Buschelman essl->iparm[3] = 0; 77e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 7862331464SKris Buschelman essl->rparm[1] = 1.0; 792205254eSKarl Rupp 80*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL,((PetscObject)A)->prefix,"-matessl_lu_threshold",&essl->rparm[1],NULL)); 81e8aa55a4SKris Buschelman 82c5c20521SJed Brown dgsf(&one,&nessl,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,essl->rparm,essl->oparm,essl->aux,&essl->naux); 83e8aa55a4SKris Buschelman 8435bd34faSBarry Smith F->ops->solve = MatSolve_Essl; 85719d5645SBarry Smith (F)->assembled = PETSC_TRUE; 86719d5645SBarry Smith (F)->preallocated = PETSC_TRUE; 87e8aa55a4SKris Buschelman PetscFunctionReturn(0); 88e8aa55a4SKris Buschelman } 89e8aa55a4SKris Buschelman 900481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat B,Mat A,IS r,IS c,const MatFactorInfo *info) 91b24902e0SBarry Smith { 92eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 93dfbe8321SBarry Smith PetscErrorCode ierr; 94f0c56d0fSKris Buschelman Mat_Essl *essl; 95e8aa55a4SKris Buschelman PetscReal f = 1.0; 96e8aa55a4SKris Buschelman 97e8aa55a4SKris Buschelman PetscFunctionBegin; 98ac913495SBarry Smith essl = (Mat_Essl*)(B->data); 99e8aa55a4SKris Buschelman 100e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 101e8aa55a4SKris Buschelman f = info->fill; 102*9566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->nz,&essl->nz)); 103*9566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast((PetscInt)(a->nz*f),&essl->lna)); 104*9566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(100 + 10*A->rmap->n,&essl->naux)); 105e8aa55a4SKris Buschelman 106e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 107*9566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(essl->lna,&essl->a,essl->naux,&essl->aux,essl->lna,&essl->ia,essl->lna,&essl->ja)); 1082205254eSKarl Rupp 1092f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 110e8aa55a4SKris Buschelman 111*9566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)B,essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar))); 1122205254eSKarl Rupp 113db4efbfdSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 114e8aa55a4SKris Buschelman PetscFunctionReturn(0); 115e8aa55a4SKris Buschelman } 116e8aa55a4SKris Buschelman 117ea799195SBarry Smith PetscErrorCode MatFactorGetSolverType_essl(Mat A,MatSolverType *type) 11835bd34faSBarry Smith { 11935bd34faSBarry Smith PetscFunctionBegin; 1202692d6eeSBarry Smith *type = MATSOLVERESSL; 12135bd34faSBarry Smith PetscFunctionReturn(0); 12235bd34faSBarry Smith } 123719d5645SBarry Smith 1242f71e704SKris Buschelman /*MC 1252692d6eeSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers (LU) for sequential matrices 1262f71e704SKris Buschelman via the external package ESSL. 1272f71e704SKris Buschelman 1282f71e704SKris Buschelman If ESSL is installed (see the manual for 1292f71e704SKris Buschelman instructions on how to declare the existence of external packages), 1302f71e704SKris Buschelman 13141c8de11SBarry Smith Works with MATSEQAIJ matrices 1322f71e704SKris Buschelman 1332f71e704SKris Buschelman Level: beginner 1342f71e704SKris Buschelman 1353ca39a21SBarry Smith .seealso: PCLU, PCFactorSetMatSolverType(), MatSolverType 1362f71e704SKris Buschelman M*/ 1372f71e704SKris Buschelman 1388cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A,MatFactorType ftype,Mat *F) 139dfbe8321SBarry Smith { 140b24902e0SBarry Smith Mat B; 141dfbe8321SBarry Smith PetscErrorCode ierr; 142b24902e0SBarry Smith Mat_Essl *essl; 143e8aa55a4SKris Buschelman 144e8aa55a4SKris Buschelman PetscFunctionBegin; 1452c71b3e2SJacob Faibussowitsch PetscCheckFalse(A->cmap->N != A->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 146*9566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 147*9566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap->n,A->cmap->n)); 148*9566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl",&((PetscObject)B)->type_name)); 149*9566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 150b24902e0SBarry Smith 151*9566063dSJacob Faibussowitsch PetscCall(PetscNewLog(B,&essl)); 1522205254eSKarl Rupp 153ac913495SBarry Smith B->data = essl; 154b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 155ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 156ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1572205254eSKarl Rupp 158*9566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_essl)); 1592205254eSKarl Rupp 160d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 161*9566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&B->preferredordering[MAT_FACTOR_LU])); 162*9566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 163*9566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL,&B->solvertype)); 16400c67f3bSHong Zhang 165b24902e0SBarry Smith *F = B; 166e8aa55a4SKris Buschelman PetscFunctionReturn(0); 167e8aa55a4SKris Buschelman } 16842c9c57cSBarry Smith 1693ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) 17042c9c57cSBarry Smith { 17142c9c57cSBarry Smith PetscErrorCode ierr; 17242c9c57cSBarry Smith PetscFunctionBegin; 173*9566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL,MATSEQAIJ, MAT_FACTOR_LU,MatGetFactor_seqaij_essl)); 17442c9c57cSBarry Smith PetscFunctionReturn(0); 17542c9c57cSBarry Smith } 176