xref: /petsc/src/ksp/pc/impls/chowiluviennacl/chowiluviennacl.cxx (revision 2b338477d770c45a88d8c20a3ee06ef156cc4d7c)
14b3f184cSKarl Rupp /*
24b3f184cSKarl Rupp    Include files needed for the ViennaCL Chow-Patel parallel ILU preconditioner:
34b3f184cSKarl Rupp      pcimpl.h - private include file intended for use by all preconditioners
44b3f184cSKarl Rupp */
599acd6aaSStefano Zampini #define PETSC_SKIP_IMMINTRIN_H_CUDAWORKAROUND 1
699acd6aaSStefano Zampini 
74b3f184cSKarl Rupp #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
84b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/aij.h>
94b3f184cSKarl Rupp #include <../src/vec/vec/impls/dvecimpl.h>
104b3f184cSKarl Rupp #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h>
114b3f184cSKarl Rupp #include <../src/vec/vec/impls/seq/seqviennacl/viennaclvecimpl.h>
124b3f184cSKarl Rupp #include <viennacl/linalg/detail/ilu/chow_patel_ilu.hpp>
134b3f184cSKarl Rupp 
144b3f184cSKarl Rupp /*
154b3f184cSKarl Rupp    Private context (data structure) for the CHOWILUVIENNACL preconditioner.
164b3f184cSKarl Rupp */
174b3f184cSKarl Rupp typedef struct {
184b3f184cSKarl Rupp   viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar>> *CHOWILUVIENNACL;
194b3f184cSKarl Rupp } PC_CHOWILUVIENNACL;
204b3f184cSKarl Rupp 
214b3f184cSKarl Rupp /*
224b3f184cSKarl Rupp    PCSetUp_CHOWILUVIENNACL - Prepares for the use of the CHOWILUVIENNACL preconditioner
234b3f184cSKarl Rupp                              by setting data structures and options.
244b3f184cSKarl Rupp 
254b3f184cSKarl Rupp    Input Parameter:
264b3f184cSKarl Rupp .  pc - the preconditioner context
274b3f184cSKarl Rupp 
284b3f184cSKarl Rupp    Application Interface Routine: PCSetUp()
294b3f184cSKarl Rupp 
30f1580f4eSBarry Smith    Note:
314b3f184cSKarl Rupp    The interface routine PCSetUp() is not usually called directly by
324b3f184cSKarl Rupp    the user, but instead is called by PCApply() if necessary.
334b3f184cSKarl Rupp */
34d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCSetUp_CHOWILUVIENNACL(PC pc)
35d71ae5a4SJacob Faibussowitsch {
364b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL *)pc->data;
374b3f184cSKarl Rupp   PetscBool           flg = PETSC_FALSE;
384b3f184cSKarl Rupp   Mat_SeqAIJViennaCL *gpustruct;
394b3f184cSKarl Rupp 
404b3f184cSKarl Rupp   PetscFunctionBegin;
419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat, MATSEQAIJVIENNACL, &flg));
4228b400f6SJacob Faibussowitsch   PetscCheck(flg, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Currently only handles ViennaCL matrices");
43*371d2eb7SMartin Diehl   if (pc->setupcalled) {
444b3f184cSKarl Rupp     try {
454b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
46d71ae5a4SJacob Faibussowitsch     } catch (char *ex) {
47d71ae5a4SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
48d71ae5a4SJacob Faibussowitsch     }
494b3f184cSKarl Rupp   }
504b3f184cSKarl Rupp   try {
514b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
524b3f184cSKarl Rupp     gpustruct = NULL;
534b3f184cSKarl Rupp     SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "No support for complex arithmetic in CHOWILUVIENNACL preconditioner");
544b3f184cSKarl Rupp #else
559566063dSJacob Faibussowitsch     PetscCall(MatViennaCLCopyToGPU(pc->pmat));
56f4f49eeaSPierre Jolivet     gpustruct = (Mat_SeqAIJViennaCL *)pc->pmat->spptr;
574b3f184cSKarl Rupp 
584b3f184cSKarl Rupp     viennacl::linalg::chow_patel_tag ilu_tag;
594b3f184cSKarl Rupp     ViennaCLAIJMatrix               *mat = (ViennaCLAIJMatrix *)gpustruct->mat;
604b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL                 = new viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar>>(*mat, ilu_tag);
614b3f184cSKarl Rupp #endif
62d71ae5a4SJacob Faibussowitsch   } catch (char *ex) {
63d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
64d71ae5a4SJacob Faibussowitsch   }
653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
664b3f184cSKarl Rupp }
674b3f184cSKarl Rupp 
684b3f184cSKarl Rupp /*
694b3f184cSKarl Rupp    PCApply_CHOWILUVIENNACL - Applies the CHOWILUVIENNACL preconditioner to a vector.
704b3f184cSKarl Rupp 
714b3f184cSKarl Rupp    Input Parameters:
724b3f184cSKarl Rupp .  pc - the preconditioner context
734b3f184cSKarl Rupp .  x - input vector
744b3f184cSKarl Rupp 
754b3f184cSKarl Rupp    Output Parameter:
764b3f184cSKarl Rupp .  y - output vector
774b3f184cSKarl Rupp 
784b3f184cSKarl Rupp    Application Interface Routine: PCApply()
794b3f184cSKarl Rupp  */
80d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCApply_CHOWILUVIENNACL(PC pc, Vec x, Vec y)
81d71ae5a4SJacob Faibussowitsch {
824b3f184cSKarl Rupp   PC_CHOWILUVIENNACL                  *ilu = (PC_CHOWILUVIENNACL *)pc->data;
834b3f184cSKarl Rupp   PetscBool                            flg1, flg2;
844b3f184cSKarl Rupp   viennacl::vector<PetscScalar> const *xarray = NULL;
854b3f184cSKarl Rupp   viennacl::vector<PetscScalar>       *yarray = NULL;
864b3f184cSKarl Rupp 
874b3f184cSKarl Rupp   PetscFunctionBegin;
884b3f184cSKarl Rupp   /*how to apply a certain fixed number of iterations?*/
899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)x, VECSEQVIENNACL, &flg1));
909566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)y, VECSEQVIENNACL, &flg2));
9157508eceSPierre Jolivet   PetscCheck(flg1 && flg2, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Currently only handles ViennaCL vectors");
9248a46eb9SPierre Jolivet   if (!ilu->CHOWILUVIENNACL) PetscCall(PCSetUp_CHOWILUVIENNACL(pc));
939566063dSJacob Faibussowitsch   PetscCall(VecSet(y, 0.0));
949566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayRead(x, &xarray));
959566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayWrite(y, &yarray));
964b3f184cSKarl Rupp   try {
974b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
984b3f184cSKarl Rupp 
994b3f184cSKarl Rupp #else
1004b3f184cSKarl Rupp     *yarray = *xarray;
1014b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL->apply(*yarray);
1024b3f184cSKarl Rupp #endif
103d71ae5a4SJacob Faibussowitsch   } catch (char *ex) {
104d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
105d71ae5a4SJacob Faibussowitsch   }
1069566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayRead(x, &xarray));
1079566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayWrite(y, &yarray));
1089566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1104b3f184cSKarl Rupp }
111f1580f4eSBarry Smith 
1124b3f184cSKarl Rupp /*
1134b3f184cSKarl Rupp    PCDestroy_CHOWILUVIENNACL - Destroys the private context for the CHOWILUVIENNACL preconditioner
1144b3f184cSKarl Rupp    that was created with PCCreate_CHOWILUVIENNACL().
1154b3f184cSKarl Rupp 
1164b3f184cSKarl Rupp    Input Parameter:
1174b3f184cSKarl Rupp .  pc - the preconditioner context
1184b3f184cSKarl Rupp 
1194b3f184cSKarl Rupp    Application Interface Routine: PCDestroy()
1204b3f184cSKarl Rupp */
121d71ae5a4SJacob Faibussowitsch static PetscErrorCode PCDestroy_CHOWILUVIENNACL(PC pc)
122d71ae5a4SJacob Faibussowitsch {
1234b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL *)pc->data;
1244b3f184cSKarl Rupp 
1254b3f184cSKarl Rupp   PetscFunctionBegin;
1264b3f184cSKarl Rupp   if (ilu->CHOWILUVIENNACL) {
1274b3f184cSKarl Rupp     try {
1284b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
129d71ae5a4SJacob Faibussowitsch     } catch (char *ex) {
130d71ae5a4SJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex);
131d71ae5a4SJacob Faibussowitsch     }
1324b3f184cSKarl Rupp   }
1334b3f184cSKarl Rupp 
1344b3f184cSKarl Rupp   /*
1354b3f184cSKarl Rupp       Free the private data structure that was hanging off the PC
1364b3f184cSKarl Rupp   */
1379566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
1383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1394b3f184cSKarl Rupp }
1404b3f184cSKarl Rupp 
141ce78bad3SBarry Smith static PetscErrorCode PCSetFromOptions_CHOWILUVIENNACL(PC pc, PetscOptionItems PetscOptionsObject)
142d71ae5a4SJacob Faibussowitsch {
1434b3f184cSKarl Rupp   PetscFunctionBegin;
144d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "CHOWILUVIENNACL options");
145d0609cedSBarry Smith   PetscOptionsHeadEnd();
1463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1474b3f184cSKarl Rupp }
1484b3f184cSKarl Rupp 
149d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PCCreate_CHOWILUVIENNACL(PC pc)
150d71ae5a4SJacob Faibussowitsch {
1514b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu;
1524b3f184cSKarl Rupp 
1534b3f184cSKarl Rupp   PetscFunctionBegin;
1544b3f184cSKarl Rupp   /*
1554b3f184cSKarl Rupp      Creates the private data structure for this preconditioner and
1564b3f184cSKarl Rupp      attach it to the PC object.
1574b3f184cSKarl Rupp   */
1584dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&ilu));
1594b3f184cSKarl Rupp   pc->data = (void *)ilu;
1604b3f184cSKarl Rupp 
1614b3f184cSKarl Rupp   /*
1624b3f184cSKarl Rupp      Initialize the pointer to zero
1634b3f184cSKarl Rupp      Initialize number of v-cycles to default (1)
1644b3f184cSKarl Rupp   */
1654b3f184cSKarl Rupp   ilu->CHOWILUVIENNACL = 0;
1664b3f184cSKarl Rupp 
1674b3f184cSKarl Rupp   /*
1684b3f184cSKarl Rupp       Set the pointers for the functions that are provided above.
1694b3f184cSKarl Rupp       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
1704b3f184cSKarl Rupp       are called, they will automatically call these functions.  Note we
1714b3f184cSKarl Rupp       choose not to provide a couple of these functions since they are
1724b3f184cSKarl Rupp       not needed.
1734b3f184cSKarl Rupp   */
1744b3f184cSKarl Rupp   pc->ops->apply               = PCApply_CHOWILUVIENNACL;
1754b3f184cSKarl Rupp   pc->ops->applytranspose      = 0;
1764b3f184cSKarl Rupp   pc->ops->setup               = PCSetUp_CHOWILUVIENNACL;
1774b3f184cSKarl Rupp   pc->ops->destroy             = PCDestroy_CHOWILUVIENNACL;
1784b3f184cSKarl Rupp   pc->ops->setfromoptions      = PCSetFromOptions_CHOWILUVIENNACL;
1794b3f184cSKarl Rupp   pc->ops->view                = 0;
1804b3f184cSKarl Rupp   pc->ops->applyrichardson     = 0;
1814b3f184cSKarl Rupp   pc->ops->applysymmetricleft  = 0;
1824b3f184cSKarl Rupp   pc->ops->applysymmetricright = 0;
1833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1844b3f184cSKarl Rupp }
185