1e8aa55a4SKris Buschelman /* 2e8aa55a4SKris Buschelman Provides an interface to the IBM RS6000 Essl sparse solver 3e8aa55a4SKris Buschelman 4e8aa55a4SKris Buschelman */ 5c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 6b24902e0SBarry Smith 7e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work! */ 8e8aa55a4SKris Buschelman 98cc058d9SJed Brown PETSC_EXTERN void dgss(int *, int *, double *, int *, int *, int *, double *, double *, int *); 108cc058d9SJed Brown PETSC_EXTERN void dgsf(int *, int *, int *, double *, int *, int *, int *, int *, double *, double *, double *, int *); 11d3bad8c4SBarry Smith 12e8aa55a4SKris Buschelman typedef struct { 13e8aa55a4SKris Buschelman int n, nz; 14e8aa55a4SKris Buschelman PetscScalar *a; 15e8aa55a4SKris Buschelman int *ia; 16e8aa55a4SKris Buschelman int *ja; 17e8aa55a4SKris Buschelman int lna; 18e8aa55a4SKris Buschelman int iparm[5]; 19e8aa55a4SKris Buschelman PetscReal rparm[5]; 20e8aa55a4SKris Buschelman PetscReal oparm[5]; 21e8aa55a4SKris Buschelman PetscScalar *aux; 22e8aa55a4SKris Buschelman int naux; 23e8aa55a4SKris Buschelman 24ace3abfcSBarry Smith PetscBool CleanUpESSL; 25f0c56d0fSKris Buschelman } Mat_Essl; 26f0c56d0fSKris Buschelman 2766976f2fSJacob Faibussowitsch static PetscErrorCode MatDestroy_Essl(Mat A) 28d71ae5a4SJacob Faibussowitsch { 29ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)A->data; 30e8aa55a4SKris Buschelman 31e8aa55a4SKris Buschelman PetscFunctionBegin; 321baa6e33SBarry Smith if (essl->CleanUpESSL) PetscCall(PetscFree4(essl->a, essl->aux, essl->ia, essl->ja)); 339566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35460c4903SKris Buschelman } 36460c4903SKris Buschelman 3766976f2fSJacob Faibussowitsch static PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x) 38d71ae5a4SJacob Faibussowitsch { 39ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)A->data; 40e8aa55a4SKris Buschelman PetscScalar *xx; 41c5c20521SJed Brown int nessl, zero = 0; 42e8aa55a4SKris Buschelman 43e8aa55a4SKris Buschelman PetscFunctionBegin; 449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &nessl)); 459566063dSJacob Faibussowitsch PetscCall(VecCopy(b, x)); 469566063dSJacob Faibussowitsch PetscCall(VecGetArray(x, &xx)); 47c5c20521SJed Brown dgss(&zero, &nessl, essl->a, essl->ia, essl->ja, &essl->lna, xx, essl->aux, &essl->naux); 489566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x, &xx)); 493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50e8aa55a4SKris Buschelman } 51e8aa55a4SKris Buschelman 5266976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info) 53d71ae5a4SJacob Faibussowitsch { 54e8aa55a4SKris Buschelman Mat_SeqAIJ *aa = (Mat_SeqAIJ *)(A)->data; 55ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)(F)->data; 56c5c20521SJed Brown int nessl, i, one = 1; 57e8aa55a4SKris Buschelman 58e8aa55a4SKris Buschelman PetscFunctionBegin; 599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nessl)); 60da81f932SPierre Jolivet /* copy matrix data into silly ESSL data structure (1-based Fortran style) */ 61d0f46423SBarry Smith for (i = 0; i < A->rmap->n + 1; i++) essl->ia[i] = aa->i[i] + 1; 62e8aa55a4SKris Buschelman for (i = 0; i < aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 63e8aa55a4SKris Buschelman 649566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(essl->a, aa->a, aa->nz)); 65e8aa55a4SKris Buschelman 66e8aa55a4SKris Buschelman /* set Essl options */ 67e8aa55a4SKris Buschelman essl->iparm[0] = 1; 68e8aa55a4SKris Buschelman essl->iparm[1] = 5; 69e8aa55a4SKris Buschelman essl->iparm[2] = 1; 70e8aa55a4SKris Buschelman essl->iparm[3] = 0; 71e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 7262331464SKris Buschelman essl->rparm[1] = 1.0; 732205254eSKarl Rupp 749566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, ((PetscObject)A)->prefix, "-matessl_lu_threshold", &essl->rparm[1], NULL)); 75e8aa55a4SKris Buschelman 76c5c20521SJed Brown dgsf(&one, &nessl, &essl->nz, essl->a, essl->ia, essl->ja, &essl->lna, essl->iparm, essl->rparm, essl->oparm, essl->aux, &essl->naux); 77e8aa55a4SKris Buschelman 7835bd34faSBarry Smith F->ops->solve = MatSolve_Essl; 79719d5645SBarry Smith (F)->assembled = PETSC_TRUE; 80719d5645SBarry Smith (F)->preallocated = PETSC_TRUE; 813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82e8aa55a4SKris Buschelman } 83e8aa55a4SKris Buschelman 8466976f2fSJacob Faibussowitsch static PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info) 85d71ae5a4SJacob Faibussowitsch { 86eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 87f0c56d0fSKris Buschelman Mat_Essl *essl; 88e8aa55a4SKris Buschelman PetscReal f = 1.0; 89e8aa55a4SKris Buschelman 90e8aa55a4SKris Buschelman PetscFunctionBegin; 91*f4f49eeaSPierre Jolivet essl = (Mat_Essl *)B->data; 92e8aa55a4SKris Buschelman 93e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 94e8aa55a4SKris Buschelman f = info->fill; 959566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->nz, &essl->nz)); 969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast((PetscInt)(a->nz * f), &essl->lna)); 979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(100 + 10 * A->rmap->n, &essl->naux)); 98e8aa55a4SKris Buschelman 99e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 1009566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(essl->lna, &essl->a, essl->naux, &essl->aux, essl->lna, &essl->ia, essl->lna, &essl->ja)); 1012205254eSKarl Rupp 1022f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 103e8aa55a4SKris Buschelman 104db4efbfdSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 106e8aa55a4SKris Buschelman } 107e8aa55a4SKris Buschelman 10866976f2fSJacob Faibussowitsch static PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) 109d71ae5a4SJacob Faibussowitsch { 11035bd34faSBarry Smith PetscFunctionBegin; 1112692d6eeSBarry Smith *type = MATSOLVERESSL; 1123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11335bd34faSBarry Smith } 114719d5645SBarry Smith 1152f71e704SKris Buschelman /*MC 1162ef1f0ffSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices via the external package ESSL. 1172f71e704SKris Buschelman 11811a5261eSBarry Smith Works with `MATSEQAIJ` matrices 1192f71e704SKris Buschelman 1202f71e704SKris Buschelman Level: beginner 1212f71e704SKris Buschelman 1221cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 1232f71e704SKris Buschelman M*/ 1242f71e704SKris Buschelman 125d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) 126d71ae5a4SJacob Faibussowitsch { 127b24902e0SBarry Smith Mat B; 128b24902e0SBarry Smith Mat_Essl *essl; 129e8aa55a4SKris Buschelman 130e8aa55a4SKris Buschelman PetscFunctionBegin; 13108401ef6SPierre Jolivet PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square"); 1329566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1339566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n)); 1349566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name)); 1359566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 136b24902e0SBarry Smith 1374dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&essl)); 1382205254eSKarl Rupp 139ac913495SBarry Smith B->data = essl; 140b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 141ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 142ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1432205254eSKarl Rupp 1449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl)); 1452205254eSKarl Rupp 146d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 1479566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU])); 1489566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 1499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype)); 15000c67f3bSHong Zhang 151b24902e0SBarry Smith *F = B; 1523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 153e8aa55a4SKris Buschelman } 15442c9c57cSBarry Smith 155d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) 156d71ae5a4SJacob Faibussowitsch { 15742c9c57cSBarry Smith PetscFunctionBegin; 1589566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl)); 1593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16042c9c57cSBarry Smith } 161