Actual source code: bicgstabcusp.cu

petsc-3.5.4 2015-05-23
Report Typos and Errors
  2: /*  -------------------------------------------------------------------- */

  4: /*
  5:    Include files needed for the CUSP BiCGSTAB preconditioner:
  6:      pcimpl.h - private include file intended for use by all preconditioners
  7: */

  9: #include <petsc-private/pcimpl.h>   /*I "petscpc.h" I*/
 10: #include <../src/mat/impls/aij/seq/aij.h>
 11: #include <cusp/monitor.h>
 12: #include <cusp/krylov/bicgstab.h>
 13: #include <../src/vec/vec/impls/dvecimpl.h>
 14: #include <../src/mat/impls/aij/seq/seqcusp/cuspmatimpl.h>


 17: /*
 18:    Private context (data structure) for the CUSP BiCGStab preconditioner.
 19:  */
 20: typedef struct {
 21:   PetscInt   maxits;
 22:   PetscReal  rtol;
 23:   PetscBool  monitorverbose;
 24:   CUSPMATRIX * mat;
 25: } PC_BiCGStabCUSP;

 29: static PetscErrorCode PCBiCGStabCUSPSetTolerance_BiCGStabCUSP(PC pc,PetscReal rtol)
 30: {
 31:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;

 34:   bicg->rtol = rtol;
 35:   return(0);
 36: }

 40: static PetscErrorCode PCBiCGStabCUSPSetUseVerboseMonitor_BiCGStabCUSP(PC pc, PetscBool useverbose)
 41: {
 42:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;

 45:   bicg->monitorverbose = useverbose;
 46:   return(0);
 47: }

 51: PetscErrorCode PCBiCGStabCUSPSetUseVerboseMonitor(PC pc, PetscBool useverbose)
 52: {

 57:   PetscTryMethod(pc, "PCBiCGStabCUSPSetUseVerboseMonitors_C",(PC,PetscBool),(pc,useverbose));
 58:   return(0);
 59: }

 63: static PetscErrorCode PCBiCGStabCUSPSetIterations_BiCGStabCUSP(PC pc, PetscInt its)
 64: {
 65:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;

 68:   bicg->maxits = its;
 69:   return(0);
 70: }

 74: PetscErrorCode PCBiCGStabCUSPSetITerations(PC pc, PetscInt its)
 75: {

 80:   PetscTryMethod(pc, "PCBiCGStabCUSPSetIterations_C",(PC,PetscInt),(pc,its));
 81:   return(0);
 82: }

 86: PetscErrorCode PCBiCGStabCUSPSetTolerance(PC pc, PetscReal rtol)
 87: {

 92:   PetscTryMethod(pc, "PCBiCGStabCUSPSetTolerance_C",(PC,PetscReal),(pc,rtol));
 93:   return(0);
 94: }

 96: /* -------------------------------------------------------------------------- */
 97: /*
 98:    PCSetUp_BiCGStabCUSP - Prepares for the use of the CUSP BiCGStab preconditioner
 99:                     by setting data structures and options.

101:    Input Parameter:
102: .  pc - the preconditioner context

104:    Application Interface Routine: PCSetUp()

106:    Notes:
107:    The interface routine PCSetUp() is not usually called directly by
108:    the user, but instead is called by PCApply() if necessary.
109: */
112: static PetscErrorCode PCSetUp_BiCGStabCUSP(PC pc)
113: {
114:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
115:   PetscBool       flg   = PETSC_FALSE;
116:   Mat_SeqAIJCUSP  *gpustruct;
117:   PetscErrorCode  ierr;

120:   PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJCUSP,&flg);
121:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles CUSP matrices");
122:   try {
123:     MatCUSPCopyToGPU(pc->pmat);
124:     gpustruct = (Mat_SeqAIJCUSP*)(pc->pmat->spptr);
125:     bicg->mat = (CUSPMATRIX*)gpustruct->mat;
126:   } catch(char *ex) {
127:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s",ex);
128:   }
129:   return(0);
130: }

