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 { 30ac913495SBarry Smith Mat_Essl *essl=(Mat_Essl*)A->data; 31e8aa55a4SKris Buschelman 32e8aa55a4SKris Buschelman PetscFunctionBegin; 33*1baa6e33SBarry Smith if (essl->CleanUpESSL) PetscCall(PetscFree4(essl->a,essl->aux,essl->ia,essl->ja)); 349566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 35460c4903SKris Buschelman PetscFunctionReturn(0); 36460c4903SKris Buschelman } 37460c4903SKris Buschelman 38b24902e0SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) 39b24902e0SBarry Smith { 40ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl*)A->data; 41e8aa55a4SKris Buschelman PetscScalar *xx; 42c5c20521SJed Brown int nessl,zero = 0; 43e8aa55a4SKris Buschelman 44e8aa55a4SKris Buschelman PetscFunctionBegin; 459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&nessl)); 469566063dSJacob Faibussowitsch PetscCall(VecCopy(b,x)); 479566063dSJacob Faibussowitsch PetscCall(VecGetArray(x,&xx)); 48c5c20521SJed Brown dgss(&zero,&nessl,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux); 499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x,&xx)); 50e8aa55a4SKris Buschelman PetscFunctionReturn(0); 51e8aa55a4SKris Buschelman } 52e8aa55a4SKris Buschelman 530481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat F,Mat A,const MatFactorInfo *info) 54b24902e0SBarry Smith { 55e8aa55a4SKris Buschelman Mat_SeqAIJ *aa =(Mat_SeqAIJ*)(A)->data; 56ac913495SBarry Smith Mat_Essl *essl=(Mat_Essl*)(F)->data; 57c5c20521SJed Brown int nessl,i,one = 1; 58e8aa55a4SKris Buschelman 59e8aa55a4SKris Buschelman PetscFunctionBegin; 609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&nessl)); 61e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 62d0f46423SBarry Smith for (i=0; i<A->rmap->n+1; i++) essl->ia[i] = aa->i[i] + 1; 63e8aa55a4SKris Buschelman for (i=0; i<aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 64e8aa55a4SKris Buschelman 659566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(essl->a,aa->a,aa->nz)); 66e8aa55a4SKris Buschelman 67e8aa55a4SKris Buschelman /* set Essl options */ 68e8aa55a4SKris Buschelman essl->iparm[0] = 1; 69e8aa55a4SKris Buschelman essl->iparm[1] = 5; 70e8aa55a4SKris Buschelman essl->iparm[2] = 1; 71e8aa55a4SKris Buschelman essl->iparm[3] = 0; 72e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 7362331464SKris Buschelman essl->rparm[1] = 1.0; 742205254eSKarl Rupp 759566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL,((PetscObject)A)->prefix,"-matessl_lu_threshold",&essl->rparm[1],NULL)); 76e8aa55a4SKris Buschelman 77c5c20521SJed Brown dgsf(&one,&nessl,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,essl->rparm,essl->oparm,essl->aux,&essl->naux); 78e8aa55a4SKris Buschelman 7935bd34faSBarry Smith F->ops->solve = MatSolve_Essl; 80719d5645SBarry Smith (F)->assembled = PETSC_TRUE; 81719d5645SBarry Smith (F)->preallocated = PETSC_TRUE; 82e8aa55a4SKris Buschelman PetscFunctionReturn(0); 83e8aa55a4SKris Buschelman } 84e8aa55a4SKris Buschelman 850481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat B,Mat A,IS r,IS c,const MatFactorInfo *info) 86b24902e0SBarry Smith { 87eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 88f0c56d0fSKris Buschelman Mat_Essl *essl; 89e8aa55a4SKris Buschelman PetscReal f = 1.0; 90e8aa55a4SKris Buschelman 91e8aa55a4SKris Buschelman PetscFunctionBegin; 92ac913495SBarry Smith essl = (Mat_Essl*)(B->data); 93e8aa55a4SKris Buschelman 94e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 95e8aa55a4SKris Buschelman f = info->fill; 969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->nz,&essl->nz)); 979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast((PetscInt)(a->nz*f),&essl->lna)); 989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(100 + 10*A->rmap->n,&essl->naux)); 99e8aa55a4SKris Buschelman 100e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 1019566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(essl->lna,&essl->a,essl->naux,&essl->aux,essl->lna,&essl->ia,essl->lna,&essl->ja)); 1022205254eSKarl Rupp 1032f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 104e8aa55a4SKris Buschelman 1059566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)B,essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar))); 1062205254eSKarl Rupp 107db4efbfdSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 108e8aa55a4SKris Buschelman PetscFunctionReturn(0); 109e8aa55a4SKris Buschelman } 110e8aa55a4SKris Buschelman 111ea799195SBarry Smith PetscErrorCode MatFactorGetSolverType_essl(Mat A,MatSolverType *type) 11235bd34faSBarry Smith { 11335bd34faSBarry Smith PetscFunctionBegin; 1142692d6eeSBarry Smith *type = MATSOLVERESSL; 11535bd34faSBarry Smith PetscFunctionReturn(0); 11635bd34faSBarry Smith } 117719d5645SBarry Smith 1182f71e704SKris Buschelman /*MC 1192692d6eeSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers (LU) for sequential matrices 1202f71e704SKris Buschelman via the external package ESSL. 1212f71e704SKris Buschelman 1222f71e704SKris Buschelman If ESSL is installed (see the manual for 1232f71e704SKris Buschelman instructions on how to declare the existence of external packages), 1242f71e704SKris Buschelman 12541c8de11SBarry Smith Works with MATSEQAIJ matrices 1262f71e704SKris Buschelman 1272f71e704SKris Buschelman Level: beginner 1282f71e704SKris Buschelman 129db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 1302f71e704SKris Buschelman M*/ 1312f71e704SKris Buschelman 1328cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A,MatFactorType ftype,Mat *F) 133dfbe8321SBarry Smith { 134b24902e0SBarry Smith Mat B; 135b24902e0SBarry Smith Mat_Essl *essl; 136e8aa55a4SKris Buschelman 137e8aa55a4SKris Buschelman PetscFunctionBegin; 13808401ef6SPierre Jolivet PetscCheck(A->cmap->N == A->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square"); 1399566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 1409566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap->n,A->cmap->n)); 1419566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl",&((PetscObject)B)->type_name)); 1429566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 143b24902e0SBarry Smith 1449566063dSJacob Faibussowitsch PetscCall(PetscNewLog(B,&essl)); 1452205254eSKarl Rupp 146ac913495SBarry Smith B->data = essl; 147b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 148ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 149ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1502205254eSKarl Rupp 1519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_essl)); 1522205254eSKarl Rupp 153d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 1549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&B->preferredordering[MAT_FACTOR_LU])); 1559566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 1569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL,&B->solvertype)); 15700c67f3bSHong Zhang 158b24902e0SBarry Smith *F = B; 159e8aa55a4SKris Buschelman PetscFunctionReturn(0); 160e8aa55a4SKris Buschelman } 16142c9c57cSBarry Smith 1623ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) 16342c9c57cSBarry Smith { 16442c9c57cSBarry Smith PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL,MATSEQAIJ, MAT_FACTOR_LU,MatGetFactor_seqaij_essl)); 16642c9c57cSBarry Smith PetscFunctionReturn(0); 16742c9c57cSBarry Smith } 168