Actual source code: binv.c

petsc-3.3-p5 2012-12-01
  2: #include <petsc-private/viewerimpl.h>    /*I   "petscsys.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: } PetscViewer_Binary;

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

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

 51: PetscErrorCode PetscViewerRestoreSingleton_Binary(PetscViewer viewer,PetscViewer *outviewer)
 52: {
 54:   PetscErrorCode rank;

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

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

 71:     Not Collective

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

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

 79:     Level: advanced

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

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

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

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

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

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

105:     Not Collective

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

111:     Level: advanced

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

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

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

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

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

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

137:     Not Collective

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

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

145:     Level: advanced

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

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

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

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

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

169:     Not Collective

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

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

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

180:     Level: advanced

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

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

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

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

200: EXTERN_C_BEGIN
203: PetscErrorCode  PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
204: {
205:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

208:   *fc = vbinary->flowcontrol;
209:   return(0);
210: }
211: EXTERN_C_END

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

218:     Not Collective

220:     Input Parameter:
221: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

223:     Output Parameter:
224: .   fc - the number of messages

226:     Level: advanced

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

230: @*/
231: PetscErrorCode  PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
232: {

236:   *fc = 256;
237:   PetscTryMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt *),(viewer,fc));
238:   return(0);
239: }

241: EXTERN_C_BEGIN
244: PetscErrorCode  PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
245: {
246:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

249:   if (fc <= 1) SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
250:   vbinary->flowcontrol = fc;
251:   return(0);
252: }
253: EXTERN_C_END

257: /*@C
258:     PetscViewerBinarySetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes

260:     Not Collective

262:     Input Parameter:
263: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
264: -   fc - the number of messages, defaults to 256

266:     Level: advanced

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

270: @*/
271: PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
272: {

276:   PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
277:   return(0);
278: }

282: /*@C
283:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

285:     Not Collective

287:     Input Parameter:
288: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

290:     Output Parameter:
291: .   fdes - file descriptor

293:     Level: advanced

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

301:     Fortran Note:
302:     This routine is not supported in Fortran.

304:   Concepts: file descriptor^getting
305:   Concepts: PetscViewerBinary^accessing file descriptor

307: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
308: @*/
309: PetscErrorCode  PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
310: {
311:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

314:   *fdes = vbinary->fdes;
315:   return(0);
316: }

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

323:     Not Collective

325:     Input Paramter:
326: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

328:     Options Database Key:
329: .   -viewer_binary_skip_info

331:     Level: advanced

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

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

340:    Concepts: PetscViewerBinary^accessing info file

342: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
343:           PetscViewerBinaryGetSkipOptions()
344: @*/
345: PetscErrorCode  PetscViewerBinarySkipInfo(PetscViewer viewer)
346: {
347:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

350:   vbinary->skipinfo = PETSC_TRUE;
351:   return(0);
352: }

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

359:     Not Collective

361:     Input Parameters:
362: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
363: -   skip - PETSC_TRUE means do not use

365:     Options Database Key:
366: .   -viewer_binary_skip_options

368:     Level: advanced

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

372:    Concepts: PetscViewerBinary^accessing info file

374: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
375:           PetscViewerBinaryGetSkipOptions()
376: @*/
377: PetscErrorCode  PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool  skip)
378: {
379:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

382:   vbinary->skipoptions = skip;
383:   return(0);
384: }

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

391:     Not Collective

393:     Input Parameter:
394: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

396:     Output Parameter:
397: .   skip - PETSC_TRUE means do not use

399:     Level: advanced

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

403:    Concepts: PetscViewerBinary^accessing info file

405: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
406:           PetscViewerBinarySetSkipOptions()
407: @*/
408: PetscErrorCode  PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool  *skip)
409: {
410:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

414:   vbinary = (PetscViewer_Binary*)viewer->data;
415:   *skip = vbinary->skipoptions;
416:   return(0);
417: }

419: EXTERN_C_BEGIN
422: PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool  skip)
423: {
424:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

427:   vbinary->skipheader = skip;
428:   return(0);
429: }
430: EXTERN_C_END

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

437:     Not Collective

439:     Input Parameters:
440: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
441: -   skip - PETSC_TRUE means do not write header

443:     Options Database Key:
444: .   -viewer_binary_skip_header

446:     Level: advanced

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

450:            Can ONLY be called on a binary viewer

452: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
453:           PetscViewerBinaryGetSkipHeader()
454: @*/
455: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool  skip)
456: {

460:   PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
461:   return(0);
462: }

