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 289371c9d4SSatish Balay PetscErrorCode MatDestroy_Essl(Mat A) { 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)); 34460c4903SKris Buschelman PetscFunctionReturn(0); 35460c4903SKris Buschelman } 36460c4903SKris Buschelman 379371c9d4SSatish Balay PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x) { 38ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)A->data; 39e8aa55a4SKris Buschelman PetscScalar *xx; 40c5c20521SJed Brown int nessl, zero = 0; 41e8aa55a4SKris Buschelman 42e8aa55a4SKris Buschelman PetscFunctionBegin; 439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &nessl)); 449566063dSJacob Faibussowitsch PetscCall(VecCopy(b, x)); 459566063dSJacob Faibussowitsch PetscCall(VecGetArray(x, &xx)); 46c5c20521SJed Brown dgss(&zero, &nessl, essl->a, essl->ia, essl->ja, &essl->lna, xx, essl->aux, &essl->naux); 479566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(x, &xx)); 48e8aa55a4SKris Buschelman PetscFunctionReturn(0); 49e8aa55a4SKris Buschelman } 50e8aa55a4SKris Buschelman 519371c9d4SSatish Balay PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info) { 52e8aa55a4SKris Buschelman Mat_SeqAIJ *aa = (Mat_SeqAIJ *)(A)->data; 53ac913495SBarry Smith Mat_Essl *essl = (Mat_Essl *)(F)->data; 54c5c20521SJed Brown int nessl, i, one = 1; 55e8aa55a4SKris Buschelman 56e8aa55a4SKris Buschelman PetscFunctionBegin; 579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nessl)); 58e8aa55a4SKris Buschelman /* copy matrix data into silly ESSL data structure (1-based Frotran style) */ 59d0f46423SBarry Smith for (i = 0; i < A->rmap->n + 1; i++) essl->ia[i] = aa->i[i] + 1; 60e8aa55a4SKris Buschelman for (i = 0; i < aa->nz; i++) essl->ja[i] = aa->j[i] + 1; 61e8aa55a4SKris Buschelman 629566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(essl->a, aa->a, aa->nz)); 63e8aa55a4SKris Buschelman 64e8aa55a4SKris Buschelman /* set Essl options */ 65e8aa55a4SKris Buschelman essl->iparm[0] = 1; 66e8aa55a4SKris Buschelman essl->iparm[1] = 5; 67e8aa55a4SKris Buschelman essl->iparm[2] = 1; 68e8aa55a4SKris Buschelman essl->iparm[3] = 0; 69e8aa55a4SKris Buschelman essl->rparm[0] = 1.e-12; 7062331464SKris Buschelman essl->rparm[1] = 1.0; 712205254eSKarl Rupp 729566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, ((PetscObject)A)->prefix, "-matessl_lu_threshold", &essl->rparm[1], NULL)); 73e8aa55a4SKris Buschelman 74c5c20521SJed Brown dgsf(&one, &nessl, &essl->nz, essl->a, essl->ia, essl->ja, &essl->lna, essl->iparm, essl->rparm, essl->oparm, essl->aux, &essl->naux); 75e8aa55a4SKris Buschelman 7635bd34faSBarry Smith F->ops->solve = MatSolve_Essl; 77719d5645SBarry Smith (F)->assembled = PETSC_TRUE; 78719d5645SBarry Smith (F)->preallocated = PETSC_TRUE; 79e8aa55a4SKris Buschelman PetscFunctionReturn(0); 80e8aa55a4SKris Buschelman } 81e8aa55a4SKris Buschelman 829371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info) { 83eef49c96SKris Buschelman Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 84f0c56d0fSKris Buschelman Mat_Essl *essl; 85e8aa55a4SKris Buschelman PetscReal f = 1.0; 86e8aa55a4SKris Buschelman 87e8aa55a4SKris Buschelman PetscFunctionBegin; 88ac913495SBarry Smith essl = (Mat_Essl *)(B->data); 89e8aa55a4SKris Buschelman 90e8aa55a4SKris Buschelman /* allocate the work arrays required by ESSL */ 91e8aa55a4SKris Buschelman f = info->fill; 929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->nz, &essl->nz)); 939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast((PetscInt)(a->nz * f), &essl->lna)); 949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(100 + 10 * A->rmap->n, &essl->naux)); 95e8aa55a4SKris Buschelman 96e8aa55a4SKris Buschelman /* since malloc is slow on IBM we try a single malloc */ 979566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(essl->lna, &essl->a, essl->naux, &essl->aux, essl->lna, &essl->ia, essl->lna, &essl->ja)); 982205254eSKarl Rupp 992f71e704SKris Buschelman essl->CleanUpESSL = PETSC_TRUE; 100e8aa55a4SKris Buschelman 101db4efbfdSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_Essl; 102e8aa55a4SKris Buschelman PetscFunctionReturn(0); 103e8aa55a4SKris Buschelman } 104e8aa55a4SKris Buschelman 1059371c9d4SSatish Balay PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) { 10635bd34faSBarry Smith PetscFunctionBegin; 1072692d6eeSBarry Smith *type = MATSOLVERESSL; 10835bd34faSBarry Smith PetscFunctionReturn(0); 10935bd34faSBarry Smith } 110719d5645SBarry Smith 1112f71e704SKris Buschelman /*MC 11211a5261eSBarry Smith MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices 1132f71e704SKris Buschelman via the external package ESSL. 1142f71e704SKris Buschelman 1152f71e704SKris Buschelman If ESSL is installed (see the manual for 1162f71e704SKris Buschelman instructions on how to declare the existence of external packages), 1172f71e704SKris Buschelman 11811a5261eSBarry Smith Works with `MATSEQAIJ` matrices 1192f71e704SKris Buschelman 1202f71e704SKris Buschelman Level: beginner 1212f71e704SKris Buschelman 122db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType` 1232f71e704SKris Buschelman M*/ 1242f71e704SKris Buschelman 1259371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) { 126b24902e0SBarry Smith Mat B; 127b24902e0SBarry Smith Mat_Essl *essl; 128e8aa55a4SKris Buschelman 129e8aa55a4SKris Buschelman PetscFunctionBegin; 13008401ef6SPierre Jolivet PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square"); 1319566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1329566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n)); 1339566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name)); 1349566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 135b24902e0SBarry Smith 136*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&essl)); 1372205254eSKarl Rupp 138ac913495SBarry Smith B->data = essl; 139b24902e0SBarry Smith B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl; 140ac913495SBarry Smith B->ops->destroy = MatDestroy_Essl; 141ac913495SBarry Smith B->ops->getinfo = MatGetInfo_External; 1422205254eSKarl Rupp 1439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl)); 1442205254eSKarl Rupp 145d5f3da31SBarry Smith B->factortype = MAT_FACTOR_LU; 1469566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU])); 1479566063dSJacob Faibussowitsch PetscCall(PetscFree(B->solvertype)); 1489566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype)); 14900c67f3bSHong Zhang 150b24902e0SBarry Smith *F = B; 151e8aa55a4SKris Buschelman PetscFunctionReturn(0); 152e8aa55a4SKris Buschelman } 15342c9c57cSBarry Smith 1549371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) { 15542c9c57cSBarry Smith PetscFunctionBegin; 1569566063dSJacob Faibussowitsch PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl)); 15742c9c57cSBarry Smith PetscFunctionReturn(0); 15842c9c57cSBarry Smith } 159