Date: 2013-07-02T14:38:05+00:00

Actual source code: binv.c
petsc-3.4.2 2013-07-02

      2: #include <petsc-private/viewerimpl.h>    /*I   "petscviewer.h"   I*/
      3: #include <fcntl.h>
      4: #if defined(PETSC_HAVE_UNISTD_H)
      5: #include <unistd.h>
      6: #endif
      7: #if defined(PETSC_HAVE_IO_H)
      8: #include <io.h>
      9: #endif

     11: typedef struct  {
     12:   int           fdes;                 /* file descriptor, ignored if using MPI IO */
     13: #if defined(PETSC_HAVE_MPIIO)
     14:   PetscBool     MPIIO;
     15:   MPI_File      mfdes;                /* ignored unless using MPI IO */
     16:   MPI_Offset    moff;
     17: #endif
     18:   PetscFileMode btype;                /* read or write? */
     19:   FILE          *fdes_info;           /* optional file containing info on binary file*/
     20:   PetscBool     storecompressed;      /* gzip the write binary file when closing it*/
     21:   char          *filename;
     22:   PetscBool     skipinfo;             /* Don't create info file for writing; don't use for reading */
     23:   PetscBool     skipoptions;          /* don't use PETSc options database when loading */
     24:   PetscInt      flowcontrol;          /* allow only <flowcontrol> messages outstanding at a time while doing IO */
     25:   PetscBool     skipheader;           /* don't write header, only raw data */
     26:   PetscBool     matlabheaderwritten;  /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
     27: } PetscViewer_Binary;

     31: PetscErrorCode PetscViewerGetSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
     32: {
     33:   int                rank;
     34:   PetscErrorCode     ierr;
     35:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;

     38:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
     39:   if (!rank) {
     40:     PetscViewerCreate(PETSC_COMM_SELF,outviewer);
     41:     PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
     42:     obinary = (PetscViewer_Binary*)(*outviewer)->data;
     43:     PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
     44:   } else *outviewer = 0;
     45:   return(0);
     46: }

     50: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
     51: {
     53:   PetscErrorCode rank;

     56:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
     57:   if (!rank) {
     58:     PetscFree((*outviewer)->data);
     59:     PetscHeaderDestroy(outviewer);
     60:   }
     61:   return(0);
     62: }

     64: #if defined(PETSC_HAVE_MPIIO)
     67: /*@C
     68:     PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()

     70:     Not Collective

     72:     Input Parameter:
     73: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

     75:     Output Parameter:
     76: .    off - the current offset

     78:     Level: advanced

     80:     Fortran Note:
     81:     This routine is not supported in Fortran.

     83:     Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.

     85:   Concepts: file descriptor^getting
     86:   Concepts: PetscViewerBinary^accessing file descriptor

     88: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
     89: @*/
     90: PetscErrorCode  PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
     91: {
     92:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

     95:   *off = vbinary->moff;
     96:   return(0);
     97: }

    101: /*@C
    102:     PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()

    104:     Not Collective

    106:     Input Parameters:
    107: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
    108: -    off - the addition to the offset

    110:     Level: advanced

    112:     Fortran Note:
    113:     This routine is not supported in Fortran.

    115:     Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()

    117:   Concepts: file descriptor^getting
    118:   Concepts: PetscViewerBinary^accessing file descriptor

    120: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
    121: @*/
    122: PetscErrorCode  PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
    123: {
    124:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    127:   vbinary->moff += off;
    128:   return(0);
    129: }

    133: /*@C
    134:     PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.

    136:     Not Collective

    138:     Input Parameter:
    139: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    141:     Output Parameter:
    142: .   fdes - file descriptor

    144:     Level: advanced

    146:     Fortran Note:
    147:     This routine is not supported in Fortran.

    149:   Concepts: file descriptor^getting
    150:   Concepts: PetscViewerBinary^accessing file descriptor

    152: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
    153: @*/
    154: PetscErrorCode  PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
    155: {
    156:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    159:   *fdes = vbinary->mfdes;
    160:   return(0);
    161: }

    165: /*@C
    166:     PetscViewerBinaryGetMPIIO - Returns PETSC_TRUE if the binary viewer is an MPI viewer.

    168:     Not Collective

    170:     Input Parameter:
    171: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    173:     Output Parameter:
    174: -   flg - PETSC_TRUE if MPI IO is being used

    176:     Options Database:
    177:     -viewer_binary_mpiio : Flag for using MPI-IO

    179:     Level: advanced

    181:     Fortran Note:
    182:     This routine is not supported in Fortran.

    184:   Concepts: file descriptor^getting
    185:   Concepts: PetscViewerBinary^accessing file descriptor

    187: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
    188: @*/
    189: PetscErrorCode  PetscViewerBinaryGetMPIIO(PetscViewer viewer,PetscBool  *flg)
    190: {
    191:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    194:   *flg = vbinary->MPIIO;
    195:   return(0);
    196: }
    197: #endif

    201: PetscErrorCode  PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
    202: {
    203:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    206:   *fc = vbinary->flowcontrol;
    207:   return(0);
    208: }

    212: /*@C
    213:     PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes

    215:     Not Collective

    217:     Input Parameter:
    218: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    220:     Output Parameter:
    221: .   fc - the number of messages

    223:     Level: advanced

    225: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()

    227: @*/
    228: PetscErrorCode  PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
    229: {
    230:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    231:   PetscErrorCode     ierr;

    234:   *fc  = vbinary->flowcontrol;
    235:   PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
    236:   return(0);
    237: }

    241: PetscErrorCode  PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
    242: {
    243:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    246:   if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
    247:   vbinary->flowcontrol = fc;
    248:   return(0);
    249: }

    253: /*@C
    254:     PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes

    256:     Not Collective

    258:     Input Parameter:
    259: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
    260: -   fc - the number of messages, defaults to 256 if this function was not called

    262:     Level: advanced

    264: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()

    266: @*/
    267: PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
    268: {

    272:   PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
    273:   return(0);
    274: }

    278: /*@C
    279:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

    281:     Not Collective

    283:     Input Parameter:
    284: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    286:     Output Parameter:
    287: .   fdes - file descriptor

    289:     Level: advanced

    291:     Notes:
    292:       For writable binary PetscViewers, the descriptor will only be valid for the
    293:     first processor in the communicator that shares the PetscViewer. For readable
    294:     files it will only be valid on nodes that have the file. If node 0 does not
    295:     have the file it generates an error even if another node does have the file.

    297:     Fortran Note:
    298:     This routine is not supported in Fortran.

    300:   Concepts: file descriptor^getting
    301:   Concepts: PetscViewerBinary^accessing file descriptor

    303: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
    304: @*/
    305: PetscErrorCode  PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
    306: {
    307:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    310:   *fdes = vbinary->fdes;
    311:   return(0);
    312: }

    316: /*@
    317:     PetscViewerBinarySkipInfo - Binary file will not have .info file created with it

    319:     Not Collective

    321:     Input Paramter:
    322: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

    324:     Options Database Key:
    325: .   -viewer_binary_skip_info

    327:     Level: advanced

    329:     Notes: This must be called after PetscViewerSetType() but before PetscViewerFileSetName(). If you use PetscViewerBinaryOpen() then
    330:     you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
    331:     viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerFileSetName().

    333:     The .info contains meta information about the data in the binary file, for example the block size if it was
    334:     set for a vector or matrix.

    336:    Concepts: PetscViewerBinary^accessing info file

    338: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
    339:           PetscViewerBinaryGetSkipOptions()
    340: @*/
    341: PetscErrorCode  PetscViewerBinarySkipInfo(PetscViewer viewer)
    342: {
    343:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    346:   vbinary->skipinfo = PETSC_TRUE;
    347:   return(0);
    348: }

    352: /*@
    353:     PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects

    355:     Not Collective

    357:     Input Parameters:
    358: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
    359: -   skip - PETSC_TRUE means do not use

    361:     Options Database Key:
    362: .   -viewer_binary_skip_options

    364:     Level: advanced

    366:     Notes: This must be called after PetscViewerSetType()

    368:    Concepts: PetscViewerBinary^accessing info file

    370: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
    371:           PetscViewerBinaryGetSkipOptions()
    372: @*/
    373: PetscErrorCode  PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
    374: {
    375:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    378:   vbinary->skipoptions = skip;
    379:   return(0);
    380: }

    384: /*@
    385:     PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects

    387:     Not Collective

    389:     Input Parameter:
    390: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    392:     Output Parameter:
    393: .   skip - PETSC_TRUE means do not use

    395:     Level: advanced

    397:     Notes: This must be called after PetscViewerSetType()

    399:    Concepts: PetscViewerBinary^accessing info file

    401: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
    402:           PetscViewerBinarySetSkipOptions()
    403: @*/
    404: PetscErrorCode  PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool  *skip)
    405: {
    406:   PetscViewer_Binary *vbinary;

    410:   vbinary = (PetscViewer_Binary*)viewer->data;
    411:   *skip   = vbinary->skipoptions;
    412:   return(0);
    413: }

    417: PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
    418: {
    419:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    422:   vbinary->skipheader = skip;
    423:   return(0);
    424: }

    428: /*@
    429:     PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data

    431:     Not Collective

    433:     Input Parameters:
    434: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
    435: -   skip - PETSC_TRUE means do not write header

    437:     Options Database Key:
    438: .   -viewer_binary_skip_header

    440:     Level: advanced

    442:     Notes: This must be called after PetscViewerSetType()

    444:            Can ONLY be called on a binary viewer

    446: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
    447:           PetscViewerBinaryGetSkipHeader()
    448: @*/
    449: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
    450: {

    454:   PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
    455:   return(0);
    456: }

    460: PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool  *skip)
    461: {
    462:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    465:   *skip = vbinary->skipheader;
    466:   return(0);
    467: }

    471: /*@
    472:     PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data

    474:     Not Collective

    476:     Input Parameter:
    477: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    479:     Output Parameter:
    480: .   skip - PETSC_TRUE means do not write header

    482:     Level: advanced

    484:     Notes: This must be called after PetscViewerSetType()

    486:             Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.

    488: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
    489:           PetscViewerBinarySetSkipHeader()
    490: @*/
    491: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
    492: {

    496:   *skip = PETSC_FALSE;
    497:   PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
    498:   return(0);
    499: }

    503: PetscErrorCode  PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
    504: {
    505:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    506:   PetscErrorCode     ierr;
    507:   MPI_Comm           comm;

    510:   *file = vbinary->fdes_info;
    511:   if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
    512:     vbinary->matlabheaderwritten = PETSC_TRUE;
    513:     PetscObjectGetComm((PetscObject)viewer,&comm);
    514:     PetscFPrintf(comm,*file,"%%--- begin code written by PetscViewerBinary for MATLAB format ---%\n");
    515:     PetscFPrintf(comm,*file,"%%$$ Set.filename = '%s';\n",vbinary->filename);
    516:     PetscFPrintf(comm,*file,"%%$$ fd = PetscOpenFile(Set.filename);\n");
    517:     PetscFPrintf(comm,*file,"%%--- end code written by PetscViewerBinary for MATLAB format ---%\n\n");
    518:   }
    519:   return(0);
    520: }

    524: /*@C
    525:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
    526:           info file associated with a binary file.

    528:     Not Collective

    530:     Input Parameter:
    531: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

    533:     Output Parameter:
    534: .   file - file pointer  Always returns NULL if not a binary viewer

    536:     Level: advanced

    538:     Notes:
    539:       For writable binary PetscViewers, the descriptor will only be valid for the
    540:     first processor in the communicator that shares the PetscViewer.

    542:     Fortran Note:
    543:     This routine is not supported in Fortran.

    545:   Concepts: PetscViewerBinary^accessing info file

    547: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
    548: @*/
    549: PetscErrorCode  PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
    550: {

    554:   *file = NULL;
    555:   PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
    556:   return(0);
    557: }

    561: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
    562: {
    563:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
    564:   PetscErrorCode     ierr;
    565:   PetscMPIInt        rank;
    566:   int                err;

    569:   MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
    570:   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
    571:     close(vbinary->fdes);
    572:     if (!rank && vbinary->storecompressed) {
    573:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
    574:       FILE *fp;
    575:       /* compress the file */
    576:       PetscStrcpy(par,"gzip -f ");
    577:       PetscStrcat(par,vbinary->filename);
    578: #if defined(PETSC_HAVE_POPEN)
    579:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
    580:       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
    581:       PetscPClose(PETSC_COMM_SELF,fp,NULL);
    582: #else
    583:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
    584: #endif
    585:     }
    586:   }
    587:   if (vbinary->fdes_info) {
    588:     err = fclose(vbinary->fdes_info);
    589:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
    590:   }
    591:   PetscFree(vbinary->filename);
    592:   return(0);
    593: }

    597: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
    598: {
    599:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
    600:   PetscErrorCode     ierr;

    603:   if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
    604:     MPI_Comm comm;
    605:     FILE     *info;

    607:     PetscObjectGetComm((PetscObject)v,&comm);
    608:     PetscViewerBinaryGetInfoPointer(v,&info);
    609:     PetscFPrintf(comm,info,"%%--- begin code written by PetscViewerBinary for MATLAB format ---%\n");
    610:     PetscFPrintf(comm,info,"%%$$ close(fd);\n");
    611:     PetscFPrintf(comm,info,"%%--- end code written by PetscViewerBinary for MATLAB format ---%\n\n");
    612:   }
    613:   PetscViewerFileClose_Binary(v);
    614:   PetscFree(vbinary);
    615:   return(0);
    616: }

    618: #if defined(PETSC_HAVE_MPIIO)
    621: static PetscErrorCode PetscViewerFileClose_MPIIO(PetscViewer v)
    622: {
    623:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
    624:   int                err;
    625:   PetscErrorCode     ierr;

    628:   if (vbinary->mfdes) {
    629:     MPI_File_close(&vbinary->mfdes);
    630:   }
    631:   if (vbinary->fdes_info) {
    632:     err = fclose(vbinary->fdes_info);
    633:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
    634:   }
    635:   PetscFree(vbinary->filename);
    636:   return(0);
    637: }

    642: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
    643: {
    644:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
    645:   PetscErrorCode     ierr;

    648:   PetscViewerFileClose_MPIIO(v);
    649:   PetscFree(vbinary);
    650:   return(0);
    651: }
    652: #endif

    656: /*@C
    657:    PetscViewerBinaryOpen - Opens a file for binary input/output.

    659:    Collective on MPI_Comm

    661:    Input Parameters:
    662: +  comm - MPI communicator
    663: .  name - name of file
    664: -  type - type of file
    665: $    FILE_MODE_WRITE - create new file for binary output
    666: $    FILE_MODE_READ - open existing file for binary input
    667: $    FILE_MODE_APPEND - open existing file for binary output

    669:    Output Parameter:
    670: .  binv - PetscViewer for binary input/output to use with the specified file

    672:     Options Database Keys:
    673: +    -viewer_binary_skip_info
    674: .    -viewer_binary_skip_options
    675: -    -viewer_binary_skip_header

    677:    Level: beginner

    679:    Note:
    680:    This PetscViewer should be destroyed with PetscViewerDestroy().

    682:     For reading files, the filename may begin with ftp:// or http:// and/or
    683:     end with .gz; in this case file is brought over and uncompressed.

    685:     For creating files, if the file name ends with .gz it is automatically
    686:     compressed when closed.

    688:     For writing files it only opens the file on processor 0 in the communicator.
    689:     For readable files it opens the file on all nodes that have the file. If
    690:     node 0 does not have the file it generates an error even if other nodes
    691:     do have the file.

    693:    Concepts: binary files
    694:    Concepts: PetscViewerBinary^creating
    695:    Concepts: gzip
    696:    Concepts: accessing remote file
    697:    Concepts: remote file

    699: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
    700:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    701:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
    702: @*/
    703: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
    704: {

    708:   PetscViewerCreate(comm,binv);
    709:   PetscViewerSetType(*binv,PETSCVIEWERBINARY);
    710:   PetscViewerFileSetMode(*binv,type);
    711:   PetscViewerFileSetName(*binv,name);
    712:   return(0);
    713: }

    715: #if defined(PETSC_HAVE_MPIIO)
    718: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool write)
    719: {
    720:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    721:   PetscErrorCode     ierr;
    722:   MPI_Datatype       mdtype;
    723:   PetscMPIInt        cnt;
    724:   MPI_Status         status;
    725:   MPI_Aint           ul,dsize;

    728:   PetscMPIIntCast(count,&cnt);
    729:   PetscDataTypeToMPIDataType(dtype,&mdtype);
    730:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
    731:   if (write) {
    732:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
    733:   } else {
    734:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
    735:   }
    736:   MPI_Type_get_extent(mdtype,&ul,&dsize);

    738:   vbinary->moff += dsize*cnt;
    739:   return(0);
    740: }
    741: #endif

    745: /*@C
    746:    PetscViewerBinaryRead - Reads from a binary file, all processors get the same result

    748:    Collective on MPI_Comm

    750:    Input Parameters:
    751: +  viewer - the binary viewer
    752: .  data - location to write the data
    753: .  count - number of items of data to read
    754: -  datatype - type of data to read

    756:    Level: beginner

    758:    Concepts: binary files

    760: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
    761:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    762:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
    763: @*/
    764: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
    765: {
    766:   PetscErrorCode     ierr;
    767:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    769: #if defined(PETSC_HAVE_MPIIO)
    770:   if (vbinary->MPIIO) {
    771:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
    772:   } else {
    773: #endif
    774:     PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);
    775: #if defined(PETSC_HAVE_MPIIO)
    776:   }
    777: #endif
    778:   return(0);
    779: }

    784: /*@C
    785:    PetscViewerBinaryWrite - writes to a binary file, only from the first process

    787:    Collective on MPI_Comm

    789:    Input Parameters:
    790: +  viewer - the binary viewer
    791: .  data - location of data
    792: .  count - number of items of data to read
    793: .  dtype - type of data to read
    794: -  istemp - data may be overwritten

    796:    Level: beginner

    798:    Notes: because byte-swapping may be done on the values in data it cannot be declared const

    800:    Concepts: binary files

    802: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
    803:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
    804:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
    805: @*/
    806: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
    807: {
    808:   PetscErrorCode     ierr;
    809:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    812: #if defined(PETSC_HAVE_MPIIO)
    813:   if (vbinary->MPIIO) {
    814:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
    815:   } else {
    816: #endif
    817:     PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
    818: #if defined(PETSC_HAVE_MPIIO)
    819:   }
    820: #endif
    821:   return(0);
    822: }

    826: /*@C
    827:    PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings

    829:    Collective on MPI_Comm

    831:    Input Parameters:
    832: +  viewer - the binary viewer
    833: -  data - location of the array of strings

    836:    Level: intermediate

    838:    Concepts: binary files

    840:     Notes: array of strings is null terminated

    842: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
    843:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    844:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
    845: @*/
    846: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
    847: {
    849:   PetscInt       i,n = 0,*sizes;

    851:   /* count number of strings */
    852:   while (data[n++]) ;
    853:   n--;
    854:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
    855:   sizes[0] = n;
    856:   for (i=0; i<n; i++) {
    857:     size_t tmp;
    858:     PetscStrlen(data[i],&tmp);
    859:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
    860:   }
    861:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
    862:   for (i=0; i<n; i++) {
    863:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
    864:   }
    865:   PetscFree(sizes);
    866:   return(0);
    867: }

    869: /*@C
    870:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

    872:    Collective on MPI_Comm

    874:    Input Parameter:
    875: .  viewer - the binary viewer

    877:    Output Parameter:
    878: .  data - location of the array of strings

    880:    Level: intermediate

    882:    Concepts: binary files

    884:     Notes: array of strings is null terminated

    886: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
    887:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    888:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
    889: @*/
    890: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
    891: {
    893:   PetscInt       i,n,*sizes,N = 0;

    895:   /* count number of strings */
    896:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
    897:   PetscMalloc(n*sizeof(PetscInt),&sizes);
    898:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
    899:   for (i=0; i<n; i++) N += sizes[i];
    900:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
    901:   (*data)[0] = (char*)((*data) + n + 1);
    902:   for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
    903:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);

    905:   (*data)[n] = 0;

    907:   PetscFree(sizes);
    908:   return(0);
    909: }

    913: PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
    914: {
    915:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    918:   *name = vbinary->filename;
    919:   return(0);
    920: }

    924: /*@C
    925:      PetscViewerFileGetMode - Gets the type of file to be open

    927:     Not Collective

    929:   Input Parameter:
    930: .  viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer

    932:   Output Parameter:
    933: .  type - type of file
    934: $    FILE_MODE_WRITE - create new file for binary output
    935: $    FILE_MODE_READ - open existing file for binary input
    936: $    FILE_MODE_APPEND - open existing file for binary output

    938:   Level: advanced

    940: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

    942: @*/
    943: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
    944: {

    950:   PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
    951:   return(0);
    952: }

    956: /*@
    957:      PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called
    958:         before PetscViewerFileSetName()

    960:     Logically Collective on PetscViewer

    962:   Input Parameters:
    963: .  viewer - the PetscViewer; must be a binary

    965:     Options Database:
    966:     -viewer_binary_mpiio : Flag for using MPI-IO

    968:   Level: advanced

    970: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

    972: @*/
    973: PetscErrorCode  PetscViewerBinarySetMPIIO(PetscViewer viewer)
    974: {

    979:   PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));
    980:   return(0);
    981: }

    986: /*@C
    987:      PetscViewerFileSetMode - Sets the type of file to be open

    989:     Logically Collective on PetscViewer

    991:   Input Parameters:
    992: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
    993: -  type - type of file
    994: $    FILE_MODE_WRITE - create new file for binary output
    995: $    FILE_MODE_READ - open existing file for binary input
    996: $    FILE_MODE_APPEND - open existing file for binary output

    998:   Level: advanced

    1000: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()

    1002: @*/
    1003: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
    1004: {

    1010:   PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
    1011:   return(0);
    1012: }

    1016: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
    1017: {
    1018:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    1021:   *type = vbinary->btype;
    1022:   return(0);
    1023: }

    1027: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
    1028: {
    1029:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

    1032:   vbinary->btype = type;
    1033:   return(0);
    1034: }

    1036: /*
    1037:         Actually opens the file
    1038: */
    1041: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
    1042: {
    1043:   PetscMPIInt        rank;
    1044:   PetscErrorCode     ierr;
    1045:   size_t             len;
    1046:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    1047:   const char         *fname;
    1048:   char               bname[PETSC_MAX_PATH_LEN],*gz;
    1049:   PetscBool          found;
    1050:   PetscFileMode      type = vbinary->btype;

    1053:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
    1054:   PetscViewerFileClose_Binary(viewer);
    1055:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);
    1056:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);
    1057:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,NULL);

    1059:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);

    1061:   /* copy name so we can edit it */
    1062:   PetscStrallocpy(name,&vbinary->filename);

    1064:   /* if ends in .gz strip that off and note user wants file compressed */
    1065:   vbinary->storecompressed = PETSC_FALSE;
    1066:   if (!rank && type == FILE_MODE_WRITE) {
    1067:     /* remove .gz if it ends library name */
    1068:     PetscStrstr(vbinary->filename,".gz",&gz);
    1069:     if (gz) {
    1070:       PetscStrlen(gz,&len);
    1071:       if (len == 3) {
    1072:         *gz = 0;
    1073:         vbinary->storecompressed = PETSC_TRUE;
    1074:       }
    1075:     }
    1076:   }

    1078:   /* only first processor opens file if writeable */
    1079:   if (!rank || type == FILE_MODE_READ) {

    1081:     if (type == FILE_MODE_READ) {
    1082:       /* possibly get the file from remote site or compressed file */
    1083:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
    1084:       fname = bname;
    1085:       if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
    1086:       else if (!found) {
    1087:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
    1088:         fname = 0;
    1089:       }
    1090:     } else fname = vbinary->filename;

    1092: #if defined(PETSC_HAVE_O_BINARY)
    1093:     if (type == FILE_MODE_WRITE) {
    1094:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
    1095:     } else if (type == FILE_MODE_READ && fname) {
    1096:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
    1097:     } else if (type == FILE_MODE_APPEND) {
    1098:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
    1099:     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
    1100: #else
    1101:     if (type == FILE_MODE_WRITE) {
    1102:       if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
    1103:     } else if (type == FILE_MODE_READ && fname) {
    1104:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
    1105:     } else if (type == FILE_MODE_APPEND) {
    1106:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
    1107:     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
    1108: #endif
    1109:   } else vbinary->fdes = -1;

    1111:   /*
    1112:       try to open info file: all processors open this file if read only
    1113:   */
    1114:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
    1115:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];

    1117:     PetscStrcpy(infoname,name);
    1118:     /* remove .gz if it ends library name */
    1119:     PetscStrstr(infoname,".gz",&gz);
    1120:     if (gz) {
    1121:       PetscStrlen(gz,&len);
    1122:       if (len == 3) *gz = 0;
    1123:     }

    1125:     PetscStrcat(infoname,".info");
    1126:     PetscFixFilename(infoname,iname);
    1127:     if (type == FILE_MODE_READ) {
    1128:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
    1129:       PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);
    1130:     } else {
    1131:       vbinary->fdes_info = fopen(infoname,"w");
    1132:       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
    1133:     }
    1134:   }

    1136: #if defined(PETSC_USE_LOG)
    1137:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    1138: #endif
    1139:   return(0);
    1140: }

    1142: #if defined(PETSC_HAVE_MPIIO)
    1145: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
    1146: {
    1147:   PetscMPIInt        rank;
    1148:   PetscErrorCode     ierr;
    1149:   size_t             len;
    1150:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    1151:   char               *gz;
    1152:   PetscBool          found;
    1153:   PetscFileMode      type = vbinary->btype;

    1156:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
    1157:   PetscViewerFileClose_MPIIO(viewer);
    1158:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);
    1159:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);

    1161:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    1162:   PetscStrallocpy(name,&vbinary->filename);

    1164:   vbinary->storecompressed = PETSC_FALSE;

    1166:   /* only first processor opens file if writeable */
    1167:   if (type == FILE_MODE_READ) {
    1168:     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
    1169:   } else if (type == FILE_MODE_WRITE) {
    1170:     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
    1171:   }

    1173:   /*
    1174:       try to open info file: all processors open this file if read only

    1176:       Below is identical code to the code for Binary above, should be put in seperate routine
    1177:   */
    1178:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
    1179:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];

    1181:     PetscStrcpy(infoname,name);
    1182:     /* remove .gz if it ends library name */
    1183:     PetscStrstr(infoname,".gz",&gz);
    1184:     if (gz) {
    1185:       PetscStrlen(gz,&len);
    1186:       if (len == 3) *gz = 0;
    1187:     }

    1189:     PetscStrcat(infoname,".info");
    1190:     PetscFixFilename(infoname,iname);
    1191:     if (type == FILE_MODE_READ) {
    1192:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
    1193:       PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);
    1194:     } else {
    1195:       vbinary->fdes_info = fopen(infoname,"w");
    1196:       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
    1197:     }
    1198:   }

    1200: #if defined(PETSC_USE_LOG)
    1201:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    1202: #endif
    1203:   return(0);
    1204: }

    1208: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
    1209: {
    1210:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
    1211:   PetscErrorCode     ierr;

    1214:   if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
    1215:   viewer->ops->destroy = PetscViewerDestroy_MPIIO;
    1216:   vbinary->MPIIO       = PETSC_TRUE;
    1217:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_MPIIO);
    1218:   return(0);
    1219: }
    1220: #endif

    1224: PetscErrorCode  PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
    1225: {
    1226:   PetscErrorCode     ierr;
    1227:   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;

    1230:   if (binary->filename) {
    1231:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
    1232:   }
    1233:   return(0);
    1234: }

    1238: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
    1239: {
    1240:   PetscErrorCode     ierr;
    1241:   PetscViewer_Binary *vbinary;
    1242: #if defined(PETSC_HAVE_MPIIO)
    1243:   PetscBool          useMPIIO = PETSC_FALSE;
    1244: #endif

    1247:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
    1248:   v->data                  = (void*)vbinary;
    1249:   v->ops->destroy          = PetscViewerDestroy_Binary;
    1250:   v->ops->view             = PetscViewerView_Binary;
    1251:   v->ops->flush            = 0;
    1252:   vbinary->fdes_info       = 0;
    1253:   vbinary->fdes            = 0;
    1254:   vbinary->skipinfo        = PETSC_FALSE;
    1255:   vbinary->skipoptions     = PETSC_TRUE;
    1256:   vbinary->skipheader      = PETSC_FALSE;
    1257:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
    1258:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
    1259:   vbinary->btype           = (PetscFileMode) -1;
    1260:   vbinary->storecompressed = PETSC_FALSE;
    1261:   vbinary->filename        = 0;
    1262:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

    1264:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
    1265:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
    1266:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
    1267:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
    1268:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
    1269:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
    1270:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
    1271:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
    1272:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
    1273: #if defined(PETSC_HAVE_MPIIO)
    1274:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C",PetscViewerBinarySetMPIIO_Binary);

    1276:   PetscOptionsGetBool(NULL,"-viewer_binary_mpiio",&useMPIIO,NULL);
    1277:   if (useMPIIO) {
    1278:     PetscViewerBinarySetMPIIO(v);
    1279:   }
    1280: #endif
    1281:   return(0);
    1282: }

    1284: /* ---------------------------------------------------------------------*/
    1285: /*
    1286:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
    1287:   is attached to a communicator, in this case the attribute is a PetscViewer.
    1288: */
    1289: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

    1293: /*@C
    1294:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
    1295:                      in a communicator.

    1297:      Collective on MPI_Comm

    1299:      Input Parameter:
    1300: .    comm - the MPI communicator to share the binary PetscViewer

    1302:      Level: intermediate

    1304:    Options Database Keys:
    1305: +    -viewer_binary_filename <name>
    1306: .    -viewer_binary_skip_info
    1307: -    -viewer_binary_skip_options

    1309:    Environmental variables:
    1310: -   PETSC_VIEWER_BINARY_FILENAME

    1312:      Notes:
    1313:      Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
    1314:      an error code.  The binary PetscViewer is usually used in the form
    1315: $       XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));

    1317: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
    1318:           PetscViewerDestroy()
    1319: @*/
    1320: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
    1321: {
    1323:   PetscBool      flg;
    1324:   PetscViewer    viewer;
    1325:   char           fname[PETSC_MAX_PATH_LEN];
    1326:   MPI_Comm       ncomm;

    1329:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1330:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
    1331:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
    1332:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1333:   }
    1334:   MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
    1335:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1336:   if (!flg) { /* PetscViewer not yet created */
    1337:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
    1338:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1339:     if (!flg) {
    1340:       PetscStrcpy(fname,"binaryoutput");
    1341:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1342:     }
    1343:     PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
    1344:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1345:     PetscObjectRegisterDestroy((PetscObject)viewer);
    1346:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1347:     MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
    1348:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1349:   }
    1350:   PetscCommDestroy(&ncomm);
    1351:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
    1352:   PetscFunctionReturn(viewer);
    1353: }