Actual source code: rowscalingviennacl.cxx

petsc-3.10.5 2019-03-28
Report Typos and Errors

  2: /*  -------------------------------------------------------------------- */

  4: /*
  5:    Include files needed for the ViennaCL row-scaling preconditioner:
  6:      pcimpl.h - private include file intended for use by all preconditioners
  7: */
  8: #define PETSC_SKIP_SPINLOCK
  9:  #include <petsc/private/pcimpl.h>
 10:  #include <../src/mat/impls/aij/seq/aij.h>
 11:  #include <../src/vec/vec/impls/dvecimpl.h>
 12:  #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h>
 13:  #include <../src/vec/vec/impls/seq/seqviennacl/viennaclvecimpl.h>
 14: #include <viennacl/linalg/row_scaling.hpp>

 16: /*
 17:    Private context (data structure) for the ROWSCALINGVIENNACL preconditioner.
 18: */
 19: typedef struct {
 20:   viennacl::linalg::row_scaling< viennacl::compressed_matrix<PetscScalar> > *ROWSCALINGVIENNACL;
 21: } PC_ROWSCALINGVIENNACL;


 24: /* -------------------------------------------------------------------------- */
 25: /*
 26:    PCSetUp_ROWSCALINGVIENNACL - Prepares for the use of the ROWSCALINGVIENNACL preconditioner
 27:                                 by setting data structures and options.

 29:    Input Parameter:
 30: .  pc - the preconditioner context

 32:    Application Interface Routine: PCSetUp()

 34:    Notes:
 35:    The interface routine PCSetUp() is not usually called directly by
 36:    the user, but instead is called by PCApply() if necessary.
 37: */
 38: static PetscErrorCode PCSetUp_ROWSCALINGVIENNACL(PC pc)
 39: {
 40:   PC_ROWSCALINGVIENNACL  *rowscaling = (PC_ROWSCALINGVIENNACL*)pc->data;
 41:   PetscBool              flg = PETSC_FALSE;
 42:   PetscErrorCode         ierr;
 43:   Mat_SeqAIJViennaCL     *gpustruct;

 46:   PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJVIENNACL,&flg);
 47:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles ViennaCL matrices");
 48:   if (pc->setupcalled != 0) {
 49:     try {
 50:       delete rowscaling->ROWSCALINGVIENNACL;
 51:     } catch(char *ex) {
 52:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
 53:     }
 54:   }
 55:   try {
 56: #if defined(PETSC_USE_COMPLEX)
 57:     gpustruct = NULL;
 58:     SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"No support for complex arithmetic in ROWSCALINGVIENNACL preconditioner");
 59: #else
 60:     MatViennaCLCopyToGPU(pc->pmat);
 61:     gpustruct = (Mat_SeqAIJViennaCL*)(pc->pmat->spptr);
 62: 
 63:     viennacl::linalg::row_scaling_tag pc_tag(1);
 64:     ViennaCLAIJMatrix *mat = (ViennaCLAIJMatrix*)gpustruct->mat;
 65:     rowscaling->ROWSCALINGVIENNACL = new viennacl::linalg::row_scaling<viennacl::compressed_matrix<PetscScalar> >(*mat, pc_tag);
 66: #endif
 67:   } catch(char *ex) {
 68:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
 69:   }
 70:   return(0);
 71: }

 73: /* -------------------------------------------------------------------------- */
 74: /*
 75:    PCApply_ROWSCALINGVIENNACL - Applies the ROWSCALINGVIENNACL preconditioner to a vector.

 77:    Input Parameters:
 78: .  pc - the preconditioner context
 79: .  x - input vector

 81:    Output Parameter:
 82: .  y - output vector

 84:    Application Interface Routine: PCApply()
 85:  */
 86: static PetscErrorCode PCApply_ROWSCALINGVIENNACL(PC pc,Vec x,Vec y)
 87: {
 88:   PC_ROWSCALINGVIENNACL         *ilu = (PC_ROWSCALINGVIENNACL*)pc->data;
 89:   PetscErrorCode                ierr;
 90:   PetscBool                     flg1,flg2;
 91:   viennacl::vector<PetscScalar> const *xarray=NULL;
 92:   viennacl::vector<PetscScalar> *yarray=NULL;

 95:   /*how to apply a certain fixed number of iterations?*/
 96:   PetscObjectTypeCompare((PetscObject)x,VECSEQVIENNACL,&flg1);
 97:   PetscObjectTypeCompare((PetscObject)y,VECSEQVIENNACL,&flg2);
 98:   if (!(flg1 && flg2)) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles ViennaCL vectors");
 99:   if (!ilu->ROWSCALINGVIENNACL) {
100:     PCSetUp_ROWSCALINGVIENNACL(pc);
101:   }
102:   VecSet(y,0.0);
103:   VecViennaCLGetArrayRead(x,&xarray);
104:   VecViennaCLGetArrayWrite(y,&yarray);
105:   try {
106: #if defined(PETSC_USE_COMPLEX)

108: #else
109:     *yarray = *xarray;
110:     ilu->ROWSCALINGVIENNACL->apply(*yarray);
111: #endif
112:   } catch(char * ex) {
113:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
114:   }
115:   VecViennaCLRestoreArrayRead(x,&xarray);
116:   VecViennaCLRestoreArrayWrite(y,&yarray);
117:   PetscObjectStateIncrease((PetscObject)y);
118:   return(0);
119: }
120: /* -------------------------------------------------------------------------- */
121: /*
122:    PCDestroy_ROWSCALINGVIENNACL - Destroys the private context for the ROWSCALINGVIENNACL preconditioner
123:    that was created with PCCreate_ROWSCALINGVIENNACL().

125:    Input Parameter:
126: .  pc - the preconditioner context

128:    Application Interface Routine: PCDestroy()
129: */
130: static PetscErrorCode PCDestroy_ROWSCALINGVIENNACL(PC pc)
131: {
132:   PC_ROWSCALINGVIENNACL  *rowscaling = (PC_ROWSCALINGVIENNACL*)pc->data;

136:   if (rowscaling->ROWSCALINGVIENNACL) {
137:     try {
138:       delete rowscaling->ROWSCALINGVIENNACL;
139:     } catch(char *ex) {
140:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
141:     }
142:   }

144:   /*
145:       Free the private data structure that was hanging off the PC
146:   */
147:   PetscFree(pc->data);
148:   return(0);
149: }

