Actual source code: bicgstabcusp.cu
petsc-3.5.4 2015-05-23
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: }