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