xref: /petsc/src/ksp/pc/impls/chowiluviennacl/chowiluviennacl.cxx (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
14b3f184cSKarl Rupp 
24b3f184cSKarl Rupp /*
34b3f184cSKarl Rupp    Include files needed for the ViennaCL Chow-Patel parallel ILU preconditioner:
44b3f184cSKarl Rupp      pcimpl.h - private include file intended for use by all preconditioners
54b3f184cSKarl Rupp */
64b3f184cSKarl Rupp #define PETSC_SKIP_SPINLOCK
799acd6aaSStefano Zampini #define PETSC_SKIP_IMMINTRIN_H_CUDAWORKAROUND 1
899acd6aaSStefano Zampini 
94b3f184cSKarl Rupp #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
104b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/aij.h>
114b3f184cSKarl Rupp #include <../src/vec/vec/impls/dvecimpl.h>
124b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h>
134b3f184cSKarl Rupp #include <../src/vec/vec/impls/seq/seqviennacl/viennaclvecimpl.h>
144b3f184cSKarl Rupp #include <viennacl/linalg/detail/ilu/chow_patel_ilu.hpp>
154b3f184cSKarl Rupp 
164b3f184cSKarl Rupp /*
174b3f184cSKarl Rupp    Private context (data structure) for the CHOWILUVIENNACL preconditioner.
184b3f184cSKarl Rupp */
194b3f184cSKarl Rupp typedef struct {
204b3f184cSKarl Rupp   viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar>> *CHOWILUVIENNACL;
214b3f184cSKarl Rupp } PC_CHOWILUVIENNACL;
224b3f184cSKarl Rupp 
234b3f184cSKarl Rupp /*
244b3f184cSKarl Rupp    PCSetUp_CHOWILUVIENNACL - Prepares for the use of the CHOWILUVIENNACL preconditioner
254b3f184cSKarl Rupp                              by setting data structures and options.
264b3f184cSKarl Rupp 
274b3f184cSKarl Rupp    Input Parameter:
284b3f184cSKarl Rupp .  pc - the preconditioner context
294b3f184cSKarl Rupp 
304b3f184cSKarl Rupp    Application Interface Routine: PCSetUp()
314b3f184cSKarl Rupp 
32f1580f4eSBarry Smith    Note:
334b3f184cSKarl Rupp    The interface routine PCSetUp() is not usually called directly by
344b3f184cSKarl Rupp    the user, but instead is called by PCApply() if necessary.
354b3f184cSKarl Rupp */
36*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_CHOWILUVIENNACL(PC pc)
37*d71ae5a4SJacob Faibussowitsch {
384b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL *)pc->data;
394b3f184cSKarl Rupp   PetscBool           flg = PETSC_FALSE;
404b3f184cSKarl Rupp   Mat_SeqAIJViennaCL *gpustruct;
414b3f184cSKarl Rupp 
424b3f184cSKarl Rupp   PetscFunctionBegin;
439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATSEQAIJVIENNACL, &flg));
4428b400f6SJacob Faibussowitsch   PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Currently only handles ViennaCL matrices");
454b3f184cSKarl Rupp   if (pc->setupcalled != 0) {
464b3f184cSKarl Rupp     try {
474b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
48*d71ae5a4SJacob Faibussowitsch     } catch (char *ex) {
49*d71ae5a4SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
50*d71ae5a4SJacob Faibussowitsch     }
514b3f184cSKarl Rupp   }
524b3f184cSKarl Rupp   try {
534b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
544b3f184cSKarl Rupp     gpustruct = NULL;
554b3f184cSKarl Rupp     SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "No support for complex arithmetic in CHOWILUVIENNACL preconditioner");
564b3f184cSKarl Rupp #else
579566063dSJacob Faibussowitsch     PetscCall(MatViennaCLCopyToGPU(pc->pmat));
584b3f184cSKarl Rupp     gpustruct = (Mat_SeqAIJViennaCL *)(pc->pmat->spptr);
594b3f184cSKarl Rupp 
604b3f184cSKarl Rupp     viennacl::linalg::chow_patel_tag ilu_tag;
614b3f184cSKarl Rupp     ViennaCLAIJMatrix               *mat = (ViennaCLAIJMatrix *)gpustruct->mat;
624b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL                 = new viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar>>(*mat, ilu_tag);
634b3f184cSKarl Rupp #endif
64*d71ae5a4SJacob Faibussowitsch   } catch (char *ex) {
65*d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
66*d71ae5a4SJacob Faibussowitsch   }
674b3f184cSKarl Rupp   PetscFunctionReturn(0);
684b3f184cSKarl Rupp }
694b3f184cSKarl Rupp 
704b3f184cSKarl Rupp /*
714b3f184cSKarl Rupp    PCApply_CHOWILUVIENNACL - Applies the CHOWILUVIENNACL preconditioner to a vector.
724b3f184cSKarl Rupp 
734b3f184cSKarl Rupp    Input Parameters:
744b3f184cSKarl Rupp .  pc - the preconditioner context
754b3f184cSKarl Rupp .  x - input vector
764b3f184cSKarl Rupp 
774b3f184cSKarl Rupp    Output Parameter:
784b3f184cSKarl Rupp .  y - output vector
794b3f184cSKarl Rupp 
804b3f184cSKarl Rupp    Application Interface Routine: PCApply()
814b3f184cSKarl Rupp  */
82*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_CHOWILUVIENNACL(PC pc, Vec x, Vec y)
83*d71ae5a4SJacob Faibussowitsch {
844b3f184cSKarl Rupp   PC_CHOWILUVIENNACL                  *ilu = (PC_CHOWILUVIENNACL *)pc->data;
854b3f184cSKarl Rupp   PetscBool                            flg1, flg2;
864b3f184cSKarl Rupp   viennacl::vector<PetscScalar> const *xarray = NULL;
874b3f184cSKarl Rupp   viennacl::vector<PetscScalar>       *yarray = NULL;
884b3f184cSKarl Rupp 
894b3f184cSKarl Rupp   PetscFunctionBegin;
904b3f184cSKarl Rupp   /*how to apply a certain fixed number of iterations?*/
919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)x, VECSEQVIENNACL, &flg1));
929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)y, VECSEQVIENNACL, &flg2));
9308401ef6SPierre Jolivet   PetscCheck((flg1 && flg2), PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Currently only handles ViennaCL vectors");
9448a46eb9SPierre Jolivet   if (!ilu->CHOWILUVIENNACL) PetscCall(PCSetUp_CHOWILUVIENNACL(pc));
959566063dSJacob Faibussowitsch   PetscCall(VecSet(y, 0.0));
969566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayRead(x, &xarray));
979566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayWrite(y, &yarray));
984b3f184cSKarl Rupp   try {
994b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
1004b3f184cSKarl Rupp 
1014b3f184cSKarl Rupp #else
1024b3f184cSKarl Rupp     *yarray                              = *xarray;
1034b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL->apply(*yarray);
1044b3f184cSKarl Rupp #endif
105*d71ae5a4SJacob Faibussowitsch   } catch (char *ex) {
106*d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
107*d71ae5a4SJacob Faibussowitsch   }
1089566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayRead(x, &xarray));
1099566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayWrite(y, &yarray));
1109566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1114b3f184cSKarl Rupp   PetscFunctionReturn(0);
1124b3f184cSKarl Rupp }
113f1580f4eSBarry Smith 
1144b3f184cSKarl Rupp /*
1154b3f184cSKarl Rupp    PCDestroy_CHOWILUVIENNACL - Destroys the private context for the CHOWILUVIENNACL preconditioner
1164b3f184cSKarl Rupp    that was created with PCCreate_CHOWILUVIENNACL().
1174b3f184cSKarl Rupp 
1184b3f184cSKarl Rupp    Input Parameter:
1194b3f184cSKarl Rupp .  pc - the preconditioner context
1204b3f184cSKarl Rupp 
1214b3f184cSKarl Rupp    Application Interface Routine: PCDestroy()
1224b3f184cSKarl Rupp */
123*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_CHOWILUVIENNACL(PC pc)
124*d71ae5a4SJacob Faibussowitsch {
1254b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL *)pc->data;
1264b3f184cSKarl Rupp 
1274b3f184cSKarl Rupp   PetscFunctionBegin;
1284b3f184cSKarl Rupp   if (ilu->CHOWILUVIENNACL) {
1294b3f184cSKarl Rupp     try {
1304b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
131*d71ae5a4SJacob Faibussowitsch     } catch (char *ex) {
132*d71ae5a4SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
133*d71ae5a4SJacob Faibussowitsch     }
1344b3f184cSKarl Rupp   }
1354b3f184cSKarl Rupp 
1364b3f184cSKarl Rupp   /*
1374b3f184cSKarl Rupp       Free the private data structure that was hanging off the PC
1384b3f184cSKarl Rupp   */
1399566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
1404b3f184cSKarl Rupp   PetscFunctionReturn(0);
1414b3f184cSKarl Rupp }
1424b3f184cSKarl Rupp 
143*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetFromOptions_CHOWILUVIENNACL(PC pc, PetscOptionItems *PetscOptionsObject)
144*d71ae5a4SJacob Faibussowitsch {
1454b3f184cSKarl Rupp   PetscFunctionBegin;
146d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "CHOWILUVIENNACL options");
147d0609cedSBarry Smith   PetscOptionsHeadEnd();
1484b3f184cSKarl Rupp   PetscFunctionReturn(0);
1494b3f184cSKarl Rupp }
1504b3f184cSKarl Rupp 
1514b3f184cSKarl Rupp /*MC
1524b3f184cSKarl Rupp      PCCHOWILUViennaCL  - A smoothed agglomeration algorithm that can be used via the CUDA, OpenCL, and OpenMP backends of ViennaCL
1534b3f184cSKarl Rupp 
1544b3f184cSKarl Rupp    Level: advanced
1554b3f184cSKarl Rupp 
156f1580f4eSBarry Smith    Developer Note:
157f1580f4eSBarry Smith    This does not appear to be wired up with `PCRegisterType()`
1584b3f184cSKarl Rupp 
159f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`
1604b3f184cSKarl Rupp M*/
1614b3f184cSKarl Rupp 
162*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_CHOWILUVIENNACL(PC pc)
163*d71ae5a4SJacob Faibussowitsch {
1644b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu;
1654b3f184cSKarl Rupp 
1664b3f184cSKarl Rupp   PetscFunctionBegin;
1674b3f184cSKarl Rupp   /*
1684b3f184cSKarl Rupp      Creates the private data structure for this preconditioner and
1694b3f184cSKarl Rupp      attach it to the PC object.
1704b3f184cSKarl Rupp   */
1714dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&ilu));
1724b3f184cSKarl Rupp   pc->data = (void *)ilu;
1734b3f184cSKarl Rupp 
1744b3f184cSKarl Rupp   /*
1754b3f184cSKarl Rupp      Initialize the pointer to zero
1764b3f184cSKarl Rupp      Initialize number of v-cycles to default (1)
1774b3f184cSKarl Rupp   */
1784b3f184cSKarl Rupp   ilu->CHOWILUVIENNACL = 0;
1794b3f184cSKarl Rupp 
1804b3f184cSKarl Rupp   /*
1814b3f184cSKarl Rupp       Set the pointers for the functions that are provided above.
1824b3f184cSKarl Rupp       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
1834b3f184cSKarl Rupp       are called, they will automatically call these functions.  Note we
1844b3f184cSKarl Rupp       choose not to provide a couple of these functions since they are
1854b3f184cSKarl Rupp       not needed.
1864b3f184cSKarl Rupp   */
1874b3f184cSKarl Rupp   pc->ops->apply               = PCApply_CHOWILUVIENNACL;
1884b3f184cSKarl Rupp   pc->ops->applytranspose      = 0;
1894b3f184cSKarl Rupp   pc->ops->setup               = PCSetUp_CHOWILUVIENNACL;
1904b3f184cSKarl Rupp   pc->ops->destroy             = PCDestroy_CHOWILUVIENNACL;
1914b3f184cSKarl Rupp   pc->ops->setfromoptions      = PCSetFromOptions_CHOWILUVIENNACL;
1924b3f184cSKarl Rupp   pc->ops->view                = 0;
1934b3f184cSKarl Rupp   pc->ops->applyrichardson     = 0;
1944b3f184cSKarl Rupp   pc->ops->applysymmetricleft  = 0;
1954b3f184cSKarl Rupp   pc->ops->applysymmetricright = 0;
1964b3f184cSKarl Rupp   PetscFunctionReturn(0);
1974b3f184cSKarl Rupp }
198