Actual source code: vector.c

      1: /*
      2:      Provides the interface functions for vector operations that do NOT have PetscScalar/PetscReal in the signature
      3:    These are the vector functions the user calls.
      4: */
      5: #include <petsc/private/vecimpl.h>

      7: /* Logging support */
      8: PetscClassId  VEC_CLASSID;
      9: PetscLogEvent VEC_View, VEC_Max, VEC_Min, VEC_Dot, VEC_MDot, VEC_TDot;
     10: PetscLogEvent VEC_Norm, VEC_Normalize, VEC_Scale, VEC_Copy, VEC_Set, VEC_AXPY, VEC_AYPX, VEC_WAXPY;
     11: PetscLogEvent VEC_MTDot, VEC_MAXPY, VEC_Swap, VEC_AssemblyBegin, VEC_ScatterBegin, VEC_ScatterEnd;
     12: PetscLogEvent VEC_AssemblyEnd, VEC_PointwiseMult, VEC_SetValues, VEC_Load;
     13: PetscLogEvent VEC_SetRandom, VEC_ReduceArithmetic, VEC_ReduceCommunication,VEC_ReduceBegin,VEC_ReduceEnd,VEC_Ops;
     14: PetscLogEvent VEC_DotNorm2, VEC_AXPBYPCZ;
     15: PetscLogEvent VEC_ViennaCLCopyFromGPU, VEC_ViennaCLCopyToGPU;
     16: PetscLogEvent VEC_CUDACopyFromGPU, VEC_CUDACopyToGPU;
     17: PetscLogEvent VEC_CUDACopyFromGPUSome, VEC_CUDACopyToGPUSome;
     18: PetscLogEvent VEC_HIPCopyFromGPU, VEC_HIPCopyToGPU;
     19: PetscLogEvent VEC_HIPCopyFromGPUSome, VEC_HIPCopyToGPUSome;

     21: /*@
     22:    VecStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
     23:        to be communicated to other processors during the VecAssemblyBegin/End() process

     25:     Not collective

     27:    Input Parameter:
     28: .   vec - the vector

     30:    Output Parameters:
     31: +   nstash   - the size of the stash
     32: .   reallocs - the number of additional mallocs incurred.
     33: .   bnstash   - the size of the block stash
     34: -   breallocs - the number of additional mallocs incurred.in the block stash

     36:    Level: advanced

     38: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), Vec, VecStashSetInitialSize(), VecStashView()

     40: @*/
     41: PetscErrorCode  VecStashGetInfo(Vec vec,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
     42: {
     43:   VecStashGetInfo_Private(&vec->stash,nstash,reallocs);
     44:   VecStashGetInfo_Private(&vec->bstash,bnstash,breallocs);
     45:   return 0;
     46: }

     48: /*@
     49:    VecSetLocalToGlobalMapping - Sets a local numbering to global numbering used
     50:    by the routine VecSetValuesLocal() to allow users to insert vector entries
     51:    using a local (per-processor) numbering.

     53:    Logically Collective on Vec

     55:    Input Parameters:
     56: +  x - vector
     57: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()

     59:    Notes:
     60:    All vectors obtained with VecDuplicate() from this vector inherit the same mapping.

     62:    Level: intermediate

     64: seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesLocal(),
     65:            VecSetLocalToGlobalMapping(), VecSetValuesBlockedLocal()
     66: @*/
     67: PetscErrorCode  VecSetLocalToGlobalMapping(Vec x,ISLocalToGlobalMapping mapping)
     68: {
     71:   if (x->ops->setlocaltoglobalmapping) {
     72:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
     73:   } else {
     74:     PetscLayoutSetISLocalToGlobalMapping(x->map,mapping);
     75:   }
     76:   return 0;
     77: }

     79: /*@
     80:    VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by VecSetLocalToGlobalMapping()

     82:    Not Collective

     84:    Input Parameter:
     85: .  X - the vector

     87:    Output Parameter:
     88: .  mapping - the mapping

     90:    Level: advanced

     92: .seealso:  VecSetValuesLocal()
     93: @*/
     94: PetscErrorCode VecGetLocalToGlobalMapping(Vec X,ISLocalToGlobalMapping *mapping)
     95: {
     99:   *mapping = X->map->mapping;
    100:   return 0;
    101: }

    103: /*@
    104:    VecAssemblyBegin - Begins assembling the vector.  This routine should
    105:    be called after completing all calls to VecSetValues().

    107:    Collective on Vec

    109:    Input Parameter:
    110: .  vec - the vector

    112:    Level: beginner

    114: .seealso: VecAssemblyEnd(), VecSetValues()
    115: @*/
    116: PetscErrorCode  VecAssemblyBegin(Vec vec)
    117: {
    120:   VecStashViewFromOptions(vec,NULL,"-vec_view_stash");
    121:   PetscLogEventBegin(VEC_AssemblyBegin,vec,0,0,0);
    122:   if (vec->ops->assemblybegin) {
    123:     (*vec->ops->assemblybegin)(vec);
    124:   }
    125:   PetscLogEventEnd(VEC_AssemblyBegin,vec,0,0,0);
    126:   PetscObjectStateIncrease((PetscObject)vec);
    127:   return 0;
    128: }

    130: /*@
    131:    VecAssemblyEnd - Completes assembling the vector.  This routine should
    132:    be called after VecAssemblyBegin().

    134:    Collective on Vec

    136:    Input Parameter:
    137: .  vec - the vector

    139:    Options Database Keys:
    140: +  -vec_view - Prints vector in ASCII format
    141: .  -vec_view ::ascii_matlab - Prints vector in ASCII MATLAB format to stdout
    142: .  -vec_view matlab:filename - Prints vector in MATLAB format to matlaboutput.mat
    143: .  -vec_view draw - Activates vector viewing using drawing tools
    144: .  -display <name> - Sets display name (default is host)
    145: .  -draw_pause <sec> - Sets number of seconds to pause after display
    146: -  -vec_view socket - Activates vector viewing using a socket

    148:    Level: beginner

    150: .seealso: VecAssemblyBegin(), VecSetValues()
    151: @*/
    152: PetscErrorCode  VecAssemblyEnd(Vec vec)
    153: {
    155:   PetscLogEventBegin(VEC_AssemblyEnd,vec,0,0,0);
    157:   if (vec->ops->assemblyend) {
    158:     (*vec->ops->assemblyend)(vec);
    159:   }
    160:   PetscLogEventEnd(VEC_AssemblyEnd,vec,0,0,0);
    161:   VecViewFromOptions(vec,NULL,"-vec_view");
    162:   return 0;
    163: }

    165: /*@
    166:    VecPointwiseMax - Computes the componentwise maximum w_i = max(x_i, y_i).

    168:    Logically Collective on Vec

    170:    Input Parameters:
    171: .  x, y  - the vectors

    173:    Output Parameter:
    174: .  w - the result

    176:    Level: advanced

    178:    Notes:
    179:     any subset of the x, y, and w may be the same vector.
    180:           For complex numbers compares only the real part

    182: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
    183: @*/
    184: PetscErrorCode  VecPointwiseMax(Vec w,Vec x,Vec y)
    185: {
    194:   VecCheckSameSize(w,1,x,2);
    195:   VecCheckSameSize(w,1,y,3);
    196:   VecSetErrorIfLocked(w,1);
    197:   (*w->ops->pointwisemax)(w,x,y);
    198:   PetscObjectStateIncrease((PetscObject)w);
    199:   return 0;
    200: }

    202: /*@
    203:    VecPointwiseMin - Computes the componentwise minimum w_i = min(x_i, y_i).

    205:    Logically Collective on Vec

    207:    Input Parameters:
    208: .  x, y  - the vectors

    210:    Output Parameter:
    211: .  w - the result

    213:    Level: advanced

    215:    Notes:
    216:     any subset of the x, y, and w may be the same vector.
    217:           For complex numbers compares only the real part

    219: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
    220: @*/
    221: PetscErrorCode  VecPointwiseMin(Vec w,Vec x,Vec y)
    222: {
    231:   VecCheckSameSize(w,1,x,2);
    232:   VecCheckSameSize(w,1,y,3);
    233:   VecSetErrorIfLocked(w,1);
    234:   (*w->ops->pointwisemin)(w,x,y);
    235:   PetscObjectStateIncrease((PetscObject)w);
    236:   return 0;
    237: }

    239: /*@
    240:    VecPointwiseMaxAbs - Computes the componentwise maximum of the absolute values w_i = max(abs(x_i), abs(y_i)).

    242:    Logically Collective on Vec

    244:    Input Parameters:
    245: .  x, y  - the vectors

    247:    Output Parameter:
    248: .  w - the result

    250:    Level: advanced

    252:    Notes:
    253:     any subset of the x, y, and w may be the same vector.

    255: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMax(), VecMaxPointwiseDivide()
    256: @*/
    257: PetscErrorCode  VecPointwiseMaxAbs(Vec w,Vec x,Vec y)
    258: {
    267:   VecCheckSameSize(w,1,x,2);
    268:   VecCheckSameSize(w,1,y,3);
    269:   VecSetErrorIfLocked(w,1);
    270:   (*w->ops->pointwisemaxabs)(w,x,y);
    271:   PetscObjectStateIncrease((PetscObject)w);
    272:   return 0;
    273: }

    275: /*@
    276:    VecPointwiseDivide - Computes the componentwise division w = x/y.

    278:    Logically Collective on Vec

    280:    Input Parameters:
    281: .  x, y  - the vectors

    283:    Output Parameter:
    284: .  w - the result

    286:    Level: advanced

    288:    Notes:
    289:     any subset of the x, y, and w may be the same vector.

    291: .seealso: VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
    292: @*/
    293: PetscErrorCode  VecPointwiseDivide(Vec w,Vec x,Vec y)
    294: {
    303:   VecCheckSameSize(w,1,x,2);
    304:   VecCheckSameSize(w,1,y,3);
    305:   VecSetErrorIfLocked(w,1);
    306:   (*w->ops->pointwisedivide)(w,x,y);
    307:   PetscObjectStateIncrease((PetscObject)w);
    308:   return 0;
    309: }

    311: /*@
    312:    VecDuplicate - Creates a new vector of the same type as an existing vector.

    314:    Collective on Vec

    316:    Input Parameters:
    317: .  v - a vector to mimic

    319:    Output Parameter:
    320: .  newv - location to put new vector

    322:    Notes:
    323:    VecDuplicate() DOES NOT COPY the vector entries, but rather allocates storage
    324:    for the new vector.  Use VecCopy() to copy a vector.

    326:    Use VecDestroy() to free the space. Use VecDuplicateVecs() to get several
    327:    vectors.

    329:    Level: beginner

    331: .seealso: VecDestroy(), VecDuplicateVecs(), VecCreate(), VecCopy()
    332: @*/
    333: PetscErrorCode  VecDuplicate(Vec v,Vec *newv)
    334: {
    338:   (*v->ops->duplicate)(v,newv);
    339: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    340:   if (v->boundtocpu && v->bindingpropagates) {
    341:     VecSetBindingPropagates(*newv,PETSC_TRUE);
    342:     VecBindToCPU(*newv,PETSC_TRUE);
    343:   }
    344: #endif
    345:   PetscObjectStateIncrease((PetscObject)*newv);
    346:   return 0;
    347: }

    349: /*@C
    350:    VecDestroy - Destroys a vector.

    352:    Collective on Vec

    354:    Input Parameters:
    355: .  v  - the vector

    357:    Level: beginner

    359: .seealso: VecDuplicate(), VecDestroyVecs()
    360: @*/
    361: PetscErrorCode  VecDestroy(Vec *v)
    362: {
    363:   if (!*v) return 0;
    365:   if (--((PetscObject)(*v))->refct > 0) {*v = NULL; return 0;}

    367:   PetscObjectSAWsViewOff((PetscObject)*v);
    368:   /* destroy the internal part */
    369:   if ((*v)->ops->destroy) {
    370:     (*(*v)->ops->destroy)(*v);
    371:   }
    372:   PetscFree((*v)->defaultrandtype);
    373:   /* destroy the external/common part */
    374:   PetscLayoutDestroy(&(*v)->map);
    375:   PetscHeaderDestroy(v);
    376:   return 0;
    377: }

    379: /*@C
    380:    VecDuplicateVecs - Creates several vectors of the same type as an existing vector.

    382:    Collective on Vec

    384:    Input Parameters:
    385: +  m - the number of vectors to obtain
    386: -  v - a vector to mimic

    388:    Output Parameter:
    389: .  V - location to put pointer to array of vectors

    391:    Notes:
    392:    Use VecDestroyVecs() to free the space. Use VecDuplicate() to form a single
    393:    vector.

    395:    Fortran Note:
    396:    The Fortran interface is slightly different from that given below, it
    397:    requires one to pass in V a Vec (integer) array of size at least m.
    398:    See the Fortran chapter of the users manual and petsc/src/vec/vec/examples for details.

    400:    Level: intermediate

    402: .seealso:  VecDestroyVecs(), VecDuplicate(), VecCreate(), VecDuplicateVecsF90()
    403: @*/
    404: PetscErrorCode  VecDuplicateVecs(Vec v,PetscInt m,Vec *V[])
    405: {
    409:   (*v->ops->duplicatevecs)(v,m,V);
    410: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    411:   if (v->boundtocpu && v->bindingpropagates) {
    412:     PetscInt i;

    414:     for (i=0; i<m; i++) {
    415:       /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
    416:        * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
    417:       if (!(*V)[i]->boundtocpu) {
    418:         VecSetBindingPropagates((*V)[i],PETSC_TRUE);
    419:         VecBindToCPU((*V)[i],PETSC_TRUE);
    420:       }
    421:     }
    422:   }
    423: #endif
    424:   return 0;
    425: }

    427: /*@C
    428:    VecDestroyVecs - Frees a block of vectors obtained with VecDuplicateVecs().

    430:    Collective on Vec

    432:    Input Parameters:
    433: +  vv - pointer to pointer to array of vector pointers, if NULL no vectors are destroyed
    434: -  m - the number of vectors previously obtained, if zero no vectors are destroyed

    436:    Fortran Note:
    437:    The Fortran interface is slightly different from that given below.
    438:    See the Fortran chapter of the users manual

    440:    Level: intermediate

    442: .seealso: VecDuplicateVecs(), VecDestroyVecsf90()
    443: @*/
    444: PetscErrorCode  VecDestroyVecs(PetscInt m,Vec *vv[])
    445: {
    448:   if (!m || !*vv) {*vv  = NULL; return 0;}
    451:   (*(**vv)->ops->destroyvecs)(m,*vv);
    452:   *vv  = NULL;
    453:   return 0;
    454: }

    456: /*@C
    457:    VecViewFromOptions - View from Options

    459:    Collective on Vec

    461:    Input Parameters:
    462: +  A - the vector
    463: .  obj - Optional object
    464: -  name - command line option

    466:    Level: intermediate
    467: .seealso:  Vec, VecView, PetscObjectViewFromOptions(), VecCreate()
    468: @*/
    469: PetscErrorCode  VecViewFromOptions(Vec A,PetscObject obj,const char name[])
    470: {
    472:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
    473:   return 0;
    474: }

    476: /*@C
    477:    VecView - Views a vector object.

    479:    Collective on Vec

    481:    Input Parameters:
    482: +  vec - the vector
    483: -  viewer - an optional visualization context

    485:    Notes:
    486:    The available visualization contexts include
    487: +     PETSC_VIEWER_STDOUT_SELF - for sequential vectors
    488: .     PETSC_VIEWER_STDOUT_WORLD - for parallel vectors created on PETSC_COMM_WORLD
    489: -     PETSC_VIEWER_STDOUT_(comm) - for parallel vectors created on MPI communicator comm

    491:    You can change the format the vector is printed using the
    492:    option PetscViewerPushFormat().

    494:    The user can open alternative viewers with
    495: +    PetscViewerASCIIOpen() - Outputs vector to a specified file
    496: .    PetscViewerBinaryOpen() - Outputs vector in binary to a
    497:          specified file; corresponding input uses VecLoad()
    498: .    PetscViewerDrawOpen() - Outputs vector to an X window display
    499: .    PetscViewerSocketOpen() - Outputs vector to Socket viewer
    500: -    PetscViewerHDF5Open() - Outputs vector to HDF5 file viewer

    502:    The user can call PetscViewerPushFormat() to specify the output
    503:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
    504:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
    505: +    PETSC_VIEWER_DEFAULT - default, prints vector contents
    506: .    PETSC_VIEWER_ASCII_MATLAB - prints vector contents in MATLAB format
    507: .    PETSC_VIEWER_ASCII_INDEX - prints vector contents, including indices of vector elements
    508: -    PETSC_VIEWER_ASCII_COMMON - prints vector contents, using a
    509:          format common among all vector types

    511:    Notes:
    512:     You can pass any number of vector objects, or other PETSc objects to the same viewer.

    514:     In the debugger you can do "call VecView(v,0)" to display the vector. (The same holds for any PETSc object viewer).

    516:    Notes for binary viewer:
    517:      If you pass multiple vectors to a binary viewer you can read them back in in the same order
    518:      with VecLoad().

    520:      If the blocksize of the vector is greater than one then you must provide a unique prefix to
    521:      the vector with PetscObjectSetOptionsPrefix((PetscObject)vec,"uniqueprefix"); BEFORE calling VecView() on the
    522:      vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
    523:      information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
    524:      filename. If you copy the binary file, make sure you copy the associated .info file with it.

    526:      See the manual page for VecLoad() on the exact format the binary viewer stores
    527:      the values in the file.

    529:    Notes for HDF5 Viewer:
    530:      The name of the Vec (given with PetscObjectSetName() is the name that is used
    531:      for the object in the HDF5 file. If you wish to store the same Vec into multiple
    532:      datasets in the same file (typically with different values), you must change its
    533:      name each time before calling the VecView(). To load the same vector,
    534:      the name of the Vec object passed to VecLoad() must be the same.

    536:      If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
    537:      If the function PetscViewerHDF5SetBaseDimension2()is called then even if the block size is one it will
    538:      be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
    539:      See also PetscViewerHDF5SetTimestep() which adds an additional complication to reading and writing Vecs
    540:      with the HDF5 viewer.

    542:    Level: beginner

    544: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscDrawLGCreate(),
    545:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), VecLoad(), PetscViewerCreate(),
    546:           PetscRealView(), PetscScalarView(), PetscIntView(), PetscViewerHDF5SetTimestep()
    547: @*/
    548: PetscErrorCode  VecView(Vec vec,PetscViewer viewer)
    549: {
    550:   PetscBool         iascii;
    551:   PetscViewerFormat format;
    552:   PetscMPIInt       size;

    556:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec),&viewer);
    558:   PetscViewerGetFormat(viewer,&format);
    559:   MPI_Comm_size(PetscObjectComm((PetscObject)vec),&size);
    560:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) return 0;

    564:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    565:   if (iascii) {
    566:     PetscInt rows,bs;

    568:     PetscObjectPrintClassNamePrefixType((PetscObject)vec,viewer);
    569:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    570:       PetscViewerASCIIPushTab(viewer);
    571:       VecGetSize(vec,&rows);
    572:       VecGetBlockSize(vec,&bs);
    573:       if (bs != 1) {
    574:         PetscViewerASCIIPrintf(viewer,"length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,bs);
    575:       } else {
    576:         PetscViewerASCIIPrintf(viewer,"length=%" PetscInt_FMT "\n",rows);
    577:       }
    578:       PetscViewerASCIIPopTab(viewer);
    579:     }
    580:   }
    581:   VecLockReadPush(vec);
    582:   PetscLogEventBegin(VEC_View,vec,viewer,0,0);
    583:   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
    584:     (*vec->ops->viewnative)(vec,viewer);
    585:   } else {
    586:     (*vec->ops->view)(vec,viewer);
    587:   }
    588:   VecLockReadPop(vec);
    589:   PetscLogEventEnd(VEC_View,vec,viewer,0,0);
    590:   return 0;
    591: }

    593: #if defined(PETSC_USE_DEBUG)
    594: #include <../src/sys/totalview/tv_data_display.h>
    595: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
    596: {
    597:   const PetscScalar *values;
    598:   char              type[32];

    600:   TV_add_row("Local rows", "int", &v->map->n);
    601:   TV_add_row("Global rows", "int", &v->map->N);
    602:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
    603:   VecGetArrayRead((Vec)v,&values);
    604:   PetscSNPrintf(type,32,"double[%" PetscInt_FMT "]",v->map->n);
    605:   TV_add_row("values",type, values);
    606:   VecRestoreArrayRead((Vec)v,&values);
    607:   return TV_format_OK;
    608: }
    609: #endif

    611: /*@C
    612:    VecViewNative - Views a vector object with the original type specific viewer

    614:    Collective on Vec

    616:    Input Parameters:
    617: +  vec - the vector
    618: -  viewer - an optional visualization context

    620:    Level: developer

    622: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscDrawLGCreate(), VecView()
    623:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), VecLoad(), PetscViewerCreate(),
    624:           PetscRealView(), PetscScalarView(), PetscIntView(), PetscViewerHDF5SetTimestep()
    625: @*/
    626: PetscErrorCode  VecViewNative(Vec vec,PetscViewer viewer)
    627: {
    630:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec),&viewer);
    632:   (*vec->ops->viewnative)(vec,viewer);
    633:   return 0;
    634: }

    636: /*@
    637:    VecGetSize - Returns the global number of elements of the vector.

    639:    Not Collective

    641:    Input Parameter:
    642: .  x - the vector

    644:    Output Parameters:
    645: .  size - the global length of the vector

    647:    Level: beginner

    649: .seealso: VecGetLocalSize()
    650: @*/
    651: PetscErrorCode  VecGetSize(Vec x,PetscInt *size)
    652: {
    656:   (*x->ops->getsize)(x,size);
    657:   return 0;
    658: }

    660: /*@
    661:    VecGetLocalSize - Returns the number of elements of the vector stored
    662:    in local memory.

    664:    Not Collective

    666:    Input Parameter:
    667: .  x - the vector

    669:    Output Parameter:
    670: .  size - the length of the local piece of the vector

    672:    Level: beginner

    674: .seealso: VecGetSize()
    675: @*/
    676: PetscErrorCode  VecGetLocalSize(Vec x,PetscInt *size)
    677: {
    681:   (*x->ops->getlocalsize)(x,size);
    682:   return 0;
    683: }

    685: /*@C
    686:    VecGetOwnershipRange - Returns the range of indices owned by
    687:    this processor, assuming that the vectors are laid out with the
    688:    first n1 elements on the first processor, next n2 elements on the
    689:    second, etc.  For certain parallel layouts this range may not be
    690:    well defined.

    692:    Not Collective

    694:    Input Parameter:
    695: .  x - the vector

    697:    Output Parameters:
    698: +  low - the first local element, pass in NULL if not interested
    699: -  high - one more than the last local element, pass in NULL if not interested

    701:    Note:
    702:    The high argument is one more than the last element stored locally.

    704:    Fortran: PETSC_NULL_INTEGER should be used instead of NULL

    706:    Level: beginner

    708: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRanges(), VecGetOwnershipRanges()
    709: @*/
    710: PetscErrorCode  VecGetOwnershipRange(Vec x,PetscInt *low,PetscInt *high)
    711: {
    716:   if (low)  *low  = x->map->rstart;
    717:   if (high) *high = x->map->rend;
    718:   return 0;
    719: }

    721: /*@C
    722:    VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
    723:    assuming that the vectors are laid out with the
    724:    first n1 elements on the first processor, next n2 elements on the
    725:    second, etc.  For certain parallel layouts this range may not be
    726:    well defined.

    728:    Not Collective

    730:    Input Parameter:
    731: .  x - the vector

    733:    Output Parameters:
    734: .  range - array of length size+1 with the start and end+1 for each process

    736:    Note:
    737:    The high argument is one more than the last element stored locally.

    739:    Fortran: You must PASS in an array of length size+1

    741:    If the ranges are used after all vectors that share the ranges has been destroyed then the program will crash accessing ranges[].

    743:    Level: beginner

    745: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRanges(), VecGetOwnershipRange()
    746: @*/
    747: PetscErrorCode  VecGetOwnershipRanges(Vec x,const PetscInt *ranges[])
    748: {
    751:   PetscLayoutGetRanges(x->map,ranges);
    752:   return 0;
    753: }

    755: /*@
    756:    VecSetOption - Sets an option for controling a vector's behavior.

    758:    Collective on Vec

    760:    Input Parameters:
    761: +  x - the vector
    762: .  op - the option
    763: -  flag - turn the option on or off

    765:    Supported Options:
    766: +     VEC_IGNORE_OFF_PROC_ENTRIES, which causes VecSetValues() to ignore
    767:           entries destined to be stored on a separate processor. This can be used
    768:           to eliminate the global reduction in the VecAssemblyXXXX() if you know
    769:           that you have only used VecSetValues() to set local elements
    770: .     VEC_IGNORE_NEGATIVE_INDICES, which means you can pass negative indices
    771:           in ix in calls to VecSetValues() or VecGetValues(). These rows are simply
    772:           ignored.
    773: -     VEC_SUBSET_OFF_PROC_ENTRIES, which causes VecAssemblyBegin() to assume that the off-process
    774:           entries will always be a subset (possibly equal) of the off-process entries set on the
    775:           first assembly which had a true VEC_SUBSET_OFF_PROC_ENTRIES and the vector has not
    776:           changed this flag afterwards. If this assembly is not such first assembly, then this
    777:           assembly can reuse the communication pattern setup in that first assembly, thus avoiding
    778:           a global reduction. Subsequent assemblies setting off-process values should use the same
    779:           InsertMode as the first assembly.

    781:    Developer Note:
    782:    The InsertMode restriction could be removed by packing the stash messages out of place.

    784:    Level: intermediate

    786: @*/
    787: PetscErrorCode  VecSetOption(Vec x,VecOption op,PetscBool flag)
    788: {
    791:   if (x->ops->setoption) {
    792:     (*x->ops->setoption)(x,op,flag);
    793:   }
    794:   return 0;
    795: }

    797: /* Default routines for obtaining and releasing; */
    798: /* may be used by any implementation */
    799: PetscErrorCode VecDuplicateVecs_Default(Vec w,PetscInt m,Vec *V[])
    800: {
    804:   PetscMalloc1(m,V);
    805:   for (PetscInt i=0; i<m; i++) VecDuplicate(w,*V+i);
    806:   return 0;
    807: }

    809: PetscErrorCode VecDestroyVecs_Default(PetscInt m,Vec v[])
    810: {
    811:   PetscInt       i;

    814:   for (i=0; i<m; i++) VecDestroy(&v[i]);
    815:   PetscFree(v);
    816:   return 0;
    817: }

    819: /*@
    820:    VecResetArray - Resets a vector to use its default memory. Call this
    821:    after the use of VecPlaceArray().

    823:    Not Collective

    825:    Input Parameters:
    826: .  vec - the vector

    828:    Level: developer

    830: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray()

    832: @*/
    833: PetscErrorCode  VecResetArray(Vec vec)
    834: {
    837:   if (vec->ops->resetarray) {
    838:     (*vec->ops->resetarray)(vec);
    839:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot reset array in this type of vector");
    840:   PetscObjectStateIncrease((PetscObject)vec);
    841:   return 0;
    842: }

    844: /*@C
    845:   VecLoad - Loads a vector that has been stored in binary or HDF5 format
    846:   with VecView().

    848:   Collective on PetscViewer

    850:   Input Parameters:
    851: + vec - the newly loaded vector, this needs to have been created with VecCreate() or
    852:            some related function before a call to VecLoad().
    853: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
    854:            HDF5 file viewer, obtained from PetscViewerHDF5Open()

    856:    Level: intermediate

    858:   Notes:
    859:   Defaults to the standard Seq or MPI Vec, if you want some other type of Vec call VecSetFromOptions()
    860:   before calling this.

    862:   The input file must contain the full global vector, as
    863:   written by the routine VecView().

    865:   If the type or size of vec is not set before a call to VecLoad, PETSc
    866:   sets the type and the local and global sizes. If type and/or
    867:   sizes are already set, then the same are used.

    869:   If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
    870:   the vector with PetscObjectSetOptionsPrefix((PetscObject)vec,"uniqueprefix"); BEFORE calling VecView() on the
    871:   vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
    872:   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
    873:   filename. If you copy the binary file, make sure you copy the associated .info file with it.

    875:   If using HDF5, you must assign the Vec the same name as was used in the Vec
    876:   that was stored in the file using PetscObjectSetName(). Otherwise you will
    877:   get the error message: "Cannot H5DOpen2() with Vec name NAMEOFOBJECT".

    879:   If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
    880:   in loading the vector. Hence, for example, using Matlab notation h5create('vector.dat','/Test_Vec',[27 1]);
    881:   will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
    882:   vectors communicator and the rest of the processes having zero entries

    884:   Notes for advanced users when using the binary viewer:
    885:   Most users should not need to know the details of the binary storage
    886:   format, since VecLoad() and VecView() completely hide these details.
    887:   But for anyone who's interested, the standard binary vector storage
    888:   format is
    889: .vb
    890:      PetscInt    VEC_FILE_CLASSID
    891:      PetscInt    number of rows
    892:      PetscScalar *values of all entries
    893: .ve

    895:    In addition, PETSc automatically uses byte swapping to work on all machines; the files
    896:    are written ALWAYS using big-endian ordering. On small-endian machines the numbers
    897:    are converted to the small-endian format when they are read in from the file.
    898:    See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.

    900: .seealso: PetscViewerBinaryOpen(), VecView(), MatLoad(), VecLoad()
    901: @*/
    902: PetscErrorCode  VecLoad(Vec vec, PetscViewer viewer)
    903: {
    904:   PetscBool         isbinary,ishdf5,isadios,isexodusii;
    905:   PetscViewerFormat format;

    910:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    911:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
    912:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERADIOS,&isadios);
    913:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWEREXODUSII,&isexodusii);

    916:   VecSetErrorIfLocked(vec,1);
    917:   if (!((PetscObject)vec)->type_name && !vec->ops->create) VecSetType(vec, VECSTANDARD);
    918:   PetscLogEventBegin(VEC_Load,viewer,0,0,0);
    919:   PetscViewerGetFormat(viewer,&format);
    920:   if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
    921:     (*vec->ops->loadnative)(vec,viewer);
    922:   } else {
    923:     (*vec->ops->load)(vec,viewer);
    924:   }
    925:   PetscLogEventEnd(VEC_Load,viewer,0,0,0);
    926:   return 0;
    927: }

    929: /*@
    930:    VecReciprocal - Replaces each component of a vector by its reciprocal.

    932:    Logically Collective on Vec

    934:    Input Parameter:
    935: .  vec - the vector

    937:    Output Parameter:
    938: .  vec - the vector reciprocal

    940:    Level: intermediate

    942: .seealso: VecLog(), VecExp(), VecSqrtAbs()

    944: @*/
    945: PetscErrorCode  VecReciprocal(Vec vec)
    946: {
    951:   VecSetErrorIfLocked(vec,1);
    952:   (*vec->ops->reciprocal)(vec);
    953:   PetscObjectStateIncrease((PetscObject)vec);
    954:   return 0;
    955: }

    957: /*@C
    958:     VecSetOperation - Allows user to set a vector operation.

    960:    Logically Collective on Vec

    962:     Input Parameters:
    963: +   vec - the vector
    964: .   op - the name of the operation
    965: -   f - the function that provides the operation.

    967:    Level: advanced

    969:     Usage:
    970: $      PetscErrorCode userview(Vec,PetscViewer);
    971: $      VecCreateMPI(comm,m,M,&x);
    972: $      VecSetOperation(x,VECOP_VIEW,(void(*)(void))userview);

    974:     Notes:
    975:     See the file include/petscvec.h for a complete list of matrix
    976:     operations, which all have the form VECOP_<OPERATION>, where
    977:     <OPERATION> is the name (in all capital letters) of the
    978:     user interface routine (e.g., VecView() -> VECOP_VIEW).

    980:     This function is not currently available from Fortran.

    982: .seealso: VecCreate(), MatShellSetOperation()
    983: @*/
    984: PetscErrorCode VecSetOperation(Vec vec,VecOperation op, void (*f)(void))
    985: {
    987:   if (op == VECOP_VIEW && !vec->ops->viewnative) {
    988:     vec->ops->viewnative = vec->ops->view;
    989:   } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
    990:     vec->ops->loadnative = vec->ops->load;
    991:   }
    992:   (((void(**)(void))vec->ops)[(int)op]) = f;
    993:   return 0;
    994: }

    996: /*@
    997:    VecStashSetInitialSize - sets the sizes of the vec-stash, that is
    998:    used during the assembly process to store values that belong to
    999:    other processors.

    1001:    Not Collective, different processes can have different size stashes

    1003:    Input Parameters:
    1004: +  vec   - the vector
    1005: .  size  - the initial size of the stash.
    1006: -  bsize - the initial size of the block-stash(if used).

    1008:    Options Database Keys:
    1009: +   -vecstash_initial_size <size> or <size0,size1,...sizep-1>
    1010: -   -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>

    1012:    Level: intermediate

    1014:    Notes:
    1015:      The block-stash is used for values set with VecSetValuesBlocked() while
    1016:      the stash is used for values set with VecSetValues()

    1018:      Run with the option -info and look for output of the form
    1019:      VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
    1020:      to determine the appropriate value, MM, to use for size and
    1021:      VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
    1022:      to determine the value, BMM to use for bsize

    1024: .seealso: VecSetBlockSize(), VecSetValues(), VecSetValuesBlocked(), VecStashView()

    1026: @*/
    1027: PetscErrorCode  VecStashSetInitialSize(Vec vec,PetscInt size,PetscInt bsize)
    1028: {
    1030:   VecStashSetInitialSize_Private(&vec->stash,size);
    1031:   VecStashSetInitialSize_Private(&vec->bstash,bsize);
    1032:   return 0;
    1033: }

    1035: /*@
    1036:    VecConjugate - Conjugates a vector.

    1038:    Logically Collective on Vec

    1040:    Input Parameters:
    1041: .  x - the vector

    1043:    Level: intermediate

    1045: @*/
    1046: PetscErrorCode  VecConjugate(Vec x)
    1047: {
    1051:   if (PetscDefined(USE_COMPLEX)) {
    1052:     VecSetErrorIfLocked(x,1);
    1053:     (*x->ops->conjugate)(x);
    1054:     /* we need to copy norms here */
    1055:     PetscObjectStateIncrease((PetscObject)x);
    1056:   }
    1057:   return 0;
    1058: }

    1060: /*@
    1061:    VecPointwiseMult - Computes the componentwise multiplication w = x*y.

    1063:    Logically Collective on Vec

    1065:    Input Parameters:
    1066: .  x, y  - the vectors

    1068:    Output Parameter:
    1069: .  w - the result

    1071:    Level: advanced

    1073:    Notes:
    1074:     any subset of the x, y, and w may be the same vector.

    1076: .seealso: VecPointwiseDivide(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
    1077: @*/
    1078: PetscErrorCode  VecPointwiseMult(Vec w,Vec x,Vec y)
    1079: {
    1088:   VecCheckSameSize(w,1,x,2);
    1089:   VecCheckSameSize(w,2,y,3);
    1090:   VecSetErrorIfLocked(w,1);
    1091:   PetscLogEventBegin(VEC_PointwiseMult,x,y,w,0);
    1092:   (*w->ops->pointwisemult)(w,x,y);
    1093:   PetscLogEventEnd(VEC_PointwiseMult,x,y,w,0);
    1094:   PetscObjectStateIncrease((PetscObject)w);
    1095:   return 0;
    1096: }

    1098: /*@
    1099:    VecSetRandom - Sets all components of a vector to random numbers.

    1101:    Logically Collective on Vec

    1103:    Input Parameters:
    1104: +  x  - the vector
    1105: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
    1106:           it will create one internally.

    1108:    Output Parameter:
    1109: .  x  - the vector

    1111:    Example of Usage:
    1112: .vb
    1113:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
    1114:      VecSetRandom(x,rctx);
    1115:      PetscRandomDestroy(&rctx);
    1116: .ve

    1118:    Level: intermediate

    1120: .seealso: VecSet(), VecSetValues(), PetscRandomCreate(), PetscRandomDestroy()
    1121: @*/
    1122: PetscErrorCode  VecSetRandom(Vec x,PetscRandom rctx)
    1123: {
    1124:   PetscRandom randObj = NULL;

    1130:   VecSetErrorIfLocked(x,1);

    1132:   if (!rctx) {
    1133:     PetscRandomCreate(PetscObjectComm((PetscObject)x),&randObj);
    1134:     PetscRandomSetType(randObj,x->defaultrandtype);
    1135:     PetscRandomSetFromOptions(randObj);
    1136:     rctx = randObj;
    1137:   }

    1139:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
    1140:   (*x->ops->setrandom)(x,rctx);
    1141:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

    1143:   PetscRandomDestroy(&randObj);
    1144:   PetscObjectStateIncrease((PetscObject)x);
    1145:   return 0;
    1146: }

    1148: /*@
    1149:   VecZeroEntries - puts a 0.0 in each element of a vector

    1151:   Logically Collective on Vec

    1153:   Input Parameter:
    1154: . vec - The vector

    1156:   Level: beginner

    1158: .seealso: VecCreate(),  VecSetOptionsPrefix(), VecSet(), VecSetValues()
    1159: @*/
    1160: PetscErrorCode  VecZeroEntries(Vec vec)
    1161: {
    1162:   VecSet(vec,0);
    1163:   return 0;
    1164: }

    1166: /*
    1167:   VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
    1168:   processor and a PETSc MPI vector on more than one processor.

    1170:   Collective on Vec

    1172:   Input Parameter:
    1173: . vec - The vector

    1175:   Level: intermediate

    1177: .seealso: VecSetFromOptions(), VecSetType()
    1178: */
    1179: static PetscErrorCode VecSetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,Vec vec)
    1180: {
    1181:   PetscBool      opt;
    1182:   VecType        defaultType;
    1183:   char           typeName[256];
    1184:   PetscMPIInt    size;

    1186:   if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
    1187:   else {
    1188:     MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size);
    1189:     if (size > 1) defaultType = VECMPI;
    1190:     else defaultType = VECSEQ;
    1191:   }

    1193:   VecRegisterAll();
    1194:   PetscOptionsFList("-vec_type","Vector type","VecSetType",VecList,defaultType,typeName,256,&opt);
    1195:   if (opt) {
    1196:     VecSetType(vec, typeName);
    1197:   } else {
    1198:     VecSetType(vec, defaultType);
    1199:   }
    1200:   return 0;
    1201: }

    1203: /*@
    1204:   VecSetFromOptions - Configures the vector from the options database.

    1206:   Collective on Vec

    1208:   Input Parameter:
    1209: . vec - The vector

    1211:   Notes:
    1212:     To see all options, run your program with the -help option, or consult the users manual.
    1213:           Must be called after VecCreate() but before the vector is used.

    1215:   Level: beginner

    1217: .seealso: VecCreate(), VecSetOptionsPrefix()
    1218: @*/
    1219: PetscErrorCode  VecSetFromOptions(Vec vec)
    1220: {
    1222:   PetscBool      flg;
    1223:   PetscInt       bind_below = 0;

    1227:   PetscObjectOptionsBegin((PetscObject)vec);
    1228:   /* Handle vector type options */
    1229:   VecSetTypeFromOptions_Private(PetscOptionsObject,vec);

    1231:   /* Handle specific vector options */
    1232:   if (vec->ops->setfromoptions) (*vec->ops->setfromoptions)(PetscOptionsObject,vec);

    1234:   /* Bind to CPU if below a user-specified size threshold.
    1235:    * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
    1236:    * and putting it here makes is more maintainable than duplicating this for all. */
    1237:   PetscOptionsInt("-vec_bind_below","Set the size threshold (in local entries) below which the Vec is bound to the CPU","VecBindToCPU",bind_below,&bind_below,&flg);
    1238:   if (flg && vec->map->n < bind_below) VecBindToCPU(vec,PETSC_TRUE);

    1240:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    1241:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)vec);
    1242:   PetscOptionsEnd();
    1243:   return 0;
    1244: }

    1246: /*@
    1247:   VecSetSizes - Sets the local and global sizes, and checks to determine compatibility

    1249:   Collective on Vec

    1251:   Input Parameters:
    1252: + v - the vector
    1253: . n - the local size (or PETSC_DECIDE to have it set)
    1254: - N - the global size (or PETSC_DECIDE)

    1256:   Notes:
    1257:   n and N cannot be both PETSC_DECIDE
    1258:   If one processor calls this with N of PETSC_DECIDE then all processors must, otherwise the program will hang.

    1260:   Level: intermediate

    1262: .seealso: VecGetSize(), PetscSplitOwnership()
    1263: @*/
    1264: PetscErrorCode  VecSetSizes(Vec v, PetscInt n, PetscInt N)
    1265: {
    1267:   if (N >= 0) {
    1270:   }
    1272:   v->map->n = n;
    1273:   v->map->N = N;
    1274:   if (v->ops->create) {
    1275:     (*v->ops->create)(v);
    1276:     v->ops->create = NULL;
    1277:   }
    1278:   return 0;
    1279: }

    1281: /*@
    1282:    VecSetBlockSize - Sets the blocksize for future calls to VecSetValuesBlocked()
    1283:    and VecSetValuesBlockedLocal().

    1285:    Logically Collective on Vec

    1287:    Input Parameters:
    1288: +  v - the vector
    1289: -  bs - the blocksize

    1291:    Notes:
    1292:    All vectors obtained by VecDuplicate() inherit the same blocksize.

    1294:    Level: advanced

    1296: .seealso: VecSetValuesBlocked(), VecSetLocalToGlobalMapping(), VecGetBlockSize()

    1298: @*/
    1299: PetscErrorCode  VecSetBlockSize(Vec v,PetscInt bs)
    1300: {
    1303:   PetscLayoutSetBlockSize(v->map,bs);
    1304:   v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
    1305:   return 0;
    1306: }

    1308: /*@
    1309:    VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for VecSetValuesBlocked()
    1310:    and VecSetValuesBlockedLocal().

    1312:    Not Collective

    1314:    Input Parameter:
    1315: .  v - the vector

    1317:    Output Parameter:
    1318: .  bs - the blocksize

    1320:    Notes:
    1321:    All vectors obtained by VecDuplicate() inherit the same blocksize.

    1323:    Level: advanced

    1325: .seealso: VecSetValuesBlocked(), VecSetLocalToGlobalMapping(), VecSetBlockSize()

    1327: @*/
    1328: PetscErrorCode  VecGetBlockSize(Vec v,PetscInt *bs)
    1329: {
    1332:   PetscLayoutGetBlockSize(v->map,bs);
    1333:   return 0;
    1334: }

    1336: /*@C
    1337:    VecSetOptionsPrefix - Sets the prefix used for searching for all
    1338:    Vec options in the database.

    1340:    Logically Collective on Vec

    1342:    Input Parameters:
    1343: +  v - the Vec context
    1344: -  prefix - the prefix to prepend to all option names

    1346:    Notes:
    1347:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    1348:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    1350:    Level: advanced

    1352: .seealso: VecSetFromOptions()
    1353: @*/
    1354: PetscErrorCode  VecSetOptionsPrefix(Vec v,const char prefix[])
    1355: {
    1357:   PetscObjectSetOptionsPrefix((PetscObject)v,prefix);
    1358:   return 0;
    1359: }

    1361: /*@C
    1362:    VecAppendOptionsPrefix - Appends to the prefix used for searching for all
    1363:    Vec options in the database.

    1365:    Logically Collective on Vec

    1367:    Input Parameters:
    1368: +  v - the Vec context
    1369: -  prefix - the prefix to prepend to all option names

    1371:    Notes:
    1372:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    1373:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    1375:    Level: advanced

    1377: .seealso: VecGetOptionsPrefix()
    1378: @*/
    1379: PetscErrorCode  VecAppendOptionsPrefix(Vec v,const char prefix[])
    1380: {
    1382:   PetscObjectAppendOptionsPrefix((PetscObject)v,prefix);
    1383:   return 0;
    1384: }

    1386: /*@C
    1387:    VecGetOptionsPrefix - Sets the prefix used for searching for all
    1388:    Vec options in the database.

    1390:    Not Collective

    1392:    Input Parameter:
    1393: .  v - the Vec context

    1395:    Output Parameter:
    1396: .  prefix - pointer to the prefix string used

    1398:    Notes:
    1399:     On the fortran side, the user should pass in a string 'prefix' of
    1400:    sufficient length to hold the prefix.

    1402:    Level: advanced

    1404: .seealso: VecAppendOptionsPrefix()
    1405: @*/
    1406: PetscErrorCode  VecGetOptionsPrefix(Vec v,const char *prefix[])
    1407: {
    1409:   PetscObjectGetOptionsPrefix((PetscObject)v,prefix);
    1410:   return 0;
    1411: }

    1413: /*@
    1414:    VecSetUp - Sets up the internal vector data structures for the later use.

    1416:    Collective on Vec

    1418:    Input Parameters:
    1419: .  v - the Vec context

    1421:    Notes:
    1422:    For basic use of the Vec classes the user need not explicitly call
    1423:    VecSetUp(), since these actions will happen automatically.

    1425:    Level: advanced

    1427: .seealso: VecCreate(), VecDestroy()
    1428: @*/
    1429: PetscErrorCode  VecSetUp(Vec v)
    1430: {
    1431:   PetscMPIInt    size;

    1435:   if (!((PetscObject)v)->type_name) {
    1436:     MPI_Comm_size(PetscObjectComm((PetscObject)v), &size);
    1437:     if (size == 1) {
    1438:       VecSetType(v, VECSEQ);
    1439:     } else {
    1440:       VecSetType(v, VECMPI);
    1441:     }
    1442:   }
    1443:   return 0;
    1444: }

    1446: /*
    1447:     These currently expose the PetscScalar/PetscReal in updating the
    1448:     cached norm. If we push those down into the implementation these
    1449:     will become independent of PetscScalar/PetscReal
    1450: */

    1452: /*@
    1453:    VecCopy - Copies a vector. y <- x

    1455:    Logically Collective on Vec

    1457:    Input Parameter:
    1458: .  x - the vector

    1460:    Output Parameter:
    1461: .  y - the copy

    1463:    Notes:
    1464:    For default parallel PETSc vectors, both x and y must be distributed in
    1465:    the same manner; local copies are done.

    1467:    Developer Notes:
    1469:    of the vectors to be sequential and one to be parallel so long as both have the same
    1470:    local sizes. This is used in some internal functions in PETSc.

    1472:    Level: beginner

    1474: .seealso: VecDuplicate()
    1475: @*/
    1476: PetscErrorCode  VecCopy(Vec x,Vec y)
    1477: {
    1478:   PetscBool flgs[4];
    1479:   PetscReal norms[4] = {0.0,0.0,0.0,0.0};

    1485:   if (x == y) return 0;
    1486:   VecCheckSameLocalSize(x,1,y,2);
    1488:   VecSetErrorIfLocked(y,2);

    1490: #if !defined(PETSC_USE_MIXED_PRECISION)
    1491:   for (PetscInt i=0; i<4; i++) PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
    1492: #endif

    1494:   PetscLogEventBegin(VEC_Copy,x,y,0,0);
    1495: #if defined(PETSC_USE_MIXED_PRECISION)
    1496:   extern PetscErrorCode VecGetArray(Vec,double**);
    1497:   extern PetscErrorCode VecRestoreArray(Vec,double**);
    1498:   extern PetscErrorCode VecGetArray(Vec,float**);
    1499:   extern PetscErrorCode VecRestoreArray(Vec,float**);
    1500:   extern PetscErrorCode VecGetArrayRead(Vec,const double**);
    1501:   extern PetscErrorCode VecRestoreArrayRead(Vec,const double**);
    1502:   extern PetscErrorCode VecGetArrayRead(Vec,const float**);
    1503:   extern PetscErrorCode VecRestoreArrayRead(Vec,const float**);
    1504:   if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
    1505:     PetscInt    i,n;
    1506:     const float *xx;
    1507:     double      *yy;
    1508:     VecGetArrayRead(x,&xx);
    1509:     VecGetArray(y,&yy);
    1510:     VecGetLocalSize(x,&n);
    1511:     for (i=0; i<n; i++) yy[i] = xx[i];
    1512:     VecRestoreArrayRead(x,&xx);
    1513:     VecRestoreArray(y,&yy);
    1514:   } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
    1515:     PetscInt     i,n;
    1516:     float        *yy;
    1517:     const double *xx;
    1518:     VecGetArrayRead(x,&xx);
    1519:     VecGetArray(y,&yy);
    1520:     VecGetLocalSize(x,&n);
    1521:     for (i=0; i<n; i++) yy[i] = (float) xx[i];
    1522:     VecRestoreArrayRead(x,&xx);
    1523:     VecRestoreArray(y,&yy);
    1524:   } else {
    1525:     (*x->ops->copy)(x,y);
    1526:   }
    1527: #else
    1528:   (*x->ops->copy)(x,y);
    1529: #endif

    1531:   PetscObjectStateIncrease((PetscObject)y);
    1532: #if !defined(PETSC_USE_MIXED_PRECISION)
    1533:   for (PetscInt i=0; i<4; i++) {
    1534:     if (flgs[i]) PetscObjectComposedDataSetReal((PetscObject)y,NormIds[i],norms[i]);
    1535:   }
    1536: #endif

    1538:   PetscLogEventEnd(VEC_Copy,x,y,0,0);
    1539:   return 0;
    1540: }

    1542: /*@
    1543:    VecSwap - Swaps the vectors x and y.

    1545:    Logically Collective on Vec

    1547:    Input Parameters:
    1548: .  x, y  - the vectors

    1550:    Level: advanced

    1552: @*/
    1553: PetscErrorCode  VecSwap(Vec x,Vec y)
    1554: {
    1555:   PetscReal normxs[4] = {0.0,0.0,0.0,0.0},normys[4]={0.0,0.0,0.0,0.0};
    1556:   PetscBool flgxs[4],flgys[4];

    1563:   VecCheckSameSize(x,1,y,2);
    1566:   VecSetErrorIfLocked(x,1);
    1567:   VecSetErrorIfLocked(y,2);

    1569:   PetscLogEventBegin(VEC_Swap,x,y,0,0);
    1570:   for (PetscInt i=0; i<4; i++) {
    1571:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],normxs[i],flgxs[i]);
    1572:     PetscObjectComposedDataGetReal((PetscObject)y,NormIds[i],normys[i],flgys[i]);
    1573:   }
    1574:   (*x->ops->swap)(x,y);
    1575:   PetscObjectStateIncrease((PetscObject)x);
    1576:   PetscObjectStateIncrease((PetscObject)y);
    1577:   for (PetscInt i=0; i<4; i++) {
    1578:     if (flgxs[i]) PetscObjectComposedDataSetReal((PetscObject)y,NormIds[i],normxs[i]);
    1579:     if (flgys[i]) PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],normys[i]);
    1580:   }
    1581:   PetscLogEventEnd(VEC_Swap,x,y,0,0);
    1582:   return 0;
    1583: }

    1585: /*
    1586:   VecStashViewFromOptions - Processes command line options to determine if/how an VecStash object is to be viewed.

    1588:   Collective on VecStash

    1590:   Input Parameters:
    1591: + obj   - the VecStash object
    1592: . bobj - optional other object that provides the prefix
    1593: - optionname - option to activate viewing

    1595:   Level: intermediate

    1597:   Developer Note: This cannot use PetscObjectViewFromOptions() because it takes a Vec as an argument but does not use VecView

    1599: */
    1600: PetscErrorCode VecStashViewFromOptions(Vec obj,PetscObject bobj,const char optionname[])
    1601: {
    1602:   PetscViewer       viewer;
    1603:   PetscBool         flg;
    1604:   PetscViewerFormat format;
    1605:   char              *prefix;

    1607:   prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
    1608:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj),((PetscObject)obj)->options,prefix,optionname,&viewer,&format,&flg);
    1609:   if (flg) {
    1610:     PetscViewerPushFormat(viewer,format);
    1611:     VecStashView(obj,viewer);
    1612:     PetscViewerPopFormat(viewer);
    1613:     PetscViewerDestroy(&viewer);
    1614:   }
    1615:   return 0;
    1616: }

    1618: /*@
    1619:    VecStashView - Prints the entries in the vector stash and block stash.

    1621:    Collective on Vec

    1623:    Input Parameters:
    1624: +  v - the vector
    1625: -  viewer - the viewer

    1627:    Level: advanced

    1629: .seealso: VecSetBlockSize(), VecSetValues(), VecSetValuesBlocked()

    1631: @*/
    1632: PetscErrorCode  VecStashView(Vec v,PetscViewer viewer)
    1633: {
    1634:   PetscMPIInt  rank;
    1635:   PetscInt     i,j;
    1636:   PetscBool    match;
    1637:   VecStash    *s;
    1638:   PetscScalar  val;

    1644:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&match);
    1646:   PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
    1647:   MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
    1648:   s = &v->bstash;

    1650:   /* print block stash */
    1651:   PetscViewerASCIIPushSynchronized(viewer);
    1652:   PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n",rank,s->n,s->bs);
    1653:   for (i=0; i<s->n; i++) {
    1654:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %" PetscInt_FMT " ",rank,s->idx[i]);
    1655:     for (j=0; j<s->bs; j++) {
    1656:       val = s->array[i*s->bs+j];
    1657: #if defined(PETSC_USE_COMPLEX)
    1658:       PetscViewerASCIISynchronizedPrintf(viewer,"(%18.16e %18.16e) ",(double)PetscRealPart(val),(double)PetscImaginaryPart(val));
    1659: #else
    1660:       PetscViewerASCIISynchronizedPrintf(viewer,"%18.16e ",(double)val);
    1661: #endif
    1662:     }
    1663:     PetscViewerASCIISynchronizedPrintf(viewer,"\n");
    1664:   }
    1665:   PetscViewerFlush(viewer);

    1667:   s = &v->stash;

    1669:   /* print basic stash */
    1670:   PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Vector stash size %" PetscInt_FMT "\n",rank,s->n);
    1671:   for (i=0; i<s->n; i++) {
    1672:     val = s->array[i];
    1673: #if defined(PETSC_USE_COMPLEX)
    1674:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ",rank,s->idx[i],(double)PetscRealPart(val),(double)PetscImaginaryPart(val));
    1675: #else
    1676:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %" PetscInt_FMT " %18.16e\n",rank,s->idx[i],(double)val);
    1677: #endif
    1678:   }
    1679:   PetscViewerFlush(viewer);
    1680:   PetscViewerASCIIPopSynchronized(viewer);
    1681:   PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
    1682:   return 0;
    1683: }

    1685: PetscErrorCode PetscOptionsGetVec(PetscOptions options,const char prefix[],const char key[],Vec v,PetscBool *set)
    1686: {
    1687:   PetscInt       i,N,rstart,rend;
    1688:   PetscScalar    *xx;
    1689:   PetscReal      *xreal;
    1690:   PetscBool      iset;

    1692:   VecGetOwnershipRange(v,&rstart,&rend);
    1693:   VecGetSize(v,&N);
    1694:   PetscCalloc1(N,&xreal);
    1695:   PetscOptionsGetRealArray(options,prefix,key,xreal,&N,&iset);
    1696:   if (iset) {
    1697:     VecGetArray(v,&xx);
    1698:     for (i=rstart; i<rend; i++) xx[i-rstart] = xreal[i];
    1699:     VecRestoreArray(v,&xx);
    1700:   }
    1701:   PetscFree(xreal);
    1702:   if (set) *set = iset;
    1703:   return 0;
    1704: }

    1706: /*@
    1707:    VecGetLayout - get PetscLayout describing vector layout

    1709:    Not Collective

    1711:    Input Parameter:
    1712: .  x - the vector

    1714:    Output Parameter:
    1715: .  map - the layout

    1717:    Level: developer

    1719: .seealso: VecGetSizes(), VecGetOwnershipRange(), VecGetOwnershipRanges()
    1720: @*/
    1721: PetscErrorCode VecGetLayout(Vec x,PetscLayout *map)
    1722: {
    1725:   *map = x->map;
    1726:   return 0;
    1727: }

    1729: /*@
    1730:    VecSetLayout - set PetscLayout describing vector layout

    1732:    Not Collective

    1734:    Input Parameters:
    1735: +  x - the vector
    1736: -  map - the layout

    1738:    Notes:
    1739:    It is normally only valid to replace the layout with a layout known to be equivalent.

    1741:    Level: developer

    1743: .seealso: VecGetLayout(), VecGetSizes(), VecGetOwnershipRange(), VecGetOwnershipRanges()
    1744: @*/
    1745: PetscErrorCode VecSetLayout(Vec x,PetscLayout map)
    1746: {
    1748:   PetscLayoutReference(map,&x->map);
    1749:   return 0;
    1750: }

    1752: PetscErrorCode VecSetInf(Vec xin)
    1753: {
    1754:   PetscInt       i,n = xin->map->n;
    1755:   PetscScalar    *xx;
    1756:   PetscScalar    zero=0.0,one=1.0,inf=one/zero;

    1758:   if (xin->ops->set) { /* can be called by a subset of processes, do not use collective routines */
    1759:     (*xin->ops->set)(xin,inf);
    1760:   } else {
    1761:     VecGetArrayWrite(xin,&xx);
    1762:     for (i=0; i<n; i++) xx[i] = inf;
    1763:     VecRestoreArrayWrite(xin,&xx);
    1764:   }
    1765:   return 0;
    1766: }

    1768: /*@
    1769:      VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU

    1771:   Logically collective on Vec

    1773:    Input Parameters:
    1774: +   v - the vector
    1775: -   flg - bind to the CPU if value of PETSC_TRUE

    1777:    Level: intermediate
    1778: @*/
    1779: PetscErrorCode VecBindToCPU(Vec v,PetscBool flg)
    1780: {
    1783: #if defined(PETSC_HAVE_DEVICE)
    1784:   if (v->boundtocpu == flg) return 0;
    1785:   v->boundtocpu = flg;
    1786:   if (v->ops->bindtocpu) {
    1787:     (*v->ops->bindtocpu)(v,flg);
    1788:   }
    1789: #endif
    1790:   return 0;
    1791: }

    1793: /*@
    1794:      VecBoundToCPU - query if a vector is bound to the CPU

    1796:   Not collective

    1798:    Input Parameter:
    1799: .   v - the vector

    1801:    Output Parameter:
    1802: .   flg - the logical flag

    1804:    Level: intermediate

    1806: .seealso: VecBindToCPU()
    1807: @*/
    1808: PetscErrorCode VecBoundToCPU(Vec v,PetscBool *flg)
    1809: {
    1812: #if defined(PETSC_HAVE_DEVICE)
    1813:   *flg = v->boundtocpu;
    1814: #else
    1815:   *flg = PETSC_TRUE;
    1816: #endif
    1817:   return 0;
    1818: }

    1820: /*@
    1821:    VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects

    1823:    Input Parameters:
    1824: +  v - the vector
    1825: -  flg - flag indicating whether the boundtocpu flag should be propagated

    1827:    Level: developer

    1829:    Notes:
    1830:    If the value of flg is set to true, then VecDuplicate() and VecDuplicateVecs() will bind created vectors to GPU if the input vector is bound to the CPU.
    1831:    The created vectors will also have their bindingpropagates flag set to true.

    1833:    Developer Notes:
    1834:    If a DMDA has the -dm_bind_below option set to true, then vectors created by DMCreateGlobalVector() will have VecSetBindingPropagates() called on them to
    1835:    set their bindingpropagates flag to true.

    1837: .seealso: MatSetBindingPropagates(), VecGetBindingPropagates()
    1838: @*/
    1839: PetscErrorCode VecSetBindingPropagates(Vec v,PetscBool flg)
    1840: {
    1842: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1843:   v->bindingpropagates = flg;
    1844: #endif
    1845:   return 0;
    1846: }

    1848: /*@
    1849:    VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects

    1851:    Input Parameter:
    1852: .  v - the vector

    1854:    Output Parameter:
    1855: .  flg - flag indicating whether the boundtocpu flag will be propagated

    1857:    Level: developer

    1859: .seealso: VecSetBindingPropagates()
    1860: @*/
    1861: PetscErrorCode VecGetBindingPropagates(Vec v,PetscBool *flg)
    1862: {
    1865: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
    1866:   *flg = v->bindingpropagates;
    1867: #else
    1868:   *flg = PETSC_FALSE;
    1869: #endif
    1870:   return 0;
    1871: }

    1873: /*@C
    1874:   VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.

    1876:   Logically Collective on Vec

    1878:   Input Parameters:
    1879: +  v    - the vector
    1880: -  mbytes - minimum data size in bytes

    1882:   Options Database Keys:

    1884: . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
    1885:                                   Note that this takes a PetscScalar, to accommodate large values;
    1886:                                   specifying -1 ensures that pinned memory will never be used.

    1888:   Level: developer

    1890: .seealso: VecGetPinnedMemoryMin()
    1891: @*/
    1892: PetscErrorCode VecSetPinnedMemoryMin(Vec v,size_t mbytes)
    1893: {
    1894: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
    1895:   v->minimum_bytes_pinned_memory = mbytes;
    1896:   return 0;
    1897: #else
    1898:   return 0;
    1899: #endif
    1900: }

    1902: /*@C
    1903:   VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.

    1905:   Logically Collective on Vec

    1907:   Input Parameters:
    1908: .  v    - the vector

    1910:   Output Parameters:
    1911: .  mbytes - minimum data size in bytes

    1913:   Level: developer

    1915: .seealso: VecSetPinnedMemoryMin()
    1916: @*/
    1917: PetscErrorCode VecGetPinnedMemoryMin(Vec v,size_t *mbytes)
    1918: {
    1919: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
    1920:   *mbytes = v->minimum_bytes_pinned_memory;
    1921:   return 0;
    1922: #else
    1923:   return 0;
    1924: #endif
    1925: }

    1927: /*@
    1928:   VecGetOffloadMask - Get the offload mask of a Vec.

    1930:   Not Collective

    1932:   Input Parameters:
    1933: .   v - the vector

    1935:   Output Parameters:
    1936: .   mask - corresponding PetscOffloadMask enum value.

    1938:    Level: intermediate

    1940: .seealso: VecCreateSeqCUDA(), VecCreateSeqViennaCL(), VecGetArray(), VecGetType()
    1941: @*/
    1942: PetscErrorCode VecGetOffloadMask(Vec v,PetscOffloadMask* mask)
    1943: {
    1944:   *mask = v->offloadmask;
    1945:   return 0;
    1946: }

    1948: #if !defined(PETSC_HAVE_VIENNACL)
    1949: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v,PETSC_UINTPTR_T* ctx)
    1950: {
    1951:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_context");
    1952: }

    1954: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v,PETSC_UINTPTR_T* queue)
    1955: {
    1956:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
    1957: }

    1959: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v,PETSC_UINTPTR_T* queue)
    1960: {
    1961:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
    1962: }

    1964: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v,PETSC_UINTPTR_T* queue)
    1965: {
    1966:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
    1967: }

    1969: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v,PETSC_UINTPTR_T* queue)
    1970: {
    1971:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
    1972: }

    1974: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
    1975: {
    1976:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
    1977: }
    1978: #endif