xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 17667f9060a8aad9ce8a34f74735d38d2a7e6242)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2e8aa55a4SKris Buschelman 
3e8aa55a4SKris Buschelman /*
4e8aa55a4SKris Buschelman         Provides an interface to the IBM RS6000 Essl sparse solver
5e8aa55a4SKris Buschelman 
6e8aa55a4SKris Buschelman */
7e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
9e8aa55a4SKris Buschelman 
10d3bad8c4SBarry Smith EXTERN_C_BEGIN
11d3bad8c4SBarry Smith void dgss(int*,int*,double*,int*,int*,int*,double*,double*,int*);
12d3bad8c4SBarry Smith void dgsf(int*,int*,int*,double*,int*,int*,int*,int*,double*,double*,double*,int*);
13d3bad8c4SBarry Smith EXTERN_C_END
14d3bad8c4SBarry Smith 
15e8aa55a4SKris Buschelman typedef struct {
16e8aa55a4SKris Buschelman   int         n,nz;
17e8aa55a4SKris Buschelman   PetscScalar *a;
18e8aa55a4SKris Buschelman   int         *ia;
19e8aa55a4SKris Buschelman   int         *ja;
20e8aa55a4SKris Buschelman   int         lna;
21e8aa55a4SKris Buschelman   int         iparm[5];
22e8aa55a4SKris Buschelman   PetscReal   rparm[5];
23e8aa55a4SKris Buschelman   PetscReal   oparm[5];
24e8aa55a4SKris Buschelman   PetscScalar *aux;
25e8aa55a4SKris Buschelman   int         naux;
26e8aa55a4SKris Buschelman 
276849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
286849ba73SBarry Smith   PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType);
296849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
306849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
312f71e704SKris Buschelman   PetscTruth CleanUpESSL;
32f0c56d0fSKris Buschelman } Mat_Essl;
33f0c56d0fSKris Buschelman 
34dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*);
35e8aa55a4SKris Buschelman 
36460c4903SKris Buschelman EXTERN_C_BEGIN
37460c4903SKris Buschelman #undef __FUNCT__
38460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ"
39d3bad8c4SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Essl_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat) {
40dfbe8321SBarry Smith   PetscErrorCode ierr;
41460c4903SKris Buschelman   Mat            B=*newmat;
42f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)A->spptr;
43460c4903SKris Buschelman 
44460c4903SKris Buschelman   PetscFunctionBegin;
45ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
46460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);
47f0c56d0fSKris Buschelman   }
48f0c56d0fSKris Buschelman   B->ops->duplicate        = essl->MatDuplicate;
49f0c56d0fSKris Buschelman   B->ops->assemblyend      = essl->MatAssemblyEnd;
502f71e704SKris Buschelman   B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic;
512f71e704SKris Buschelman   B->ops->destroy          = essl->MatDestroy;
522f71e704SKris Buschelman 
53460c4903SKris Buschelman   /* free the Essl datastructures */
54460c4903SKris Buschelman   ierr = PetscFree(essl);CHKERRQ(ierr);
55901853e0SKris Buschelman 
56901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr);
57901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
58901853e0SKris Buschelman 
59460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
60460c4903SKris Buschelman   *newmat = B;
61460c4903SKris Buschelman   PetscFunctionReturn(0);
62460c4903SKris Buschelman }
63460c4903SKris Buschelman EXTERN_C_END
64460c4903SKris Buschelman 
65e8aa55a4SKris Buschelman #undef __FUNCT__
66f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
67dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
68dfbe8321SBarry Smith {
69dfbe8321SBarry Smith   PetscErrorCode ierr;
70f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)A->spptr;
71e8aa55a4SKris Buschelman 
72e8aa55a4SKris Buschelman   PetscFunctionBegin;
732f71e704SKris Buschelman   if (essl->CleanUpESSL) {
742f71e704SKris Buschelman     ierr = PetscFree(essl->a);CHKERRQ(ierr);
75e8aa55a4SKris Buschelman   }
76ceb03754SKris Buschelman   ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
772f71e704SKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
78460c4903SKris Buschelman   PetscFunctionReturn(0);
79460c4903SKris Buschelman }
80460c4903SKris Buschelman 
81460c4903SKris Buschelman #undef __FUNCT__
82f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl"
83dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) {
84f0c56d0fSKris Buschelman   Mat_Essl       *essl = (Mat_Essl*)A->spptr;
85e8aa55a4SKris Buschelman   PetscScalar    *xx;
86dfbe8321SBarry Smith   PetscErrorCode ierr;
87dfbe8321SBarry Smith   int            m,zero = 0;
88e8aa55a4SKris Buschelman 
89e8aa55a4SKris Buschelman   PetscFunctionBegin;
90e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
91e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
92e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
932a4c71feSBarry Smith   dgss(&zero,&A->cmap.n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
94e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
95e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
96e8aa55a4SKris Buschelman }
97e8aa55a4SKris Buschelman 
98e8aa55a4SKris Buschelman #undef __FUNCT__
99f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
100af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) {
101e8aa55a4SKris Buschelman   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)(A)->data;
102f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)(*F)->spptr;
1036849ba73SBarry Smith   PetscErrorCode ierr;
1046849ba73SBarry Smith   int            i,one = 1;
105e8aa55a4SKris Buschelman 
106e8aa55a4SKris Buschelman   PetscFunctionBegin;
107e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
1082a4c71feSBarry Smith   for (i=0; i<A->rmap.n+1; i++) essl->ia[i] = aa->i[i] + 1;
109e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
110e8aa55a4SKris Buschelman 
111e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
112e8aa55a4SKris Buschelman 
113e8aa55a4SKris Buschelman   /* set Essl options */
114e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
115e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
116e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
117e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
118e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
11962331464SKris Buschelman   essl->rparm[1] = 1.0;
12062331464SKris Buschelman   ierr = PetscOptionsGetReal(A->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr);
121e8aa55a4SKris Buschelman 
1222a4c71feSBarry Smith   dgsf(&one,&A->rmap.n,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,
123e8aa55a4SKris Buschelman                essl->rparm,essl->oparm,essl->aux,&essl->naux);
124e8aa55a4SKris Buschelman 
125d3bad8c4SBarry Smith   (*F)->assembled = PETSC_TRUE;
126e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
127e8aa55a4SKris Buschelman }
128e8aa55a4SKris Buschelman 
129e8aa55a4SKris Buschelman #undef __FUNCT__
130f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
131dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) {
132e8aa55a4SKris Buschelman   Mat            B;
133eef49c96SKris Buschelman   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
134dfbe8321SBarry Smith   PetscErrorCode ierr;
135dfbe8321SBarry Smith   int            len;
136f0c56d0fSKris Buschelman   Mat_Essl       *essl;
137e8aa55a4SKris Buschelman   PetscReal      f = 1.0;
138e8aa55a4SKris Buschelman 
139e8aa55a4SKris Buschelman   PetscFunctionBegin;
1402a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
141f69a0ea3SMatthew Knepley   ierr = MatCreate(A->comm,&B);CHKERRQ(ierr);
1422a4c71feSBarry Smith   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
143be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);CHKERRQ(ierr);
144e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
145e8aa55a4SKris Buschelman 
146f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
147f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
148e8aa55a4SKris Buschelman   B->factor               = FACTOR_LU;
149e8aa55a4SKris Buschelman 
150f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
151e8aa55a4SKris Buschelman 
152e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
153e8aa55a4SKris Buschelman   f = info->fill;
154e8aa55a4SKris Buschelman   essl->nz   = a->nz;
155e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
1562a4c71feSBarry Smith   essl->naux = 100 + 10*A->rmap.n;
157e8aa55a4SKris Buschelman 
158e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
159e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
160e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
161e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
162e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
163e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1642f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
165e8aa55a4SKris Buschelman 
16652e6d16bSBarry Smith   ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr);
167e8aa55a4SKris Buschelman   *F = B;
168e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
169e8aa55a4SKris Buschelman }
170e8aa55a4SKris Buschelman 
1712f71e704SKris Buschelman #undef __FUNCT__
172f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl"
1731153da11SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode)
1741153da11SBarry Smith {
175dfbe8321SBarry Smith   PetscErrorCode ierr;
176f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)(A->spptr);
1772f71e704SKris Buschelman 
1782f71e704SKris Buschelman   PetscFunctionBegin;
1792f71e704SKris Buschelman   ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
1802f71e704SKris Buschelman 
1812f71e704SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
182f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
183ae15b995SBarry Smith   ierr = PetscInfo(0,"Using ESSL for LU factorization and solves\n");CHKERRQ(ierr);
1842f71e704SKris Buschelman   PetscFunctionReturn(0);
1852f71e704SKris Buschelman }
1862f71e704SKris Buschelman 
187460c4903SKris Buschelman EXTERN_C_BEGIN
188e8aa55a4SKris Buschelman #undef __FUNCT__
189460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl"
190d3bad8c4SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Essl(Mat A,MatType type,MatReuse reuse,Mat *newmat)
191521d7252SBarry Smith {
192460c4903SKris Buschelman   Mat            B=*newmat;
193dfbe8321SBarry Smith   PetscErrorCode ierr;
194f0c56d0fSKris Buschelman   Mat_Essl       *essl;
195460c4903SKris Buschelman 
196e8aa55a4SKris Buschelman   PetscFunctionBegin;
197ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
198460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
199460c4903SKris Buschelman   }
200460c4903SKris Buschelman 
201f0c56d0fSKris Buschelman   ierr                      = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr);
202f0c56d0fSKris Buschelman   essl->MatDuplicate        = A->ops->duplicate;
203460c4903SKris Buschelman   essl->MatAssemblyEnd      = A->ops->assemblyend;
204460c4903SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
205460c4903SKris Buschelman   essl->MatDestroy          = A->ops->destroy;
2062f71e704SKris Buschelman   essl->CleanUpESSL         = PETSC_FALSE;
207460c4903SKris Buschelman 
2082f71e704SKris Buschelman   B->spptr                  = (void*)essl;
209f0c56d0fSKris Buschelman   B->ops->duplicate         = MatDuplicate_Essl;
210f0c56d0fSKris Buschelman   B->ops->assemblyend       = MatAssemblyEnd_Essl;
211f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
212f0c56d0fSKris Buschelman   B->ops->destroy           = MatDestroy_Essl;
213460c4903SKris Buschelman 
214460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C",
215460c4903SKris Buschelman                                            "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr);
216460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C",
217460c4903SKris Buschelman                                            "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr);
218460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr);
21962331464SKris Buschelman 
220460c4903SKris Buschelman   *newmat = B;
221e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
222e8aa55a4SKris Buschelman }
223460c4903SKris Buschelman EXTERN_C_END
224e8aa55a4SKris Buschelman 
225f0c56d0fSKris Buschelman #undef __FUNCT__
226f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl"
2271153da11SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M)
2281153da11SBarry Smith {
229dfbe8321SBarry Smith   PetscErrorCode ierr;
23013ee22deSSatish Balay   Mat_Essl       *lu = (Mat_Essl *)A->spptr;
2318f340917SKris Buschelman 
232f0c56d0fSKris Buschelman   PetscFunctionBegin;
2338f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
2343f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr);
235f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
236f0c56d0fSKris Buschelman }
237f0c56d0fSKris Buschelman 
2382f71e704SKris Buschelman /*MC
239fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
2402f71e704SKris Buschelman   via the external package ESSL.
2412f71e704SKris Buschelman 
2422f71e704SKris Buschelman   If ESSL is installed (see the manual for
2432f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2442f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2452f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2462f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2472f71e704SKris Buschelman 
2482f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
24928b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
25028b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
2512f71e704SKris Buschelman 
2522f71e704SKris Buschelman   Options Database Keys:
2530bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
2542f71e704SKris Buschelman 
2552f71e704SKris Buschelman    Level: beginner
2562f71e704SKris Buschelman 
2572f71e704SKris Buschelman .seealso: PCLU
2582f71e704SKris Buschelman M*/
2592f71e704SKris Buschelman 
260e8aa55a4SKris Buschelman EXTERN_C_BEGIN
261e8aa55a4SKris Buschelman #undef __FUNCT__
262f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
263be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Essl(Mat A)
264dfbe8321SBarry Smith {
265dfbe8321SBarry Smith   PetscErrorCode ierr;
266e8aa55a4SKris Buschelman 
267e8aa55a4SKris Buschelman   PetscFunctionBegin;
268*17667f90SBarry Smith   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
269ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
270e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
271e8aa55a4SKris Buschelman }
2724eb8e494SKris Buschelman EXTERN_C_END
273