151: static PetscErrorCode PCSetFromOptions_ROWSCALINGVIENNACL(PetscOptionItems *PetscOptionsObject,PC pc)
152: {

156:   PetscOptionsHead(PetscOptionsObject,"ROWSCALINGVIENNACL options");
157:   PetscOptionsTail();
158:   return(0);
159: }

161: /* -------------------------------------------------------------------------- */


164: /*MC
165:      PCRowScalingViennaCL  - A diagonal preconditioner (scaling rows of matrices by their norm) that can be used via the CUDA, OpenCL, and OpenMP backends of ViennaCL

167:    Level: advanced

169: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC

171: M*/

173: PETSC_EXTERN PetscErrorCode PCCreate_ROWSCALINGVIENNACL(PC pc)
174: {
175:   PC_ROWSCALINGVIENNACL  *rowscaling;

179:   /*
180:      Creates the private data structure for this preconditioner and
181:      attach it to the PC object.
182:   */
183:   PetscNewLog(pc,&rowscaling);
184:   pc->data = (void*)rowscaling;

186:   /*
187:      Initialize the pointer to zero
188:      Initialize number of v-cycles to default (1)
189:   */
190:   rowscaling->ROWSCALINGVIENNACL = 0;

192:   /*
193:       Set the pointers for the functions that are provided above.
194:       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
195:       are called, they will automatically call these functions.  Note we
196:       choose not to provide a couple of these functions since they are
197:       not needed.
198:   */
199:   pc->ops->apply               = PCApply_ROWSCALINGVIENNACL;
200:   pc->ops->applytranspose      = 0;
201:   pc->ops->setup               = PCSetUp_ROWSCALINGVIENNACL;
202:   pc->ops->destroy             = PCDestroy_ROWSCALINGVIENNACL;
203:   pc->ops->setfromoptions      = PCSetFromOptions_ROWSCALINGVIENNACL;
204:   pc->ops->view                = 0;
205:   pc->ops->applyrichardson     = 0;
206:   pc->ops->applysymmetricleft  = 0;
207:   pc->ops->applysymmetricright = 0;
208:   return(0);
209: }