Actual source code: sacusp.cu
2: /* -------------------------------------------------------------------- */
4: /*
5: Include files needed for the CUSP Smoothed Aggregation preconditioner:
6: pcimpl.h - private include file intended for use by all preconditioners
7: */
9: #include <private/pcimpl.h> /*I "petscpc.h" I*/
10: #include <../src/mat/impls/aij/seq/aij.h>
11: #include <cusp/monitor.h>
12: #undef VecType
13: #include <cusp/precond/smoothed_aggregation.h>
14: #define VecType char*
15: #include <../src/vec/vec/impls/dvecimpl.h>
16: #include <../src/mat/impls/aij/seq/seqcusp/cuspmatimpl.h>
18: #define cuspsaprecond cusp::precond::smoothed_aggregation<PetscInt,PetscScalar,cusp::device_memory>
20: /*
21: Private context (data structure) for the SACUSP preconditioner.
22: */
23: typedef struct {
24: cuspsaprecond* SACUSP;
25: /*int cycles; */
26: } PC_SACUSP;
30: static PetscErrorCode PCSACUSPSetCycles(PC pc, int n)
31: {
32: PC_SACUSP *sac = (PC_SACUSP*)pc->data;
35: sac->cycles = n;
36: return(0);
38: }*/
40: /* -------------------------------------------------------------------------- */
41: /*
42: PCSetUp_SACUSP - Prepares for the use of the SACUSP preconditioner
43: by setting data structures and options.
45: Input Parameter:
46: . pc - the preconditioner context
48: Application Interface Routine: PCSetUp()
50: Notes:
51: The interface routine PCSetUp() is not usually called directly by
52: the user, but instead is called by PCApply() if necessary.
53: */
56: static PetscErrorCode PCSetUp_SACUSP(PC pc)
57: {
58: PC_SACUSP *sa = (PC_SACUSP*)pc->data;
59: PetscBool flg = PETSC_FALSE;
61: Mat_SeqAIJCUSP *gpustruct;
64: PetscTypeCompare((PetscObject)pc->pmat,MATSEQAIJCUSP,&flg);
65: if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Currently only handles CUSP matrices");
66: if (pc->setupcalled != 0){
67: try {
68: delete sa->SACUSP;
69: } catch(char* ex) {
70: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
71: }
72: }
73: try {
74: MatCUSPCopyToGPU(pc->pmat);CHKERRCUSP(ierr);
75: gpustruct = (Mat_SeqAIJCUSP *)(pc->pmat->spptr);
76: sa->SACUSP = new cuspsaprecond(*(CUSPMATRIX*)gpustruct->mat);
77: } catch(char* ex) {
78: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
79: }
80: /*PetscOptionsInt("-pc_sacusp_cycles","Number of v-cycles to perform","PCSACUSPSetCycles",sa->cycles,
81: &sa->cycles,PETSC_NULL);*/
82: return(0);
83: }
87: static PetscErrorCode PCApplyRichardson_SACUSP(PC pc, Vec b, Vec y, Vec w,PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt its, PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
88: {
89: PC_SACUSP *sac = (PC_SACUSP*)pc->data;
91: CUSPARRAY *barray,*yarray;
94: /* how to incorporate dtol, guesszero, w?*/
96: VecCUSPGetArrayRead(b,&barray);
97: VecCUSPGetArrayReadWrite(y,&yarray);
98: cusp::default_monitor<PetscScalar> monitor(*barray,its,rtol,abstol);
99: sac->SACUSP->solve(*barray,*yarray,monitor);
100: *outits = monitor.iteration_count();
101: if (monitor.converged()){
102: /* how to discern between converging from RTOL or ATOL?*/
103: *reason = PCRICHARDSON_CONVERGED_RTOL;
104: } else{
105: *reason = PCRICHARDSON_CONVERGED_ITS;
106: }
107: PetscObjectStateIncrease((PetscObject)y);
108: VecCUSPRestoreArrayRead(b,&barray);
109: VecCUSPRestoreArrayReadWrite(y,&yarray);
110: return(0);
111: }
113: /* -------------------------------------------------------------------------- */
114: /*
115: PCApply_SACUSP - Applies the SACUSP preconditioner to a vector.
117: Input Parameters:
118: . pc - the preconditioner context
119: . x - input vector
121: Output Parameter:
122: . y - output vector
124: Application Interface Routine: PCApply()
125: */
128: static PetscErrorCode PCApply_SACUSP(PC pc,Vec x,Vec y)
129: {
130: PC_SACUSP *sac = (PC_SACUSP*)pc->data;
132: PetscBool flg1,flg2;
133: CUSPARRAY *xarray,*yarray;
136: /*how to apply a certain fixed number of iterations?*/
137: PetscTypeCompare((PetscObject)x,VECSEQCUSP,&flg1);
138: PetscTypeCompare((PetscObject)y,VECSEQCUSP,&flg2);
139: if (!(flg1 && flg2)) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP, "Currently only handles CUSP vectors");
140: if (!sac->SACUSP) {
141: PCSetUp_SACUSP(pc);
142: }
143: VecSet(y,0.0);
144: VecCUSPGetArrayRead(x,&xarray);
145: VecCUSPGetArrayWrite(y,&yarray);
146: try {
147: cusp::multiply(*sac->SACUSP,*xarray,*yarray);
148: } catch(char* ex) {
149: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
150: }
151: VecCUSPRestoreArrayRead(x,&xarray);
152: VecCUSPRestoreArrayWrite(y,&yarray);
153: PetscObjectStateIncrease((PetscObject)y);
154: return(0);
155: }
156: /* -------------------------------------------------------------------------- */
157: /*
158: PCDestroy_SACUSP - Destroys the private context for the SACUSP preconditioner
159: that was created with PCCreate_SACUSP().
161: Input Parameter:
162: . pc - the preconditioner context
164: Application Interface Routine: PCDestroy()
165: */
168: static PetscErrorCode PCDestroy_SACUSP(PC pc)
169: {
170: PC_SACUSP *sac = (PC_SACUSP*)pc->data;
174: if (sac->SACUSP) {
175: try {
176: delete sac->SACUSP;
177: } catch(char* ex) {
178: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
179: }
180: }
182: /*
183: Free the private data structure that was hanging off the PC
184: */
185: PetscFree(pc->data);
186: return(0);
187: }
191: static PetscErrorCode PCSetFromOptions_SACUSP(PC pc)
192: {
196: PetscOptionsHead("SACUSP options");
197: PetscOptionsTail();
198: return(0);
199: }
201: /* -------------------------------------------------------------------------- */
208: PetscErrorCode PCCreate_SACUSP(PC pc)
209: {
210: PC_SACUSP *sac;
214: /*
215: Creates the private data structure for this preconditioner and
216: attach it to the PC object.
217: */
218: PetscNewLog(pc,PC_SACUSP,&sac);
219: pc->data = (void*)sac;
221: /*
222: Initialize the pointer to zero
223: Initialize number of v-cycles to default (1)
224: */
225: sac->SACUSP = 0;
226: /*sac->cycles=1;*/
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_SACUSP;
237: pc->ops->applytranspose = 0;
238: pc->ops->setup = PCSetUp_SACUSP;
239: pc->ops->destroy = PCDestroy_SACUSP;
240: pc->ops->setfromoptions = PCSetFromOptions_SACUSP;
241: pc->ops->view = 0;
242: pc->ops->applyrichardson = PCApplyRichardson_SACUSP;
243: pc->ops->applysymmetricleft = 0;
244: pc->ops->applysymmetricright = 0;
245: return(0);
246: }