132: /* -------------------------------------------------------------------------- */
133: /*
134:    PCApply_BiCGStabCUSP - Applies the BiCGStabCUSP preconditioner to a vector.

136:    Input Parameters:
137: .  pc - the preconditioner context
138: .  x - input vector

140:    Output Parameter:
141: .  y - output vector

143:    Application Interface Routine: PCApply()
144:  */
147: static PetscErrorCode PCApply_BiCGStabCUSP(PC pc,Vec x,Vec y)
148: {
149:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
150:   PetscErrorCode  ierr;
151:   PetscBool       flg1,flg2;
152:   CUSPARRAY       *xarray=NULL,*yarray=NULL;

155:   PetscObjectTypeCompare((PetscObject)x,VECSEQCUSP,&flg1);
156:   PetscObjectTypeCompare((PetscObject)y,VECSEQCUSP,&flg2);
157:   if (!(flg1 && flg2)) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles CUSP vectors");
158:   if (!bicg->mat) {
159:     PCSetUp_BiCGStabCUSP(pc);
160:   }
161:   VecSet(y,0.0);
162:   VecCUSPGetArrayRead(x,&xarray);
163:   VecCUSPGetArrayWrite(y,&yarray);
164:   try {
165:     cusp::default_monitor<PetscReal> monitor(*xarray,bicg->maxits,bicg->rtol);
166:     if (bicg->monitorverbose) {
167:       cusp::verbose_monitor<PetscReal> verbosemonitor(*xarray,bicg->maxits,bicg->rtol);
168:       cusp::krylov::bicgstab(*bicg->mat,*yarray,*xarray,verbosemonitor);
169:     } else {
170:       cusp::krylov::bicgstab(*bicg->mat,*yarray,*xarray,monitor);
171:     }
172:   } catch(char *ex) {
173:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
174:   }
175:   VecCUSPRestoreArrayRead(x,&xarray);
176:   VecCUSPRestoreArrayWrite(y,&yarray);
177:   PetscObjectStateIncrease((PetscObject)y);
178:   return(0);
179: }
180: /* -------------------------------------------------------------------------- */
181: /*
182:    PCDestroy_BiCGStabCUSP - Destroys the private context for the BiCGStabCUSP preconditioner
183:    that was created with PCCreate_BiCGStabCUSP().

185:    Input Parameter:
186: .  pc - the preconditioner context

188:    Application Interface Routine: PCDestroy()
189: */
192: static PetscErrorCode PCDestroy_BiCGStabCUSP(PC pc)
193: {
194:   PetscErrorCode  ierr;

197:   /*
198:       Free the private data structure that was hanging off the PC
199:   */
200:   PetscFree(pc->data);
201:   return(0);
202: }

206: static PetscErrorCode PCSetFromOptions_BiCGStabCUSP(PC pc)
207: {
208:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
209:   PetscErrorCode  ierr;

212:   PetscOptionsHead("BiCGStabCUSP options");
213:   PetscOptionsReal("-pc_bicgstabcusp_rtol","relative tolerance for BiCGStabCUSP preconditioner","PCBiCGStabCUSPSetTolerance",bicg->rtol,&bicg->rtol,0);
214:   PetscOptionsInt("-pc_bicgstabcusp_max_it","maximum iterations for BiCGStabCUSP preconditioner","PCBiCGStabCUSPSetIterations",bicg->maxits,&bicg->maxits,0);
215:   PetscOptionsBool("-pc_bicgstabcusp_monitor_verbose","Print information about GPU BiCGStabCUSP iterations","PCBiCGStabCUSPSetUseVerboseMonitor",bicg->monitorverbose,&bicg->monitorverbose,0);
216:   PetscOptionsTail();
217:   return(0);
218: }

220: /* -------------------------------------------------------------------------- */

224: PETSC_EXTERN PetscErrorCode PCCreate_BiCGStabCUSP(PC pc)
225: {
226:   PC_BiCGStabCUSP *bicg;
227:   PetscErrorCode  ierr;

230:   /*
231:      Creates the private data structure for this preconditioner and
232:      attach it to the PC object.
233:    */
234:   PetscNewLog(pc,&bicg);
235:   /*
236:      Set default values.  We don't actually want to set max iterations as far as I know, but the Cusp monitor requires them so we use a large number.
237:    */
238:   bicg->maxits         = 1000;
239:   bicg->rtol           = 1.e-1;
240:   bicg->monitorverbose = PETSC_FALSE;
241:   pc->data             = (void*)bicg;
242:   /*
243:       Set the pointers for the functions that are provided above.
244:       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
245:       are called, they will automatically call these functions.  Note we
246:       choose not to provide a couple of these functions since they are
247:       not needed.
248:   */
249:   pc->ops->apply               = PCApply_BiCGStabCUSP;
250:   pc->ops->applytranspose      = 0;
251:   pc->ops->setup               = PCSetUp_BiCGStabCUSP;
252:   pc->ops->destroy             = PCDestroy_BiCGStabCUSP;
253:   pc->ops->setfromoptions      = PCSetFromOptions_BiCGStabCUSP;
254:   pc->ops->view                = 0;
255:   pc->ops->applyrichardson     = 0;
256:   pc->ops->applysymmetricleft  = 0;
257:   pc->ops->applysymmetricright = 0;

259:   PetscObjectComposeFunction((PetscObject)pc,"PCBiCGStabCUSPSetTolerance_C",PCBiCGStabCUSPSetTolerance_BiCGStabCUSP);
260:   PetscObjectComposeFunction((PetscObject)pc, "PCBiCGStabCUSPSetIterations_C",PCBiCGStabCUSPSetIterations_BiCGStabCUSP);
261:   PetscObjectComposeFunction((PetscObject)pc, "PCBiCGStabCUSPSetUseVerboseMonitor_C", PCBiCGStabCUSPSetUseVerboseMonitor_BiCGStabCUSP);
262:   return(0);
263: }