Actual source code: binv.c

petsc-3.3-p7 2013-05-11
  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;
716:   MPI_Status         status;
717:   MPI_Aint           ul,dsize;

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

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

739:    Collective on MPI_Comm

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

747:    Level: beginner

749:    Concepts: binary files

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

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


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

778:    Collective on MPI_Comm

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

787:    Level: beginner

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

791:    Concepts: binary files

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

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

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

820:    Collective on MPI_Comm

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


827:    Level: intermediate

829:    Concepts: binary files

831:     Notes: array of strings is null terminated

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

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

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

863:    Collective on MPI_Comm

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

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

871:    Level: intermediate

873:    Concepts: binary files

875:     Notes: array of strings is null terminated

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

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

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

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

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

922:     Not Collective

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

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

933:   Level: advanced

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

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

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

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

955:     Logically Collective on PetscViewer

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

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

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

965:   Level: advanced

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

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

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


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

986:     Logically Collective on PetscViewer

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

995:   Level: advanced

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

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

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

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

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

1024: EXTERN_C_BEGIN
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: }
1035: EXTERN_C_END

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

1343:      Collective on MPI_Comm

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

1348:      Level: intermediate

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

1355:    Environmental variables:
1356: -   PETSC_VIEWER_BINARY_FILENAME

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

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

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