xref: /petsc/src/ksp/pc/impls/chowiluviennacl/chowiluviennacl.cxx (revision f1580f4e3ce5d5b2393648fd039d0d41b440385d)
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 
32*f1580f4eSBarry 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 */
369371c9d4SSatish Balay static PetscErrorCode PCSetUp_CHOWILUVIENNACL(PC pc) {
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;
479371c9d4SSatish Balay     } catch (char *ex) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex); }
484b3f184cSKarl Rupp   }
494b3f184cSKarl Rupp   try {
504b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
514b3f184cSKarl Rupp     gpustruct = NULL;
524b3f184cSKarl Rupp     SETERRQ(PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "No support for complex arithmetic in CHOWILUVIENNACL preconditioner");
534b3f184cSKarl Rupp #else
549566063dSJacob Faibussowitsch     PetscCall(MatViennaCLCopyToGPU(pc->pmat));
554b3f184cSKarl Rupp     gpustruct = (Mat_SeqAIJViennaCL *)(pc->pmat->spptr);
564b3f184cSKarl Rupp 
574b3f184cSKarl Rupp     viennacl::linalg::chow_patel_tag ilu_tag;
584b3f184cSKarl Rupp     ViennaCLAIJMatrix               *mat = (ViennaCLAIJMatrix *)gpustruct->mat;
594b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL                 = new viennacl::linalg::chow_patel_ilu_precond<viennacl::compressed_matrix<PetscScalar>>(*mat, ilu_tag);
604b3f184cSKarl Rupp #endif
619371c9d4SSatish Balay   } catch (char *ex) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex); }
624b3f184cSKarl Rupp   PetscFunctionReturn(0);
634b3f184cSKarl Rupp }
644b3f184cSKarl Rupp 
654b3f184cSKarl Rupp /*
664b3f184cSKarl Rupp    PCApply_CHOWILUVIENNACL - Applies the CHOWILUVIENNACL preconditioner to a vector.
674b3f184cSKarl Rupp 
684b3f184cSKarl Rupp    Input Parameters:
694b3f184cSKarl Rupp .  pc - the preconditioner context
704b3f184cSKarl Rupp .  x - input vector
714b3f184cSKarl Rupp 
724b3f184cSKarl Rupp    Output Parameter:
734b3f184cSKarl Rupp .  y - output vector
744b3f184cSKarl Rupp 
754b3f184cSKarl Rupp    Application Interface Routine: PCApply()
764b3f184cSKarl Rupp  */
779371c9d4SSatish Balay static PetscErrorCode PCApply_CHOWILUVIENNACL(PC pc, Vec x, Vec y) {
784b3f184cSKarl Rupp   PC_CHOWILUVIENNACL                  *ilu = (PC_CHOWILUVIENNACL *)pc->data;
794b3f184cSKarl Rupp   PetscBool                            flg1, flg2;
804b3f184cSKarl Rupp   viennacl::vector<PetscScalar> const *xarray = NULL;
814b3f184cSKarl Rupp   viennacl::vector<PetscScalar>       *yarray = NULL;
824b3f184cSKarl Rupp 
834b3f184cSKarl Rupp   PetscFunctionBegin;
844b3f184cSKarl Rupp   /*how to apply a certain fixed number of iterations?*/
859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)x, VECSEQVIENNACL, &flg1));
869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)y, VECSEQVIENNACL, &flg2));
8708401ef6SPierre Jolivet   PetscCheck((flg1 && flg2), PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Currently only handles ViennaCL vectors");
8848a46eb9SPierre Jolivet   if (!ilu->CHOWILUVIENNACL) PetscCall(PCSetUp_CHOWILUVIENNACL(pc));
899566063dSJacob Faibussowitsch   PetscCall(VecSet(y, 0.0));
909566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayRead(x, &xarray));
919566063dSJacob Faibussowitsch   PetscCall(VecViennaCLGetArrayWrite(y, &yarray));
924b3f184cSKarl Rupp   try {
934b3f184cSKarl Rupp #if defined(PETSC_USE_COMPLEX)
944b3f184cSKarl Rupp 
954b3f184cSKarl Rupp #else
964b3f184cSKarl Rupp     *yarray                              = *xarray;
974b3f184cSKarl Rupp     ilu->CHOWILUVIENNACL->apply(*yarray);
984b3f184cSKarl Rupp #endif
999371c9d4SSatish Balay   } catch (char *ex) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex); }
1009566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayRead(x, &xarray));
1019566063dSJacob Faibussowitsch   PetscCall(VecViennaCLRestoreArrayWrite(y, &yarray));
1029566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)y));
1034b3f184cSKarl Rupp   PetscFunctionReturn(0);
1044b3f184cSKarl Rupp }
105*f1580f4eSBarry Smith 
1064b3f184cSKarl Rupp /*
1074b3f184cSKarl Rupp    PCDestroy_CHOWILUVIENNACL - Destroys the private context for the CHOWILUVIENNACL preconditioner
1084b3f184cSKarl Rupp    that was created with PCCreate_CHOWILUVIENNACL().
1094b3f184cSKarl Rupp 
1104b3f184cSKarl Rupp    Input Parameter:
1114b3f184cSKarl Rupp .  pc - the preconditioner context
1124b3f184cSKarl Rupp 
1134b3f184cSKarl Rupp    Application Interface Routine: PCDestroy()
1144b3f184cSKarl Rupp */
1159371c9d4SSatish Balay static PetscErrorCode PCDestroy_CHOWILUVIENNACL(PC pc) {
1164b3f184cSKarl Rupp   PC_CHOWILUVIENNACL *ilu = (PC_CHOWILUVIENNACL *)pc->data;
1174b3f184cSKarl Rupp 
1184b3f184cSKarl Rupp   PetscFunctionBegin;
1194b3f184cSKarl Rupp   if (ilu->CHOWILUVIENNACL) {
1204b3f184cSKarl Rupp     try {
1214b3f184cSKarl Rupp       delete ilu->CHOWILUVIENNACL;
1229371c9d4SSatish Balay     } catch (char *ex) { SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "ViennaCL error: %s", ex); }
1234b3f184cSKarl Rupp   }
1244b3f184cSKarl Rupp 
1254b3f184cSKarl Rupp   /*
1264b3f184cSKarl Rupp       Free the private data structure that was hanging off the PC
1274b3f184cSKarl Rupp   */
1289566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
1294b3f184cSKarl Rupp   PetscFunctionReturn(0);
1304b3f184cSKarl Rupp }
1314b3f184cSKarl Rupp 
1329371c9d4SSatish Balay static PetscErrorCode PCSetFromOptions_CHOWILUVIENNACL(PC pc, PetscOptionItems *PetscOptionsObject) {
1334b3f184cSKarl Rupp   PetscFunctionBegin;
134d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "CHOWILUVIENNACL options");
135d0609cedSBarry Smith   PetscOptionsHeadEnd();
1364b3f184cSKarl Rupp   PetscFunctionReturn(0);
1374b3f184cSKarl Rupp }
1384b3f184cSKarl Rupp 
1394b3f184cSKarl Rupp /*MC
1404b3f184cSKarl Rupp      PCCHOWILUViennaCL  - A smoothed agglomeration algorithm that can be used via the CUDA, OpenCL, and OpenMP backends of ViennaCL
1414b3f184cSKarl Rupp 
1424b3f184cSKarl Rupp    Level: advanced
1434b3f184cSKarl Rupp 
144*f1580f4eSBarry Smith    Developer Note:
145*f1580f4eSBarry Smith    This does not appear to be wired up with `PCRegisterType()`
1464b3f184cSKarl Rupp 
147*f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`
1484b3f184cSKarl Rupp M*/
1494b3f184cSKarl Rupp 
1509371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PCCreate_CHOWILUVIENNACL(PC pc) {
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   */
1589566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc, &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;
1834b3f184cSKarl Rupp   PetscFunctionReturn(0);
1844b3f184cSKarl Rupp }
185