464: EXTERN_C_BEGIN
467: PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool  *skip)
468: {
469:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

472:   *skip   = vbinary->skipheader;
473:   return(0);
474: }
475: EXTERN_C_END

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

482:     Not Collective

484:     Input Parameter:
485: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

487:     Output Parameter:
488: .   skip - PETSC_TRUE means do not write header

490:     Level: advanced

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

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

496: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
497:           PetscViewerBinarySetSkipHeader()
498: @*/
499: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
500: {

504:   *skip = PETSC_FALSE;
505:   PetscTryMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
506:   return(0);
507: }

509: EXTERN_C_BEGIN
512: PetscErrorCode  PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
513: {
514:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;;

517:   *file = vbinary->fdes_info;
518:   return(0);
519: }
520: EXTERN_C_END

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 PETSC_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: {
551:   PetscErrorCode     ierr;

554:   *file = PETSC_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(((PetscObject)v)->comm,&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,PETSC_NULL,par,"r",&fp);
580:       if (fgets(buf,1024,fp)) {
581:         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
582:       }
583:       PetscPClose(PETSC_COMM_SELF,fp);
584: #else
585:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
586: #endif
587:     }
588:   }
589:   if (vbinary->fdes_info) {
590:     err = fclose(vbinary->fdes_info);
591:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
592:   }
593:   PetscFree(vbinary->filename);
594:   return(0);
595: }

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

605:   PetscViewerFileClose_Binary(v);
606:   PetscFree(vbinary);
607:   return(0);
608: }

610: #if defined(PETSC_HAVE_MPIIO)
613: static PetscErrorCode PetscViewerFileClose_MPIIO(PetscViewer v)
614: {
615:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
616:   int                err;
617:   PetscErrorCode     ierr;

620:   if (vbinary->mfdes) {
621:     MPI_File_close(&vbinary->mfdes);
622:   }
623:   if (vbinary->fdes_info) {
624:     err = fclose(vbinary->fdes_info);
625:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
626:   }
627:   PetscFree(vbinary->filename);
628:   return(0);
629: }


634: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
635: {
636:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
637:   PetscErrorCode     ierr;

640:   PetscViewerFileClose_MPIIO(v);
641:   PetscFree(vbinary);
642:   return(0);
643: }
644: #endif

648: /*@C
649:    PetscViewerBinaryOpen - Opens a file for binary input/output.

651:    Collective on MPI_Comm

653:    Input Parameters:
654: +  comm - MPI communicator
655: .  name - name of file
656: -  type - type of file
657: $    FILE_MODE_WRITE - create new file for binary output
658: $    FILE_MODE_READ - open existing file for binary input
659: $    FILE_MODE_APPEND - open existing file for binary output

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

664:     Options Database Keys:
665: +    -viewer_binary_skip_info
666: .    -viewer_binary_skip_options
667: -    -viewer_binary_skip_header

669:    Level: beginner

671:    Note:
672:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

680:     For writing files it only opens the file on processor 0 in the communicator.
681:     For readable files it opens the file on all nodes that have the file. If
682:     node 0 does not have the file it generates an error even if other nodes
683:     do have the file.

685:    Concepts: binary files
686:    Concepts: PetscViewerBinary^creating
687:    Concepts: gzip
688:    Concepts: accessing remote file
689:    Concepts: remote file

691: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
692:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
693:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
694: @*/
695: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
696: {

700:   PetscViewerCreate(comm,binv);
701:   PetscViewerSetType(*binv,PETSCVIEWERBINARY);
702:   PetscViewerFileSetMode(*binv,type);
703:   PetscViewerFileSetName(*binv,name);
704:   return(0);
705: }

707: #if defined(PETSC_HAVE_MPIIO)
710: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool  write)
711: {
712:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
713:   PetscErrorCode     ierr;
714:   MPI_Datatype       mdtype;
715:   PetscMPIInt        cnt = PetscMPIIntCast(count);
716:   MPI_Status         status;
717:   MPI_Aint           ul,dsize;

720:   PetscDataTypeToMPIDataType(dtype,&mdtype);
721:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
722:   if (write) {
723:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
724:   } else {
725:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
726:   }
727:   MPI_Type_get_extent(mdtype,&ul,&dsize);
728:   vbinary->moff += dsize*cnt;
729:   return(0);
730: }
731: #endif

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

