Actual source code: bicgstabcusp.cu

petsc-3.8.4 2018-03-24
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: */
  8: #define PETSC_SKIP_SPINLOCK

 10:  #include <petsc/private/pcimpl.h>
 11:  #include <../src/mat/impls/aij/seq/aij.h>
 12: #include <cusp/monitor.h>
 13: #include <cusp/krylov/bicgstab.h>
 14:  #include <../src/vec/vec/impls/dvecimpl.h>
 15:  #include <../src/mat/impls/aij/seq/seqcusp/cuspmatimpl.h>
 16:  #include <../src/vec/vec/impls/seq/seqcusp/cuspvecimpl.h>

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

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

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

 37: static PetscErrorCode PCBiCGStabCUSPSetUseVerboseMonitor_BiCGStabCUSP(PC pc, PetscBool useverbose)
 38: {
 39:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;

 42:   bicg->monitorverbose = useverbose;
 43:   return(0);
 44: }

 46: PetscErrorCode PCBiCGStabCUSPSetUseVerboseMonitor(PC pc, PetscBool useverbose)
 47: {

 52:   PetscTryMethod(pc, "PCBiCGStabCUSPSetUseVerboseMonitors_C",(PC,PetscBool),(pc,useverbose));
 53:   return(0);
 54: }

 56: static PetscErrorCode PCBiCGStabCUSPSetIterations_BiCGStabCUSP(PC pc, PetscInt its)
 57: {
 58:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;

 61:   bicg->maxits = its;
 62:   return(0);
 63: }

 65: PetscErrorCode PCBiCGStabCUSPSetITerations(PC pc, PetscInt its)
 66: {

 71:   PetscTryMethod(pc, "PCBiCGStabCUSPSetIterations_C",(PC,PetscInt),(pc,its));
 72:   return(0);
 73: }

 75: PetscErrorCode PCBiCGStabCUSPSetTolerance(PC pc, PetscReal rtol)
 76: {

 81:   PetscTryMethod(pc, "PCBiCGStabCUSPSetTolerance_C",(PC,PetscReal),(pc,rtol));
 82:   return(0);
 83: }

 85: /* -------------------------------------------------------------------------- */
 86: /*
 87:    PCSetUp_BiCGStabCUSP - Prepares for the use of the CUSP BiCGStab preconditioner
 88:                     by setting data structures and options.

 90:    Input Parameter:
 91: .  pc - the preconditioner context

 93:    Application Interface Routine: PCSetUp()

 95:    Notes:
 96:    The interface routine PCSetUp() is not usually called directly by
 97:    the user, but instead is called by PCApply() if necessary.
 98: */

100: static PetscErrorCode PCSetUp_BiCGStabCUSP(PC pc)
101: {
102:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
103:   PetscBool       flg   = PETSC_FALSE;
104:   Mat_SeqAIJCUSP  *gpustruct;
105:   PetscErrorCode  ierr;

108:   PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJCUSP,&flg);
109:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles SEQAIJCUSP matrices");
110:   try {
111:     MatCUSPCopyToGPU(pc->pmat);
112:     gpustruct = (Mat_SeqAIJCUSP*)(pc->pmat->spptr);
113:     bicg->mat = (CUSPMATRIX*)gpustruct->mat;
114:   } catch(char *ex) {
115:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s",ex);
116:   }
117:   return(0);
118: }

120: /* -------------------------------------------------------------------------- */
121: /*
122:    PCApply_BiCGStabCUSP - Applies the BiCGStabCUSP preconditioner to a vector.

124:    Input Parameters:
125: .  pc - the preconditioner context
126: .  x - input vector

128:    Output Parameter:
129: .  y - output vector

131:    Application Interface Routine: PCApply()
132:  */

