Actual source code: bicgstabcusp.cu
petsc-3.8.4 2018-03-24
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: }