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 28d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_Essl(Mat A) 29d71ae5a4SJacob 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)); 353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36460c4903SKris Buschelman } 37460c4903SKris Buschelman 38d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x) 39d71ae5a4SJacob 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)); 503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 51e8aa55a4SKris Buschelman } 52e8aa55a4SKris Buschelman 53d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info) 54d71ae5a4SJacob 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)); 61da81f932SPierre Jolivet /* copy matrix data into silly ESSL data structure (1-based Fortran 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; 823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83e8aa55a4SKris Buschelman } 84e8aa55a4SKris Buschelman 85d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info) 86d71ae5a4SJacob 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; 1063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107e8aa55a4SKris Buschelman } 108e8aa55a4SKris Buschelman 109d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) 110d71ae5a4SJacob Faibussowitsch { 11135bd34faSBarry Smith PetscFunctionBegin; 1122692d6eeSBarry Smith *type = MATSOLVERESSL; 1133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11435bd34faSBarry Smith } 115719d5645SBarry Smith 1162f71e704SKris Buschelman /*MC 1172ef1f0ffSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices via the external package ESSL. 1182f71e704SKris Buschelman 11911a5261eSBarry Smith Works with `MATSEQAIJ` matrices 1202f71e704SKris Buschelman 1212f71e704SKris Buschelman Level: beginner 1222f71e704SKris Buschelman 123*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 1242f71e704SKris Buschelman M*/ 1252f71e704SKris Buschelman 126d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) 127d71ae5a4SJacob Faibussowitsch { 128b24902e0SBarry Smith Mat B; 129b24902e0SBarry Smith Mat_Essl *essl; 130e8aa55a4SKris Buschelman 131e8aa55a4SKris Buschelman PetscFunctionBegin; 13208401ef6SPierre Jolivet PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square"); 1339566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1349566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n)); 1359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name)); 1369566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 137b24902e0SBarry Smith 1384dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&essl)); 1392205254eSKarl Rupp 140ac913495SBarry Smith B->data = essl; 141b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 142ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 143ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1442205254eSKarl Rupp 1459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl)); 1462205254eSKarl Rupp 147d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 1489566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU])); 1499566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 1509566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype)); 15100c67f3bSHong Zhang 152b24902e0SBarry Smith *F = B; 1533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 154e8aa55a4SKris Buschelman } 15542c9c57cSBarry Smith 156d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) 157d71ae5a4SJacob Faibussowitsch { 15842c9c57cSBarry Smith PetscFunctionBegin; 1599566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl)); 1603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16142c9c57cSBarry Smith } 162