Actual source code: binv.c

petsc-3.5.4 2015-05-23
Report Typos and Errors
  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:   } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get singleton viewer for binary files or sockets");
 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:   PetscMalloc1((n+1),&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:   PetscMalloc1(n,&sizes);
898:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
899:   for (i=0; i<n; i++) N += sizes[i];
900:   PetscMalloc1((n+1)*sizeof(char*) + N,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,&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__,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__,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__,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__,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__,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__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1345:     PetscObjectRegisterDestroy((PetscObject)viewer);
1346:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,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__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1349:   }
1350:   PetscCommDestroy(&ncomm);
1351:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1352:   PetscFunctionReturn(viewer);
1353: }