738:    Collective on MPI_Comm

740:    Input Parameters:
741: +  viewer - the binary viewer
742: .  data - location to write the data
743: .  count - number of items of data to read
744: -  datatype - type of data to read

746:    Level: beginner

748:    Concepts: binary files

750: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
751:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
752:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
753: @*/
754: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
755: {
756:   PetscErrorCode     ierr;
757:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

759: #if defined(PETSC_HAVE_MPIIO)
760:   if (vbinary->MPIIO) {
761:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
762:   } else {
763: #endif
764:     PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
765: #if defined(PETSC_HAVE_MPIIO)
766:   }
767: #endif
768:   return(0);
769: }


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

777:    Collective on MPI_Comm

779:    Input Parameters:
780: +  viewer - the binary viewer
781: .  data - location of data
782: .  count - number of items of data to read
783: .  dtype - type of data to read
784: -  istemp - data may be overwritten

786:    Level: beginner

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

790:    Concepts: binary files

792: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
793:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
794:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
795: @*/
796: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool  istemp)
797: {
798:   PetscErrorCode     ierr;
799:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

802: #if defined(PETSC_HAVE_MPIIO)
803:   if (vbinary->MPIIO) {
804:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
805:   } else {
806: #endif
807:     PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
808: #if defined(PETSC_HAVE_MPIIO)
809:   }
810: #endif
811:   return(0);
812: }

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

819:    Collective on MPI_Comm

821:    Input Parameters:
822: +  viewer - the binary viewer
823: -  data - location of the array of strings


826:    Level: intermediate

828:    Concepts: binary files

830:     Notes: array of strings is null terminated

832: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
833:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
834:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
835: @*/
836: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
837: {
838:   PetscErrorCode     ierr;
839:   PetscInt           i,n = 0,*sizes;

841:   /* count number of strings */
842:   while (data[n++]);
843:   n--;
844:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
845:   sizes[0] = n;
846:   for (i=0; i<n; i++) {
847:     size_t tmp;
848:     PetscStrlen(data[i],&tmp);
849:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
850:   }
851:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
852:   for (i=0; i<n; i++) {
853:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
854:   }
855:   PetscFree(sizes);
856:   return(0);
857: }

859: /*@C
860:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

862:    Collective on MPI_Comm

864:    Input Parameter:
865: .  viewer - the binary viewer

867:    Output Parameter:
868: .  data - location of the array of strings

870:    Level: intermediate

872:    Concepts: binary files

874:     Notes: array of strings is null terminated

876: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
877:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
878:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
879: @*/
880: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
881: {
882:   PetscErrorCode     ierr;
883:   PetscInt           i,n,*sizes,N = 0;

885:   /* count number of strings */
886:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
887:   PetscMalloc(n*sizeof(PetscInt),&sizes);
888:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
889:   for (i=0; i<n; i++) {
890:     N += sizes[i];
891:   }
892:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
893:   (*data)[0] = (char*)((*data) + n + 1);
894:   for (i=1; i<n; i++) {
895:     (*data)[i] = (*data)[i-1] + sizes[i-1];
896:   }
897:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
898:   (*data)[n] = 0;
899:   PetscFree(sizes);
900:   return(0);
901: }

903: EXTERN_C_BEGIN
906: PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
907: {
908:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

911:   *name = vbinary->filename;
912:   return(0);
913: }
914: EXTERN_C_END

918: /*@C
919:      PetscViewerFileGetMode - Gets the type of file to be open

921:     Not Collective

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

926:   Output Parameter:
927: .  type - type of file
928: $    FILE_MODE_WRITE - create new file for binary output
929: $    FILE_MODE_READ - open existing file for binary input
930: $    FILE_MODE_APPEND - open existing file for binary output

932:   Level: advanced

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

936: @*/
937: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
938: {

944:   PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
945:   return(0);
946: }

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

954:     Logically Collective on PetscViewer

956:   Input Parameters:
957: .  viewer - the PetscViewer; must be a binary

959:     Options Database:
960:     -viewer_binary_mpiio : Flag for using MPI-IO

962:    Notes: turns off the default usage of the .info file since that is not scalable

964:   Level: advanced

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

968: @*/
969: PetscErrorCode  PetscViewerBinarySetMPIIO(PetscViewer viewer)
970: {

975:   PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));
976:   return(0);
977: }


