Date: 2013-07-02T14:47:20+00:00

Actual source code: bicgstabcusp.cu
petsc-3.4.2 2013-07-02

      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,PC_BiCGStabCUSP,&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: }