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