xref: /petsc/src/ksp/pc/impls/chowiluviennacl/chowiluviennacl.cxx (revision 4b3f184ccd67909444362f8482c79c33e6a7622a)
1*4b3f184cSKarl Rupp 
2*4b3f184cSKarl Rupp /*  -------------------------------------------------------------------- */
3*4b3f184cSKarl Rupp 
4*4b3f184cSKarl Rupp /*
5*4b3f184cSKarl Rupp    Include files needed for the ViennaCL Chow-Patel parallel ILU preconditioner:
6*4b3f184cSKarl Rupp      pcimpl.h - private include file intended for use by all preconditioners
7*4b3f184cSKarl Rupp */
8*4b3f184cSKarl Rupp #define PETSC_SKIP_SPINLOCK
9*4b3f184cSKarl Rupp #include <petsc/private/pcimpl.h>   /*I "petscpc.h" I*/
10*4b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/aij.h>
11*4b3f184cSKarl Rupp #include <../src/vec/vec/impls/dvecimpl.h>
12*4b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h>
13*4b3f184cSKarl Rupp #include <../src/vec/vec/impls/seq/seqviennacl/viennaclvecimpl.h>
14*4b3f184cSKarl Rupp #include <viennacl/linalg/detail/ilu/chow_patel_ilu.hpp>
15*4b3f184cSKarl Rupp 
16*4b3f184cSKarl Rupp /*
17*4b3f184cSKarl Rupp    Private context (data structure) for the CHOWILUVIENNACL preconditioner.
18*4b3f184cSKarl Rupp */
19*4b3f184cSKarl Rupp typedef struct {
20*4b3f184cSKarl Rupp   viennacl::linalg::chow_patel_ilu_precond< viennacl::compressed_matrix<PetscScalar> > *CHOWILUVIENNACL;
21*4b3f184cSKarl Rupp } PC_CHOWILUVIENNACL;
22*4b3f184cSKarl Rupp 
23*4b3f184cSKarl Rupp 
24*4b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */
25*4b3f184cSKarl Rupp /*
26*4b3f184cSKarl Rupp    PCSetUp_CHOWILUVIENNACL - Prepares for the use of the CHOWILUVIENNACL preconditioner
27*4b3f184cSKarl Rupp                              by setting data structures and options.
28*4b3f184cSKarl Rupp 
29*4b3f184cSKarl Rupp    Input Parameter:
30*4b3f184cSKarl Rupp .  pc - the preconditioner context
31*4b3f184cSKarl Rupp 
32*4b3f184cSKarl Rupp    Application Interface Routine: PCSetUp()
33*4b3f184cSKarl Rupp 
34*4b3f184cSKarl Rupp    Notes:
35*4b3f184cSKarl Rupp    The interface routine PCSetUp() is not usually called directly by
36*4b3f184cSKarl Rupp    the user, but instead is called by PCApply() if necessary.
37*4b3f184cSKarl Rupp */
38*4b3f184cSKarl Rupp #undef __FUNCT__
39*4b3f184cSKarl Rupp #define __FUNCT__ "PCSetUp_CHOWILUVIENNACL"
40*4b3f184cSKarl Rupp static PetscErrorCode PCSetUp_CHOWILUVIENNACL(PC pc)
41*4b3f184cSKarl Rupp {
42*4b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL*)pc->data;
43*4b3f184cSKarl Rupp   PetscBool           flg = PETSC_FALSE;
44*4b3f184cSKarl Rupp   PetscErrorCode      ierr;
45*4b3f184cSKarl Rupp   Mat_SeqAIJViennaCL  *gpustruct;
46*4b3f184cSKarl Rupp 
47*4b3f184cSKarl Rupp   PetscFunctionBegin;
48*4b3f184cSKarl Rupp   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJVIENNACL,&flg);CHKERRQ(ierr);
49*4b3f184cSKarl Rupp   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles ViennaCL matrices");
50*4b3f184cSKarl Rupp   if (pc->setupcalled != 0) {
51*4b3f184cSKarl Rupp     try {
52*4b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
53*4b3f184cSKarl Rupp     } catch(char *ex) {
54*4b3f184cSKarl Rupp       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
55*4b3f184cSKarl Rupp     }
56*4b3f184cSKarl Rupp   }
57*4b3f184cSKarl Rupp   try {
58*4b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
59*4b3f184cSKarl Rupp     gpustruct = NULL;
60*4b3f184cSKarl Rupp     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"No support for complex arithmetic in CHOWILUVIENNACL preconditioner");
61*4b3f184cSKarl Rupp #else
62*4b3f184cSKarl Rupp     ierr      = MatViennaCLCopyToGPU(pc->pmat);CHKERRQ(ierr);
63*4b3f184cSKarl Rupp     gpustruct = (Mat_SeqAIJViennaCL*)(pc->pmat->spptr);
64*4b3f184cSKarl Rupp 
65*4b3f184cSKarl Rupp     viennacl::linalg::chow_patel_tag ilu_tag;
66*4b3f184cSKarl Rupp     ViennaCLAIJMatrix *mat = (ViennaCLAIJMatrix*)gpustruct->mat;
67*4b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL = new viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar> >(*mat, ilu_tag);
68*4b3f184cSKarl Rupp #endif
69*4b3f184cSKarl Rupp   } catch(char *ex) {
70*4b3f184cSKarl Rupp     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
71*4b3f184cSKarl Rupp   }
72*4b3f184cSKarl Rupp   PetscFunctionReturn(0);
73*4b3f184cSKarl Rupp }
74*4b3f184cSKarl Rupp 
75*4b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */
76*4b3f184cSKarl Rupp /*
77*4b3f184cSKarl Rupp    PCApply_CHOWILUVIENNACL - Applies the CHOWILUVIENNACL preconditioner to a vector.
78*4b3f184cSKarl Rupp 
79*4b3f184cSKarl Rupp    Input Parameters:
80*4b3f184cSKarl Rupp .  pc - the preconditioner context
81*4b3f184cSKarl Rupp .  x - input vector
82*4b3f184cSKarl Rupp 
83*4b3f184cSKarl Rupp    Output Parameter:
84*4b3f184cSKarl Rupp .  y - output vector
85*4b3f184cSKarl Rupp 
86*4b3f184cSKarl Rupp    Application Interface Routine: PCApply()
87*4b3f184cSKarl Rupp  */
88*4b3f184cSKarl Rupp #undef __FUNCT__
89*4b3f184cSKarl Rupp #define __FUNCT__ "PCApply_CHOWILUVIENNACL"
90*4b3f184cSKarl Rupp static PetscErrorCode PCApply_CHOWILUVIENNACL(PC pc,Vec x,Vec y)
91*4b3f184cSKarl Rupp {
92*4b3f184cSKarl Rupp   PC_CHOWILUVIENNACL            *ilu = (PC_CHOWILUVIENNACL*)pc->data;
93*4b3f184cSKarl Rupp   PetscErrorCode                ierr;
94*4b3f184cSKarl Rupp   PetscBool                     flg1,flg2;
95*4b3f184cSKarl Rupp   viennacl::vector<PetscScalar> const *xarray=NULL;
96*4b3f184cSKarl Rupp   viennacl::vector<PetscScalar> *yarray=NULL;
97*4b3f184cSKarl Rupp 
98*4b3f184cSKarl Rupp   PetscFunctionBegin;
99*4b3f184cSKarl Rupp   /*how to apply a certain fixed number of iterations?*/
100*4b3f184cSKarl Rupp   ierr = PetscObjectTypeCompare((PetscObject)x,VECSEQVIENNACL,&flg1);CHKERRQ(ierr);
101*4b3f184cSKarl Rupp   ierr = PetscObjectTypeCompare((PetscObject)y,VECSEQVIENNACL,&flg2);CHKERRQ(ierr);
102*4b3f184cSKarl Rupp   if (!(flg1 && flg2)) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles ViennaCL vectors");
103*4b3f184cSKarl Rupp   if (!ilu->CHOWILUVIENNACL) {
104*4b3f184cSKarl Rupp     ierr = PCSetUp_CHOWILUVIENNACL(pc);CHKERRQ(ierr);
105*4b3f184cSKarl Rupp   }
106*4b3f184cSKarl Rupp   ierr = VecSet(y,0.0);CHKERRQ(ierr);
107*4b3f184cSKarl Rupp   ierr = VecViennaCLGetArrayRead(x,&xarray);CHKERRQ(ierr);
108*4b3f184cSKarl Rupp   ierr = VecViennaCLGetArrayWrite(y,&yarray);CHKERRQ(ierr);
109*4b3f184cSKarl Rupp   try {
110*4b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
111*4b3f184cSKarl Rupp 
112*4b3f184cSKarl Rupp #else
113*4b3f184cSKarl Rupp     *yarray = *xarray;
114*4b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL->apply(*yarray);
115*4b3f184cSKarl Rupp #endif
116*4b3f184cSKarl Rupp   } catch(char * ex) {
117*4b3f184cSKarl Rupp     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
118*4b3f184cSKarl Rupp   }
119*4b3f184cSKarl Rupp   ierr = VecViennaCLRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
120*4b3f184cSKarl Rupp   ierr = VecViennaCLRestoreArrayWrite(y,&yarray);CHKERRQ(ierr);
121*4b3f184cSKarl Rupp   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
122*4b3f184cSKarl Rupp   PetscFunctionReturn(0);
123*4b3f184cSKarl Rupp }
124*4b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */
125*4b3f184cSKarl Rupp /*
126*4b3f184cSKarl Rupp    PCDestroy_CHOWILUVIENNACL - Destroys the private context for the CHOWILUVIENNACL preconditioner
127*4b3f184cSKarl Rupp    that was created with PCCreate_CHOWILUVIENNACL().
128*4b3f184cSKarl Rupp 
129*4b3f184cSKarl Rupp    Input Parameter:
130*4b3f184cSKarl Rupp .  pc - the preconditioner context
131*4b3f184cSKarl Rupp 
132*4b3f184cSKarl Rupp    Application Interface Routine: PCDestroy()
133*4b3f184cSKarl Rupp */
134*4b3f184cSKarl Rupp #undef __FUNCT__
135*4b3f184cSKarl Rupp #define __FUNCT__ "PCDestroy_CHOWILUVIENNACL"
136*4b3f184cSKarl Rupp static PetscErrorCode PCDestroy_CHOWILUVIENNACL(PC pc)
137*4b3f184cSKarl Rupp {
138*4b3f184cSKarl Rupp   PC_CHOWILUVIENNACL  *ilu = (PC_CHOWILUVIENNACL*)pc->data;
139*4b3f184cSKarl Rupp   PetscErrorCode ierr;
140*4b3f184cSKarl Rupp 
141*4b3f184cSKarl Rupp   PetscFunctionBegin;
142*4b3f184cSKarl Rupp   if (ilu->CHOWILUVIENNACL) {
143*4b3f184cSKarl Rupp     try {
144*4b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
145*4b3f184cSKarl Rupp     } catch(char *ex) {
146*4b3f184cSKarl Rupp       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
147*4b3f184cSKarl Rupp     }
148*4b3f184cSKarl Rupp   }
149*4b3f184cSKarl Rupp 
150*4b3f184cSKarl Rupp   /*
151*4b3f184cSKarl Rupp       Free the private data structure that was hanging off the PC
152*4b3f184cSKarl Rupp   */
153*4b3f184cSKarl Rupp   ierr = PetscFree(pc->data);CHKERRQ(ierr);
154*4b3f184cSKarl Rupp   PetscFunctionReturn(0);
155*4b3f184cSKarl Rupp }
156*4b3f184cSKarl Rupp 
157*4b3f184cSKarl Rupp #undef __FUNCT__
158*4b3f184cSKarl Rupp #define __FUNCT__ "PCSetFromOptions_CHOWILUVIENNACL"
159*4b3f184cSKarl Rupp static PetscErrorCode PCSetFromOptions_CHOWILUVIENNACL(PetscOptionItems *PetscOptionsObject,PC pc)
160*4b3f184cSKarl Rupp {
161*4b3f184cSKarl Rupp   PetscErrorCode ierr;
162*4b3f184cSKarl Rupp 
163*4b3f184cSKarl Rupp   PetscFunctionBegin;
164*4b3f184cSKarl Rupp   ierr = PetscOptionsHead(PetscOptionsObject,"CHOWILUVIENNACL options");CHKERRQ(ierr);
165*4b3f184cSKarl Rupp   ierr = PetscOptionsTail();CHKERRQ(ierr);
166*4b3f184cSKarl Rupp   PetscFunctionReturn(0);
167*4b3f184cSKarl Rupp }
168*4b3f184cSKarl Rupp 
169*4b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */
170*4b3f184cSKarl Rupp 
171*4b3f184cSKarl Rupp 
172*4b3f184cSKarl Rupp /*MC
173*4b3f184cSKarl Rupp      PCCHOWILUViennaCL  - A smoothed agglomeration algorithm that can be used via the CUDA, OpenCL, and OpenMP backends of ViennaCL
174*4b3f184cSKarl Rupp 
175*4b3f184cSKarl Rupp    Level: advanced
176*4b3f184cSKarl Rupp 
177*4b3f184cSKarl Rupp .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
178*4b3f184cSKarl Rupp 
179*4b3f184cSKarl Rupp M*/
180*4b3f184cSKarl Rupp 
181*4b3f184cSKarl Rupp #undef __FUNCT__
182*4b3f184cSKarl Rupp #define __FUNCT__ "PCCreate_CHOWILUVIENNACL"
183*4b3f184cSKarl Rupp PETSC_EXTERN PetscErrorCode PCCreate_CHOWILUVIENNACL(PC pc)
184*4b3f184cSKarl Rupp {
185*4b3f184cSKarl Rupp   PC_CHOWILUVIENNACL  *ilu;
186*4b3f184cSKarl Rupp   PetscErrorCode ierr;
187*4b3f184cSKarl Rupp 
188*4b3f184cSKarl Rupp   PetscFunctionBegin;
189*4b3f184cSKarl Rupp   /*
190*4b3f184cSKarl Rupp      Creates the private data structure for this preconditioner and
191*4b3f184cSKarl Rupp      attach it to the PC object.
192*4b3f184cSKarl Rupp   */
193*4b3f184cSKarl Rupp   ierr     = PetscNewLog(pc,&ilu);CHKERRQ(ierr);
194*4b3f184cSKarl Rupp   pc->data = (void*)ilu;
195*4b3f184cSKarl Rupp 
196*4b3f184cSKarl Rupp   /*
197*4b3f184cSKarl Rupp      Initialize the pointer to zero
198*4b3f184cSKarl Rupp      Initialize number of v-cycles to default (1)
199*4b3f184cSKarl Rupp   */
200*4b3f184cSKarl Rupp   ilu->CHOWILUVIENNACL = 0;
201*4b3f184cSKarl Rupp 
202*4b3f184cSKarl Rupp   /*
203*4b3f184cSKarl Rupp       Set the pointers for the functions that are provided above.
204*4b3f184cSKarl Rupp       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
205*4b3f184cSKarl Rupp       are called, they will automatically call these functions.  Note we
206*4b3f184cSKarl Rupp       choose not to provide a couple of these functions since they are
207*4b3f184cSKarl Rupp       not needed.
208*4b3f184cSKarl Rupp   */
209*4b3f184cSKarl Rupp   pc->ops->apply               = PCApply_CHOWILUVIENNACL;
210*4b3f184cSKarl Rupp   pc->ops->applytranspose      = 0;
211*4b3f184cSKarl Rupp   pc->ops->setup               = PCSetUp_CHOWILUVIENNACL;
212*4b3f184cSKarl Rupp   pc->ops->destroy             = PCDestroy_CHOWILUVIENNACL;
213*4b3f184cSKarl Rupp   pc->ops->setfromoptions      = PCSetFromOptions_CHOWILUVIENNACL;
214*4b3f184cSKarl Rupp   pc->ops->view                = 0;
215*4b3f184cSKarl Rupp   pc->ops->applyrichardson     = 0;
216*4b3f184cSKarl Rupp   pc->ops->applysymmetricleft  = 0;
217*4b3f184cSKarl Rupp   pc->ops->applysymmetricright = 0;
218*4b3f184cSKarl Rupp   PetscFunctionReturn(0);
219*4b3f184cSKarl Rupp }
220*4b3f184cSKarl Rupp 
221