14b3f184cSKarl Rupp 24b3f184cSKarl Rupp /* -------------------------------------------------------------------- */ 34b3f184cSKarl Rupp 44b3f184cSKarl Rupp /* 54b3f184cSKarl Rupp Include files needed for the ViennaCL Chow-Patel parallel ILU preconditioner: 64b3f184cSKarl Rupp pcimpl.h - private include file intended for use by all preconditioners 74b3f184cSKarl Rupp */ 84b3f184cSKarl Rupp #define PETSC_SKIP_SPINLOCK 999acd6aaSStefano Zampini #define PETSC_SKIP_IMMINTRIN_H_CUDAWORKAROUND 1 1099acd6aaSStefano Zampini 114b3f184cSKarl Rupp #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/ 124b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/aij.h> 134b3f184cSKarl Rupp #include <../src/vec/vec/impls/dvecimpl.h> 144b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h> 154b3f184cSKarl Rupp #include <../src/vec/vec/impls/seq/seqviennacl/viennaclvecimpl.h> 164b3f184cSKarl Rupp #include <viennacl/linalg/detail/ilu/chow_patel_ilu.hpp> 174b3f184cSKarl Rupp 184b3f184cSKarl Rupp /* 194b3f184cSKarl Rupp Private context (data structure) for the CHOWILUVIENNACL preconditioner. 204b3f184cSKarl Rupp */ 214b3f184cSKarl Rupp typedef struct { 224b3f184cSKarl Rupp viennacl::linalg::chow_patel_ilu_precond< viennacl::compressed_matrix<PetscScalar> > *CHOWILUVIENNACL; 234b3f184cSKarl Rupp } PC_CHOWILUVIENNACL; 244b3f184cSKarl Rupp 254b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */ 264b3f184cSKarl Rupp /* 274b3f184cSKarl Rupp PCSetUp_CHOWILUVIENNACL - Prepares for the use of the CHOWILUVIENNACL preconditioner 284b3f184cSKarl Rupp by setting data structures and options. 294b3f184cSKarl Rupp 304b3f184cSKarl Rupp Input Parameter: 314b3f184cSKarl Rupp . pc - the preconditioner context 324b3f184cSKarl Rupp 334b3f184cSKarl Rupp Application Interface Routine: PCSetUp() 344b3f184cSKarl Rupp 354b3f184cSKarl Rupp Notes: 364b3f184cSKarl Rupp The interface routine PCSetUp() is not usually called directly by 374b3f184cSKarl Rupp the user, but instead is called by PCApply() if necessary. 384b3f184cSKarl Rupp */ 394b3f184cSKarl Rupp static PetscErrorCode PCSetUp_CHOWILUVIENNACL(PC pc) 404b3f184cSKarl Rupp { 414b3f184cSKarl Rupp PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL*)pc->data; 424b3f184cSKarl Rupp PetscBool flg = PETSC_FALSE; 434b3f184cSKarl Rupp PetscErrorCode ierr; 444b3f184cSKarl Rupp Mat_SeqAIJViennaCL *gpustruct; 454b3f184cSKarl Rupp 464b3f184cSKarl Rupp PetscFunctionBegin; 474b3f184cSKarl Rupp ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJVIENNACL,&flg);CHKERRQ(ierr); 48*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles ViennaCL matrices"); 494b3f184cSKarl Rupp if (pc->setupcalled != 0) { 504b3f184cSKarl Rupp try { 514b3f184cSKarl Rupp delete ilu->CHOWILUVIENNACL; 524b3f184cSKarl Rupp } catch(char *ex) { 5398921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex); 544b3f184cSKarl Rupp } 554b3f184cSKarl Rupp } 564b3f184cSKarl Rupp try { 574b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX) 584b3f184cSKarl Rupp gpustruct = NULL; 594b3f184cSKarl Rupp SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"No support for complex arithmetic in CHOWILUVIENNACL preconditioner"); 604b3f184cSKarl Rupp #else 614b3f184cSKarl Rupp ierr = MatViennaCLCopyToGPU(pc->pmat);CHKERRQ(ierr); 624b3f184cSKarl Rupp gpustruct = (Mat_SeqAIJViennaCL*)(pc->pmat->spptr); 634b3f184cSKarl Rupp 644b3f184cSKarl Rupp viennacl::linalg::chow_patel_tag ilu_tag; 654b3f184cSKarl Rupp ViennaCLAIJMatrix *mat = (ViennaCLAIJMatrix*)gpustruct->mat; 664b3f184cSKarl Rupp ilu->CHOWILUVIENNACL = new viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar> >(*mat, ilu_tag); 674b3f184cSKarl Rupp #endif 684b3f184cSKarl Rupp } catch(char *ex) { 6998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex); 704b3f184cSKarl Rupp } 714b3f184cSKarl Rupp PetscFunctionReturn(0); 724b3f184cSKarl Rupp } 734b3f184cSKarl Rupp 744b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */ 754b3f184cSKarl Rupp /* 764b3f184cSKarl Rupp PCApply_CHOWILUVIENNACL - Applies the CHOWILUVIENNACL preconditioner to a vector. 774b3f184cSKarl Rupp 784b3f184cSKarl Rupp Input Parameters: 794b3f184cSKarl Rupp . pc - the preconditioner context 804b3f184cSKarl Rupp . x - input vector 814b3f184cSKarl Rupp 824b3f184cSKarl Rupp Output Parameter: 834b3f184cSKarl Rupp . y - output vector 844b3f184cSKarl Rupp 854b3f184cSKarl Rupp Application Interface Routine: PCApply() 864b3f184cSKarl Rupp */ 874b3f184cSKarl Rupp static PetscErrorCode PCApply_CHOWILUVIENNACL(PC pc,Vec x,Vec y) 884b3f184cSKarl Rupp { 894b3f184cSKarl Rupp PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL*)pc->data; 904b3f184cSKarl Rupp PetscErrorCode ierr; 914b3f184cSKarl Rupp PetscBool flg1,flg2; 924b3f184cSKarl Rupp viennacl::vector<PetscScalar> const *xarray=NULL; 934b3f184cSKarl Rupp viennacl::vector<PetscScalar> *yarray=NULL; 944b3f184cSKarl Rupp 954b3f184cSKarl Rupp PetscFunctionBegin; 964b3f184cSKarl Rupp /*how to apply a certain fixed number of iterations?*/ 974b3f184cSKarl Rupp ierr = PetscObjectTypeCompare((PetscObject)x,VECSEQVIENNACL,&flg1);CHKERRQ(ierr); 984b3f184cSKarl Rupp ierr = PetscObjectTypeCompare((PetscObject)y,VECSEQVIENNACL,&flg2);CHKERRQ(ierr); 99*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!(flg1 && flg2),PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles ViennaCL vectors"); 1004b3f184cSKarl Rupp if (!ilu->CHOWILUVIENNACL) { 1014b3f184cSKarl Rupp ierr = PCSetUp_CHOWILUVIENNACL(pc);CHKERRQ(ierr); 1024b3f184cSKarl Rupp } 1034b3f184cSKarl Rupp ierr = VecSet(y,0.0);CHKERRQ(ierr); 1044b3f184cSKarl Rupp ierr = VecViennaCLGetArrayRead(x,&xarray);CHKERRQ(ierr); 1054b3f184cSKarl Rupp ierr = VecViennaCLGetArrayWrite(y,&yarray);CHKERRQ(ierr); 1064b3f184cSKarl Rupp try { 1074b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX) 1084b3f184cSKarl Rupp 1094b3f184cSKarl Rupp #else 1104b3f184cSKarl Rupp *yarray = *xarray; 1114b3f184cSKarl Rupp ilu->CHOWILUVIENNACL->apply(*yarray); 1124b3f184cSKarl Rupp #endif 1134b3f184cSKarl Rupp } catch(char * ex) { 11498921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex); 1154b3f184cSKarl Rupp } 1164b3f184cSKarl Rupp ierr = VecViennaCLRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 1174b3f184cSKarl Rupp ierr = VecViennaCLRestoreArrayWrite(y,&yarray);CHKERRQ(ierr); 1184b3f184cSKarl Rupp ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 1194b3f184cSKarl Rupp PetscFunctionReturn(0); 1204b3f184cSKarl Rupp } 1214b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */ 1224b3f184cSKarl Rupp /* 1234b3f184cSKarl Rupp PCDestroy_CHOWILUVIENNACL - Destroys the private context for the CHOWILUVIENNACL preconditioner 1244b3f184cSKarl Rupp that was created with PCCreate_CHOWILUVIENNACL(). 1254b3f184cSKarl Rupp 1264b3f184cSKarl Rupp Input Parameter: 1274b3f184cSKarl Rupp . pc - the preconditioner context 1284b3f184cSKarl Rupp 1294b3f184cSKarl Rupp Application Interface Routine: PCDestroy() 1304b3f184cSKarl Rupp */ 1314b3f184cSKarl Rupp static PetscErrorCode PCDestroy_CHOWILUVIENNACL(PC pc) 1324b3f184cSKarl Rupp { 1334b3f184cSKarl Rupp PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL*)pc->data; 1344b3f184cSKarl Rupp PetscErrorCode ierr; 1354b3f184cSKarl Rupp 1364b3f184cSKarl Rupp PetscFunctionBegin; 1374b3f184cSKarl Rupp if (ilu->CHOWILUVIENNACL) { 1384b3f184cSKarl Rupp try { 1394b3f184cSKarl Rupp delete ilu->CHOWILUVIENNACL; 1404b3f184cSKarl Rupp } catch(char *ex) { 14198921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex); 1424b3f184cSKarl Rupp } 1434b3f184cSKarl Rupp } 1444b3f184cSKarl Rupp 1454b3f184cSKarl Rupp /* 1464b3f184cSKarl Rupp Free the private data structure that was hanging off the PC 1474b3f184cSKarl Rupp */ 1484b3f184cSKarl Rupp ierr = PetscFree(pc->data);CHKERRQ(ierr); 1494b3f184cSKarl Rupp PetscFunctionReturn(0); 1504b3f184cSKarl Rupp } 1514b3f184cSKarl Rupp 1524b3f184cSKarl Rupp static PetscErrorCode PCSetFromOptions_CHOWILUVIENNACL(PetscOptionItems *PetscOptionsObject,PC pc) 1534b3f184cSKarl Rupp { 1544b3f184cSKarl Rupp PetscErrorCode ierr; 1554b3f184cSKarl Rupp 1564b3f184cSKarl Rupp PetscFunctionBegin; 1574b3f184cSKarl Rupp ierr = PetscOptionsHead(PetscOptionsObject,"CHOWILUVIENNACL options");CHKERRQ(ierr); 1584b3f184cSKarl Rupp ierr = PetscOptionsTail();CHKERRQ(ierr); 1594b3f184cSKarl Rupp PetscFunctionReturn(0); 1604b3f184cSKarl Rupp } 1614b3f184cSKarl Rupp 1624b3f184cSKarl Rupp /* -------------------------------------------------------------------------- */ 1634b3f184cSKarl Rupp 1644b3f184cSKarl Rupp /*MC 1654b3f184cSKarl Rupp PCCHOWILUViennaCL - A smoothed agglomeration algorithm that can be used via the CUDA, OpenCL, and OpenMP backends of ViennaCL 1664b3f184cSKarl Rupp 1674b3f184cSKarl Rupp Level: advanced 1684b3f184cSKarl Rupp 1694b3f184cSKarl Rupp .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 1704b3f184cSKarl Rupp 1714b3f184cSKarl Rupp M*/ 1724b3f184cSKarl Rupp 1734b3f184cSKarl Rupp PETSC_EXTERN PetscErrorCode PCCreate_CHOWILUVIENNACL(PC pc) 1744b3f184cSKarl Rupp { 1754b3f184cSKarl Rupp PC_CHOWILUVIENNACL *ilu; 1764b3f184cSKarl Rupp PetscErrorCode ierr; 1774b3f184cSKarl Rupp 1784b3f184cSKarl Rupp PetscFunctionBegin; 1794b3f184cSKarl Rupp /* 1804b3f184cSKarl Rupp Creates the private data structure for this preconditioner and 1814b3f184cSKarl Rupp attach it to the PC object. 1824b3f184cSKarl Rupp */ 1834b3f184cSKarl Rupp ierr = PetscNewLog(pc,&ilu);CHKERRQ(ierr); 1844b3f184cSKarl Rupp pc->data = (void*)ilu; 1854b3f184cSKarl Rupp 1864b3f184cSKarl Rupp /* 1874b3f184cSKarl Rupp Initialize the pointer to zero 1884b3f184cSKarl Rupp Initialize number of v-cycles to default (1) 1894b3f184cSKarl Rupp */ 1904b3f184cSKarl Rupp ilu->CHOWILUVIENNACL = 0; 1914b3f184cSKarl Rupp 1924b3f184cSKarl Rupp /* 1934b3f184cSKarl Rupp Set the pointers for the functions that are provided above. 1944b3f184cSKarl Rupp Now when the user-level routines (such as PCApply(), PCDestroy(), etc.) 1954b3f184cSKarl Rupp are called, they will automatically call these functions. Note we 1964b3f184cSKarl Rupp choose not to provide a couple of these functions since they are 1974b3f184cSKarl Rupp not needed. 1984b3f184cSKarl Rupp */ 1994b3f184cSKarl Rupp pc->ops->apply = PCApply_CHOWILUVIENNACL; 2004b3f184cSKarl Rupp pc->ops->applytranspose = 0; 2014b3f184cSKarl Rupp pc->ops->setup = PCSetUp_CHOWILUVIENNACL; 2024b3f184cSKarl Rupp pc->ops->destroy = PCDestroy_CHOWILUVIENNACL; 2034b3f184cSKarl Rupp pc->ops->setfromoptions = PCSetFromOptions_CHOWILUVIENNACL; 2044b3f184cSKarl Rupp pc->ops->view = 0; 2054b3f184cSKarl Rupp pc->ops->applyrichardson = 0; 2064b3f184cSKarl Rupp pc->ops->applysymmetricleft = 0; 2074b3f184cSKarl Rupp pc->ops->applysymmetricright = 0; 2084b3f184cSKarl Rupp PetscFunctionReturn(0); 2094b3f184cSKarl Rupp } 210