982: /*@C
983:      PetscViewerFileSetMode - Sets the type of file to be open

985:     Logically Collective on PetscViewer

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

994:   Level: advanced

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

998: @*/
999: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1000: {

1006:   PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1007:   return(0);
1008: }

1010: EXTERN_C_BEGIN
1013: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1014: {
1015:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1018:   *type = vbinary->btype;
1019:   return(0);
1020: }
1021: EXTERN_C_END

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

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

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

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

1060:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);

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

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

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

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

1096: #if defined(PETSC_HAVE_O_BINARY)
1097:     if (type == FILE_MODE_WRITE) {
1098:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
1099:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1100:       }
1101:     } else if (type == FILE_MODE_READ && fname) {
1102:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
1103:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1104:       }
1105:     } else if (type == FILE_MODE_APPEND) {
1106:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
1107:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1108:       }
1109:     } else if (fname) {
1110:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1111:     }
1112: #else
1113:     if (type == FILE_MODE_WRITE) {
1114:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
1115:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1116:       }
1117:     } else if (type == FILE_MODE_READ && fname) {
1118:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
1119:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1120:       }
1121:     } else if (type == FILE_MODE_APPEND) {
1122:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
1123:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1124:       }
1125:     } else if (fname) {
1126:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1127:     }
1128: #endif
1129:   } else vbinary->fdes = -1;
1130:   viewer->format = PETSC_VIEWER_NOFORMAT;

1132:   /*
1133:       try to open info file: all processors open this file if read only
1134:   */
1135:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1136:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];

1138:     PetscStrcpy(infoname,name);
1139:     /* remove .gz if it ends library name */
1140:     PetscStrstr(infoname,".gz",&gz);
1141:     if (gz) {
1142:       PetscStrlen(gz,&len);
1143:       if (len == 3) {
1144:         *gz = 0;
1145:       }
1146:     }

1148:     PetscStrcat(infoname,".info");
1149:     PetscFixFilename(infoname,iname);
1150:     if (type == FILE_MODE_READ) {
1151:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1152:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1153:     } else {
1154:       vbinary->fdes_info = fopen(infoname,"w");
1155:       if (!vbinary->fdes_info) {
1156:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1157:       }
1158:     }
1159:   }

1161: #if defined(PETSC_USE_LOG)
1162:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1163: #endif
1164:   return(0);
1165: }
1166: EXTERN_C_END

1168: #if defined(PETSC_HAVE_MPIIO)
1169: EXTERN_C_BEGIN
1172: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
1173: {
1174:   PetscMPIInt         rank;
1175:   PetscErrorCode      ierr;
1176:   size_t              len;
1177:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
1178:   char                *gz;
1179:   PetscBool           found;
1180:   PetscFileMode       type = vbinary->btype;

1183:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
1184:   PetscViewerFileClose_MPIIO(viewer);
1185:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1186:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

1188:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1189:   PetscStrallocpy(name,&vbinary->filename);
1190:   vbinary->storecompressed = PETSC_FALSE;


1193:   /* only first processor opens file if writeable */
1194:   if (type == FILE_MODE_READ) {
1195:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1196:   } else if (type == FILE_MODE_WRITE) {
1197:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1198:   }
1199:   viewer->format = PETSC_VIEWER_NOFORMAT;

1201:   /*
1202:       try to open info file: all processors open this file if read only

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

1209:     PetscStrcpy(infoname,name);
1210:     /* remove .gz if it ends library name */
1211:     PetscStrstr(infoname,".gz",&gz);
1212:     if (gz) {
1213:       PetscStrlen(gz,&len);
1214:       if (len == 3) {
1215:         *gz = 0;
1216:       }
1217:     }

1219:     PetscStrcat(infoname,".info");
1220:     PetscFixFilename(infoname,iname);
1221:     if (type == FILE_MODE_READ) {
1222:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1223:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1224:     } else {
1225:       vbinary->fdes_info = fopen(infoname,"w");
1226:       if (!vbinary->fdes_info) {
1227:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1228:       }
1229:     }
1230:   }

1232: #if defined(PETSC_USE_LOG)
1233:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1234: #endif
1235:   return(0);
1236: }
1237: EXTERN_C_END

1239: EXTERN_C_BEGIN
1242: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1243: {
1244:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1245:   PetscErrorCode     ierr;

1248:   if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1249:   viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1250:   vbinary->MPIIO       = PETSC_TRUE;
1251:   /*  vbinary->skipinfo    = PETSC_TRUE; */
1252:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1253:   return(0);
1254: }
1255: EXTERN_C_END
1256: #endif

