Actual source code: sacusppoly.cu
petsc-3.7.1 2016-05-15
Report Typos and Errors

      2: /*  -------------------------------------------------------------------- */

      4: /*
      5:    Include files needed for the CUSP Smoothed Aggregation preconditioner with Chebyshev polynomial smoothing:
      6:      pcimpl.h - private include file intended for use by all preconditioners
      7: */
      8: #define PETSC_SKIP_SPINLOCK
      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/version.h>
     13: #define USE_POLY_SMOOTHER 1
     14: #if CUSP_VERSION >= 400
     15: #include <cusp/precond/aggregation/smoothed_aggregation.h>
     16: #define cuspsaprecond cusp::precond::aggregation::smoothed_aggregation<PetscInt,PetscScalar,cusp::device_memory>
     17: #else
     18: #include <cusp/precond/smoothed_aggregation.h>
     19: #define cuspsaprecond cusp::precond::smoothed_aggregation<PetscInt,PetscScalar,cusp::device_memory>
     20: #endif
     21: #undef USE_POLY_SMOOTHER
     22: #include <../src/vec/vec/impls/dvecimpl.h>
     23: #include <../src/mat/impls/aij/seq/seqcusp/cuspmatimpl.h>
     24: #include <../src/vec/vec/impls/seq/seqcusp/cuspvecimpl.h>

     26: /*
     27:    Private context (data structure) for the SACUSPPoly preconditioner.
     28: */
     29: typedef struct {
     30:   cuspsaprecond * SACUSPPoly;
     31:   /*int cycles; */
     32: } PC_SACUSPPoly;

     35: /* -------------------------------------------------------------------------- */
     36: /*
     37:    PCSetUp_SACUSPPoly - Prepares for the use of the SACUSPPoly preconditioner
     38:                     by setting data structures and options.

     40:    Input Parameter:
     41: .  pc - the preconditioner context

     43:    Application Interface Routine: PCSetUp()

     45:    Notes:
     46:    The interface routine PCSetUp() is not usually called directly by
     47:    the user, but instead is called by PCApply() if necessary.
     48: */
     51: static PetscErrorCode PCSetUp_SACUSPPoly(PC pc)
     52: {
     53:   PC_SACUSPPoly  *sa = (PC_SACUSPPoly*)pc->data;
     54:   PetscBool      flg = PETSC_FALSE;
     56: #if !defined(PETSC_USE_COMPLEX)
     57:   // protect these in order to avoid compiler warnings. This preconditioner does
     58:   // not work for complex types.
     59:   Mat_SeqAIJCUSP *gpustruct;
     60: #endif
     62:   PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJCUSP,&flg);
     63:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only handles CUSP matrices");
     64:   if (pc->setupcalled != 0) {
     65:     try {
     66:       delete sa->SACUSPPoly;
     67:     } catch(char *ex) {
     68:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
     69:     }
     70:   }
     71:   try {
     72: #if defined(PETSC_USE_COMPLEX)
     73:     sa->SACUSPPoly = 0;CHKERRQ(1); /* TODO */
     74: #else
     75:     MatCUSPCopyToGPU(pc->pmat);
     76:     gpustruct = (Mat_SeqAIJCUSP*)(pc->pmat->spptr);
     77:
     78:     if (gpustruct->format==MAT_CUSP_ELL) {
     79:       CUSPMATRIXELL *mat = (CUSPMATRIXELL*)gpustruct->mat;
     80:       sa->SACUSPPoly = new cuspsaprecond(*mat);
     81:     } else if (gpustruct->format==MAT_CUSP_DIA) {
     82:       CUSPMATRIXDIA *mat = (CUSPMATRIXDIA*)gpustruct->mat;
     83:       sa->SACUSPPoly = new cuspsaprecond(*mat);
     84:     } else {
     85:       CUSPMATRIX *mat = (CUSPMATRIX*)gpustruct->mat;
     86:       sa->SACUSPPoly = new cuspsaprecond(*mat);
     87:     }
     88: #endif
     89:   } catch(char *ex) {
     90:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
     91:   }
     92:   /*PetscOptionsInt("-pc_sacusp_cycles","Number of v-cycles to perform","PCSACUSPSetCycles",sa->cycles,
     93:     &sa->cycles,NULL);*/
     94:   return(0);
     95: }

     99: static PetscErrorCode PCApplyRichardson_SACUSPPoly(PC pc, Vec b, Vec y, Vec w,PetscReal rtol, PetscReal abstol, PetscReal dtol, PetscInt its, PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
    100: {
    101: #if !defined(PETSC_USE_COMPLEX)
    102:   // protect these in order to avoid compiler warnings. This preconditioner does
    103:   // not work for complex types.
    104:   PC_SACUSPPoly *sac = (PC_SACUSPPoly*)pc->data;
    105: #endif
    107:   CUSPARRAY      *barray,*yarray;

    110:   /* how to incorporate dtol, guesszero, w?*/
    112:   VecCUSPGetArrayRead(b,&barray);
    113:   VecCUSPGetArrayReadWrite(y,&yarray);
    114: #if defined(CUSP_VERSION) && CUSP_VERSION >= 500
    115:   cusp::monitor<PetscReal> monitor(*barray,its,rtol,abstol);
    116: #else
    117:   cusp::default_monitor<PetscReal> monitor(*barray,its,rtol,abstol);
    118: #endif
    119: #if defined(PETSC_USE_COMPLEX)
    120:   CHKERRQ(1); /* TODO */
    121: #else
    122:   sac->SACUSPPoly->solve(*barray,*yarray,monitor);
    123: #endif
    124:   *outits = monitor.iteration_count();
    125:   if (monitor.converged()) *reason = PCRICHARDSON_CONVERGED_RTOL; /* how to discern between converging from RTOL or ATOL?*/
    126:   else *reason = PCRICHARDSON_CONVERGED_ITS;

    128:   PetscObjectStateIncrease((PetscObject)y);
    129:   VecCUSPRestoreArrayRead(b,&barray);
    130:   VecCUSPRestoreArrayReadWrite(y,&yarray);
    131:   return(0);
    132: }

    134: /* -------------------------------------------------------------------------- */
    135: /*
    136:    PCApply_SACUSPPoly - Applies the SACUSPPoly preconditioner to a vector.

    138:    Input Parameters:
    139: .  pc - the preconditioner context
    140: .  x - input vector

    142:    Output Parameter:
    143: .  y - output vector

    145:    Application Interface Routine: PCApply()
    146:  */
    149: static PetscErrorCode PCApply_SACUSPPoly(PC pc,Vec x,Vec y)
    150: {
    151:   PC_SACUSPPoly  *sac = (PC_SACUSPPoly*)pc->data;
    153:   PetscBool      flg1,flg2;
    154:   CUSPARRAY      *xarray=NULL,*yarray=NULL;

    157:   /*how to apply a certain fixed number of iterations?*/
    158:   PetscObjectTypeCompare((PetscObject)x,VECSEQCUSP,&flg1);
    159:   PetscObjectTypeCompare((PetscObject)y,VECSEQCUSP,&flg2);
    160:   if (!(flg1 && flg2)) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP, "Currently only handles CUSP vectors");
    161:   if (!sac->SACUSPPoly) {
    162:     PCSetUp_SACUSPPoly(pc);
    163:   }
    164:   VecSet(y,0.0);
    165:   VecCUSPGetArrayRead(x,&xarray);
    166:   VecCUSPGetArrayWrite(y,&yarray);
    167:   try {
    168: #if defined(PETSC_USE_COMPLEX)
    169:     CHKERRQ(1); /* TODO */
    170: #else
    171:     cusp::multiply(*sac->SACUSPPoly,*xarray,*yarray);
    172: #endif
    173:   } catch(char *ex) {
    174:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
    175:   }
    176:   VecCUSPRestoreArrayRead(x,&xarray);
    177:   VecCUSPRestoreArrayWrite(y,&yarray);
    178:   PetscObjectStateIncrease((PetscObject)y);
    179:   return(0);
    180: }
    181: /* -------------------------------------------------------------------------- */
    182: /*
    183:    PCDestroy_SACUSPPoly - Destroys the private context for the SACUSPPoly preconditioner
    184:    that was created with PCCreate_SACUSPPoly().

    186:    Input Parameter:
    187: .  pc - the preconditioner context

    189:    Application Interface Routine: PCDestroy()
    190: */
    193: static PetscErrorCode PCDestroy_SACUSPPoly(PC pc)
    194: {
    195:   PC_SACUSPPoly  *sac = (PC_SACUSPPoly*)pc->data;

    199:   if (sac->SACUSPPoly) {
    200:     try {
    201:       delete sac->SACUSPPoly;
    202:     } catch(char *ex) {
    203:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"CUSP error: %s", ex);
    204:     }
    205:   }

    207:   /*
    208:       Free the private data structure that was hanging off the PC
    209:   */
    210:   PetscFree(sac);
    211:   return(0);
    212: }

    216: static PetscErrorCode PCSetFromOptions_SACUSPPoly(PetscOptionItems *PetscOptionsObject,PC pc)
    217: {

    221:   PetscOptionsHead(PetscOptionsObject,"SACUSPPoly options");
    222:   PetscOptionsTail();
    223:   return(0);
    224: }

    226: /* -------------------------------------------------------------------------- */

    230: PETSC_EXTERN PetscErrorCode PCCreate_SACUSPPoly(PC pc)
    231: {
    232:   PC_SACUSPPoly  *sac;

    236:   /*
    237:      Creates the private data structure for this preconditioner and
    238:      attach it to the PC object.
    239:   */
    240:   PetscNewLog(pc,&sac);
    241:   pc->data = (void*)sac;

    243:   /*
    244:      Initialize the pointer to zero
    245:      Initialize number of v-cycles to default (1)
    246:   */
    247:   sac->SACUSPPoly = 0;
    248:   /*sac->cycles=1;*/

    251:   /*
    252:       Set the pointers for the functions that are provided above.
    253:       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
    254:       are called, they will automatically call these functions.  Note we
    255:       choose not to provide a couple of these functions since they are
    256:       not needed.
    257:   */
    258:   pc->ops->apply               = PCApply_SACUSPPoly;
    259:   pc->ops->applytranspose      = 0;
    260:   pc->ops->setup               = PCSetUp_SACUSPPoly;
    261:   pc->ops->destroy             = PCDestroy_SACUSPPoly;
    262:   pc->ops->setfromoptions      = PCSetFromOptions_SACUSPPoly;
    263:   pc->ops->view                = 0;
    264:   pc->ops->applyrichardson     = PCApplyRichardson_SACUSPPoly;
    265:   pc->ops->applysymmetricleft  = 0;
    266:   pc->ops->applysymmetricright = 0;
    267:   return(0);
    268: }