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 28*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_Essl(Mat A) 29*d71ae5a4SJacob Faibussowitsch { 30ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)A->data; 31e8aa55a4SKris Buschelman 32e8aa55a4SKris Buschelman PetscFunctionBegin; 331baa6e33SBarry 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 38*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x) 39*d71ae5a4SJacob Faibussowitsch { 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 53*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info) 54*d71ae5a4SJacob Faibussowitsch { 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 85*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info) 86*d71ae5a4SJacob Faibussowitsch { 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 105db4efbfdSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 106e8aa55a4SKris Buschelman PetscFunctionReturn(0); 107e8aa55a4SKris Buschelman } 108e8aa55a4SKris Buschelman 109*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) 110*d71ae5a4SJacob Faibussowitsch { 11135bd34faSBarry Smith PetscFunctionBegin; 1122692d6eeSBarry Smith *type = MATSOLVERESSL; 11335bd34faSBarry Smith PetscFunctionReturn(0); 11435bd34faSBarry Smith } 115719d5645SBarry Smith 1162f71e704SKris Buschelman /*MC 11711a5261eSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices 1182f71e704SKris Buschelman via the external package ESSL. 1192f71e704SKris Buschelman 1202f71e704SKris Buschelman If ESSL is installed (see the manual for 1212f71e704SKris Buschelman instructions on how to declare the existence of external packages), 1222f71e704SKris Buschelman 12311a5261eSBarry Smith Works with `MATSEQAIJ` matrices 1242f71e704SKris Buschelman 1252f71e704SKris Buschelman Level: beginner 1262f71e704SKris Buschelman 127db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 1282f71e704SKris Buschelman M*/ 1292f71e704SKris Buschelman 130*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) 131*d71ae5a4SJacob Faibussowitsch { 132b24902e0SBarry Smith Mat B; 133b24902e0SBarry Smith Mat_Essl *essl; 134e8aa55a4SKris Buschelman 135e8aa55a4SKris Buschelman PetscFunctionBegin; 13608401ef6SPierre Jolivet PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square"); 1379566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1389566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n)); 1399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name)); 1409566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 141b24902e0SBarry Smith 1424dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&essl)); 1432205254eSKarl Rupp 144ac913495SBarry Smith B->data = essl; 145b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 146ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 147ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1482205254eSKarl Rupp 1499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl)); 1502205254eSKarl Rupp 151d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 1529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU])); 1539566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 1549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype)); 15500c67f3bSHong Zhang 156b24902e0SBarry Smith *F = B; 157e8aa55a4SKris Buschelman PetscFunctionReturn(0); 158e8aa55a4SKris Buschelman } 15942c9c57cSBarry Smith 160*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) 161*d71ae5a4SJacob Faibussowitsch { 16242c9c57cSBarry Smith PetscFunctionBegin; 1639566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl)); 16442c9c57cSBarry Smith PetscFunctionReturn(0); 16542c9c57cSBarry Smith } 166