1258: EXTERN_C_BEGIN
1261: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1262: {
1263:   PetscErrorCode     ierr;
1264:   PetscViewer_Binary *vbinary;
1265: #if defined(PETSC_HAVE_MPIIO)
1266:   PetscBool          useMPIIO = PETSC_FALSE;
1267: #endif

1270:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
1271:   v->data            = (void*)vbinary;
1272:   v->ops->destroy    = PetscViewerDestroy_Binary;
1273:   v->ops->flush      = 0;
1274:   v->iformat         = 0;
1275:   vbinary->fdes_info = 0;
1276:   vbinary->fdes      = 0;
1277:   vbinary->skipinfo        = PETSC_FALSE;
1278:   vbinary->skipoptions     = PETSC_TRUE;
1279:   vbinary->skipheader      = PETSC_FALSE;
1280:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1281:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1282:   vbinary->btype           = (PetscFileMode) -1;
1283:   vbinary->storecompressed = PETSC_FALSE;
1284:   vbinary->filename        = 0;
1285:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

1287:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",
1288:                                     "PetscViewerBinaryGetFlowControl_Binary",
1289:                                      PetscViewerBinaryGetFlowControl_Binary);
1290:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetFlowControl_C",
1291:                                     "PetscViewerBinarySetFlowControl_Binary",
1292:                                      PetscViewerBinarySetFlowControl_Binary);
1293:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",
1294:                                     "PetscViewerBinarySetSkipHeader_Binary",
1295:                                      PetscViewerBinarySetSkipHeader_Binary);
1296:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",
1297:                                     "PetscViewerBinaryGetSkipHeader_Binary",
1298:                                      PetscViewerBinaryGetSkipHeader_Binary);
1299:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",
1300:                                     "PetscViewerBinaryGetInfoPointer_Binary",
1301:                                      PetscViewerBinaryGetInfoPointer_Binary);
1302:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1303:                                     "PetscViewerFileSetName_Binary",
1304:                                      PetscViewerFileSetName_Binary);
1305:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1306:                                     "PetscViewerFileSetMode_Binary",
1307:                                      PetscViewerFileSetMode_Binary);
1308:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1309:                                     "PetscViewerFileGetMode_Binary",
1310:                                      PetscViewerFileGetMode_Binary);
1311:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetName_C",
1312:                                     "PetscViewerFileGetName_Binary",
1313:                                      PetscViewerFileGetName_Binary);
1314: #if defined(PETSC_HAVE_MPIIO)
1315:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1316:                                     "PetscViewerBinarySetMPIIO_Binary",
1317:                                      PetscViewerBinarySetMPIIO_Binary);

1319:   PetscOptionsGetBool(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1320:   if (useMPIIO) {
1321:     PetscViewerBinarySetMPIIO(v);
1322:   }
1323: #endif
1324:   return(0);
1325: }
1326: EXTERN_C_END


1329: /* ---------------------------------------------------------------------*/
1330: /*
1331:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1332:   is attached to a communicator, in this case the attribute is a PetscViewer.
1333: */
1334: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1338: /*@C
1339:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1340:                      in a communicator.

1342:      Collective on MPI_Comm

1344:      Input Parameter:
1345: .    comm - the MPI communicator to share the binary PetscViewer

1347:      Level: intermediate

1349:    Options Database Keys:
1350: +    -viewer_binary_filename <name>
1351: .    -viewer_binary_skip_info
1352: -    -viewer_binary_skip_options

1354:    Environmental variables:
1355: -   PETSC_VIEWER_BINARY_FILENAME

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

1362: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1363:           PetscViewerDestroy()
1364: @*/
1365: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
1366: {
1368:   PetscBool      flg;
1369:   PetscViewer    viewer;
1370:   char           fname[PETSC_MAX_PATH_LEN];
1371:   MPI_Comm       ncomm;

1374:   PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1375:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1376:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1377:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1378:   }
1379:   MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1380:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1381:   if (!flg) { /* PetscViewer not yet created */
1382:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1383:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1384:     if (!flg) {
1385:       PetscStrcpy(fname,"binaryoutput");
1386:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1387:     }
1388:     PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1389:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1390:     PetscObjectRegisterDestroy((PetscObject)viewer);
1391:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1392:     MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1393:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1394:   }
1395:   PetscCommDestroy(&ncomm);
1396:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1397:   PetscFunctionReturn(viewer);
1398: }