Actual source code: veccuda.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      1: /*
      2:  Implementation of the sequential cuda vectors.

      4:  This file contains the code that can be compiled with a C
      5:  compiler.  The companion file veccuda2.cu contains the code that
      6:  must be compiled with nvcc or a C++ compiler.
      7:  */

      9: #define PETSC_SKIP_SPINLOCK

     11: #include <petscconf.h>
     12: #include <petsc/private/vecimpl.h>          /*I <petscvec.h> I*/
     13: #include <../src/vec/vec/impls/dvecimpl.h>
     14: #include <../src/vec/vec/impls/seq/seqcuda/cudavecimpl.h>

     18: /*
     19:     Allocates space for the vector array on the Host if it does not exist.
     20:     Does NOT change the PetscCUDAFlag for the vector
     21:     Does NOT zero the CUDA array
     22:  */
     23: PetscErrorCode VecCUDAAllocateCheckHost(Vec v)
     24: {
     26:   PetscScalar    *array;
     27:   Vec_Seq        *s = (Vec_Seq*)v->data;
     28:   PetscInt       n = v->map->n;

     31:   if (!s) {
     32:     PetscNewLog((PetscObject)v,&s);
     33:     v->data = s;
     34:   }
     35:   if (!s->array) {
     36:     PetscMalloc1(n,&array);
     37:     PetscLogObjectMemory((PetscObject)v,n*sizeof(PetscScalar));
     38:     s->array           = array;
     39:     s->array_allocated = array;
     40:     if (v->valid_GPU_array == PETSC_CUDA_UNALLOCATED) {
     41:       v->valid_GPU_array = PETSC_CUDA_CPU;
     42:     }
     43:   }
     44:   return(0);
     45: }

     49: PetscErrorCode VecCopy_SeqCUDA_Private(Vec xin,Vec yin)
     50: {
     51:   PetscScalar       *ya;
     52:   const PetscScalar *xa;
     53:   PetscErrorCode    ierr;

     56:   VecCUDAAllocateCheckHost(xin);
     57:   VecCUDAAllocateCheckHost(yin);
     58:   if (xin != yin) {
     59:     VecGetArrayRead(xin,&xa);
     60:     VecGetArray(yin,&ya);
     61:     PetscMemcpy(ya,xa,xin->map->n*sizeof(PetscScalar));
     62:     VecRestoreArrayRead(xin,&xa);
     63:     VecRestoreArray(yin,&ya);
     64:   }
     65:   return(0);
     66: }

     70: PetscErrorCode VecSetRandom_SeqCUDA_Private(Vec xin,PetscRandom r)
     71: {
     73:   PetscInt       n = xin->map->n,i;
     74:   PetscScalar    *xx;

     77:   VecGetArray(xin,&xx);
     78:   for (i=0; i<n; i++) { PetscRandomGetValue(r,&xx[i]); }
     79:   VecRestoreArray(xin,&xx);
     80:   return(0);
     81: }

     85: PetscErrorCode VecDestroy_SeqCUDA_Private(Vec v)
     86: {
     87:   Vec_Seq        *vs = (Vec_Seq*)v->data;

     91:   PetscObjectSAWsViewOff(v);
     92: #if defined(PETSC_USE_LOG)
     93:   PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
     94: #endif
     95:   if (vs) {
     96:     if (vs->array_allocated) { PetscFree(vs->array_allocated); }
     97:     PetscFree(vs);
     98:   }
     99:   return(0);
    100: }

    104: PetscErrorCode VecResetArray_SeqCUDA_Private(Vec vin)
    105: {
    106:   Vec_Seq *v = (Vec_Seq*)vin->data;

    109:   v->array         = v->unplacedarray;
    110:   v->unplacedarray = 0;
    111:   return(0);
    112: }

    116: PetscErrorCode VecCUDAAllocateCheck_Public(Vec v)
    117: {

    121:   VecCUDAAllocateCheck(v);
    122:   return(0);
    123: }

    127: PetscErrorCode VecCUDACopyToGPU_Public(Vec v)
    128: {

    132:   VecCUDACopyToGPU(v);
    133:   return(0);
    134: }

    138: /*
    139:     VecCUDACopyToGPUSome_Public - Copies certain entries down to the GPU from the CPU of a vector

    141:    Input Parameters:
    142: .    v - the vector
    143: .    indices - the requested indices, this should be created with CUDAIndicesCreate()

    145: */
    146: PetscErrorCode VecCUDACopyToGPUSome_Public(Vec v,PetscCUDAIndices ci)
    147: {

    151:   VecCUDACopyToGPUSome(v,ci);
    152:   return(0);
    153: }

    157: /*
    158:   VecCUDACopyFromGPUSome_Public - Copies certain entries up to the CPU from the GPU of a vector

    160:   Input Parameters:
    161:  +    v - the vector
    162:  -    indices - the requested indices, this should be created with CUDAIndicesCreate()
    163: */
    164: PetscErrorCode VecCUDACopyFromGPUSome_Public(Vec v,PetscCUDAIndices ci)
    165: {

    169:   VecCUDACopyFromGPUSome(v,ci);
    170:   return(0);
    171: }

    175: PetscErrorCode VecSetRandom_SeqCUDA(Vec xin,PetscRandom r)
    176: {

    180:   VecSetRandom_SeqCUDA_Private(xin,r);
    181:   xin->valid_GPU_array = PETSC_CUDA_CPU;
    182:   return(0);
    183: }

    187: PetscErrorCode VecResetArray_SeqCUDA(Vec vin)
    188: {

    192:   VecCUDACopyFromGPU(vin);
    193:   VecResetArray_SeqCUDA_Private(vin);
    194:   vin->valid_GPU_array = PETSC_CUDA_CPU;
    195:   return(0);
    196: }

    200: PetscErrorCode VecPlaceArray_SeqCUDA(Vec vin,const PetscScalar *a)
    201: {

    205:   VecCUDACopyFromGPU(vin);
    206:   VecPlaceArray_Seq(vin,a);
    207:   vin->valid_GPU_array = PETSC_CUDA_CPU;
    208:   return(0);
    209: }

    213: PetscErrorCode VecReplaceArray_SeqCUDA(Vec vin,const PetscScalar *a)
    214: {

    218:   VecCUDACopyFromGPU(vin);
    219:   VecReplaceArray_Seq(vin,a);
    220:   vin->valid_GPU_array = PETSC_CUDA_CPU;
    221:   return(0);
    222: }

    226: /*@
    227:  VecCreateSeqCUDA - Creates a standard, sequential array-style vector.

    229:  Collective on MPI_Comm

    231:  Input Parameter:
    232:  .  comm - the communicator, should be PETSC_COMM_SELF
    233:  .  n - the vector length

    235:  Output Parameter:
    236:  .  V - the vector

    238:  Notes:
    239:  Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
    240:  same type as an existing vector.

    242:  Level: intermediate

    244:  Concepts: vectors^creating sequential

    246:  .seealso: VecCreateMPI(), VecCreate(), VecDuplicate(), VecDuplicateVecs(), VecCreateGhost()
    247:  @*/
    248: PetscErrorCode VecCreateSeqCUDA(MPI_Comm comm,PetscInt n,Vec *v)
    249: {

    253:   VecCreate(comm,v);
    254:   VecSetSizes(*v,n,n);
    255:   VecSetType(*v,VECSEQCUDA);
    256:   return(0);
    257: }

    261: PetscErrorCode VecDuplicate_SeqCUDA(Vec win,Vec *V)
    262: {

    266:   VecCreateSeqCUDA(PetscObjectComm((PetscObject)win),win->map->n,V);
    267:   PetscLayoutReference(win->map,&(*V)->map);
    268:   PetscObjectListDuplicate(((PetscObject)win)->olist,&((PetscObject)(*V))->olist);
    269:   PetscFunctionListDuplicate(((PetscObject)win)->qlist,&((PetscObject)(*V))->qlist);
    270:   (*V)->stash.ignorenegidx = win->stash.ignorenegidx;
    271:   return(0);
    272: }

    276: PETSC_EXTERN PetscErrorCode VecCreate_SeqCUDA(Vec V)
    277: {
    279:   PetscMPIInt    size;

    282:   MPI_Comm_size(PetscObjectComm((PetscObject)V),&size);
    283:   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot create VECSEQCUDA on more than one process");
    284:   VecCreate_Seq_Private(V,0);
    285:   PetscObjectChangeTypeName((PetscObject)V,VECSEQCUDA);

    287:   V->ops->dot                    = VecDot_SeqCUDA;
    288:   V->ops->norm                   = VecNorm_SeqCUDA;
    289:   V->ops->tdot                   = VecTDot_SeqCUDA;
    290:   V->ops->scale                  = VecScale_SeqCUDA;
    291:   V->ops->copy                   = VecCopy_SeqCUDA;
    292:   V->ops->set                    = VecSet_SeqCUDA;
    293:   V->ops->swap                   = VecSwap_SeqCUDA;
    294:   V->ops->axpy                   = VecAXPY_SeqCUDA;
    295:   V->ops->axpby                  = VecAXPBY_SeqCUDA;
    296:   V->ops->axpbypcz               = VecAXPBYPCZ_SeqCUDA;
    297:   V->ops->pointwisemult          = VecPointwiseMult_SeqCUDA;
    298:   V->ops->pointwisedivide        = VecPointwiseDivide_SeqCUDA;
    299:   V->ops->setrandom              = VecSetRandom_SeqCUDA;
    300:   V->ops->dot_local              = VecDot_SeqCUDA;
    301:   V->ops->tdot_local             = VecTDot_SeqCUDA;
    302:   V->ops->norm_local             = VecNorm_SeqCUDA;
    303:   V->ops->mdot_local             = VecMDot_SeqCUDA;
    304:   V->ops->maxpy                  = VecMAXPY_SeqCUDA;
    305:   V->ops->mdot                   = VecMDot_SeqCUDA;
    306:   V->ops->aypx                   = VecAYPX_SeqCUDA;
    307:   V->ops->waxpy                  = VecWAXPY_SeqCUDA;
    308:   V->ops->dotnorm2               = VecDotNorm2_SeqCUDA;
    309:   V->ops->placearray             = VecPlaceArray_SeqCUDA;
    310:   V->ops->replacearray           = VecReplaceArray_SeqCUDA;
    311:   V->ops->resetarray             = VecResetArray_SeqCUDA;
    312:   V->ops->destroy                = VecDestroy_SeqCUDA;
    313:   V->ops->duplicate              = VecDuplicate_SeqCUDA;
    314:   V->ops->conjugate              = VecConjugate_SeqCUDA;
    315:   V->ops->getlocalvector         = VecGetLocalVector_SeqCUDA;
    316:   V->ops->restorelocalvector     = VecRestoreLocalVector_SeqCUDA;
    317:   V->ops->getlocalvectorread     = VecGetLocalVector_SeqCUDA;
    318:   V->ops->restorelocalvectorread = VecRestoreLocalVector_SeqCUDA;

    320:   VecCUDAAllocateCheck(V);
    321:   V->valid_GPU_array = PETSC_CUDA_GPU;
    322:   VecSet(V,0.0);
    323:   return(0);
    324: }