134: static PetscErrorCode PCApply_BiCGStabCUSP(PC pc,Vec x,Vec y)
135: {
136:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
137:   PetscErrorCode  ierr;
138:   PetscBool       flg1,flg2;
139:   CUSPARRAY       *xarray=NULL,*yarray=NULL;

142:   PetscObjectTypeCompare((PetscObject)x,VECSEQCUSP,&flg1);
143:   PetscObjectTypeCompare((PetscObject)y,VECSEQCUSP,&flg2);
144:   if (!(flg1 && flg2)) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles CUSP vectors");
145:   if (!bicg->mat) {
146:     PCSetUp_BiCGStabCUSP(pc);
147:   }
148:   VecSet(y,0.0);
149:   VecCUSPGetArrayRead(x,&xarray);
150:   VecCUSPGetArrayWrite(y,&yarray);
151:   try {
152: #if defined(CUSP_VERSION) && CUSP_VERSION >= 500
153:     cusp::monitor<PetscReal> monitor(*xarray,bicg->maxits,bicg->rtol);
154:     cusp::krylov::bicgstab(*bicg->mat,*yarray,*xarray,monitor);
155: #else
156:     cusp::default_monitor<PetscReal> monitor(*xarray,bicg->maxits,bicg->rtol);
157:     if (bicg->monitorverbose) {
158:       cusp::verbose_monitor<PetscReal> verbosemonitor(*xarray,bicg->maxits,bicg->rtol);
159:       cusp::krylov::bicgstab(*bicg->mat,*yarray,*xarray,verbosemonitor);
160:     } else {
161:       cusp::krylov::bicgstab(*bicg->mat,*yarray,*xarray,monitor);
162:     }
163: #endif
164:   } catch(char *ex) {
165:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
166:   }
167:   VecCUSPRestoreArrayRead(x,&xarray);
168:   VecCUSPRestoreArrayWrite(y,&yarray);
169:   PetscObjectStateIncrease((PetscObject)y);
170:   return(0);
171: }
172: /* -------------------------------------------------------------------------- */
173: /*
174:    PCDestroy_BiCGStabCUSP - Destroys the private context for the BiCGStabCUSP preconditioner
175:    that was created with PCCreate_BiCGStabCUSP().

177:    Input Parameter:
178: .  pc - the preconditioner context

180:    Application Interface Routine: PCDestroy()
181: */

183: static PetscErrorCode PCDestroy_BiCGStabCUSP(PC pc)
184: {
185:   PetscErrorCode  ierr;

188:   /*
189:       Free the private data structure that was hanging off the PC
190:   */
191:   PetscFree(pc->data);
192:   return(0);
193: }

195: static PetscErrorCode PCSetFromOptions_BiCGStabCUSP(PetscOptionItems *PetscOptionsObject,PC pc)
196: {
197:   PC_BiCGStabCUSP *bicg = (PC_BiCGStabCUSP*)pc->data;
198:   PetscErrorCode  ierr;

201:   PetscOptionsHead(PetscOptionsObject,"BiCGStabCUSP options");
202:   PetscOptionsReal("-pc_bicgstabcusp_rtol","relative tolerance for BiCGStabCUSP preconditioner","PCBiCGStabCUSPSetTolerance",bicg->rtol,&bicg->rtol,0);
203:   PetscOptionsInt("-pc_bicgstabcusp_max_it","maximum iterations for BiCGStabCUSP preconditioner","PCBiCGStabCUSPSetIterations",bicg->maxits,&bicg->maxits,0);
204:   PetscOptionsBool("-pc_bicgstabcusp_monitor_verbose","Print information about GPU BiCGStabCUSP iterations","PCBiCGStabCUSPSetUseVerboseMonitor",bicg->monitorverbose,&bicg->monitorverbose,0);
205:   PetscOptionsTail();
206:   return(0);
207: }

209: /* -------------------------------------------------------------------------- */

211: PETSC_EXTERN PetscErrorCode PCCreate_BiCGStabCUSP(PC pc)
212: {
213:   PC_BiCGStabCUSP *bicg;
214:   PetscErrorCode  ierr;

217:   /*
218:      Creates the private data structure for this preconditioner and
219:      attach it to the PC object.
220:    */
221:   PetscNewLog(pc,&bicg);
222:   /*
223:      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.
224:    */
225:   bicg->maxits         = 1000;
226:   bicg->rtol           = 1.e-1;
227:   bicg->monitorverbose = PETSC_FALSE;
228:   pc->data             = (void*)bicg;
229:   /*
230:       Set the pointers for the functions that are provided above.
231:       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
232:       are called, they will automatically call these functions.  Note we
233:       choose not to provide a couple of these functions since they are
234:       not needed.
235:   */
236:   pc->ops->apply               = PCApply_BiCGStabCUSP;
237:   pc->ops->applytranspose      = 0;
238:   pc->ops->setup               = PCSetUp_BiCGStabCUSP;
239:   pc->ops->destroy             = PCDestroy_BiCGStabCUSP;
240:   pc->ops->setfromoptions      = PCSetFromOptions_BiCGStabCUSP;
241:   pc->ops->view                = 0;
242:   pc->ops->applyrichardson     = 0;
243:   pc->ops->applysymmetricleft  = 0;
244:   pc->ops->applysymmetricright = 0;

246:   PetscObjectComposeFunction((PetscObject)pc,"PCBiCGStabCUSPSetTolerance_C",PCBiCGStabCUSPSetTolerance_BiCGStabCUSP);
247:   PetscObjectComposeFunction((PetscObject)pc, "PCBiCGStabCUSPSetIterations_C",PCBiCGStabCUSPSetIterations_BiCGStabCUSP);
248:   PetscObjectComposeFunction((PetscObject)pc, "PCBiCGStabCUSPSetUseVerboseMonitor_C", PCBiCGStabCUSPSetUseVerboseMonitor_BiCGStabCUSP);
249:   return(0);
250: }