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