Actual source code: binv.c

  2: #include <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

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

205:     Not Collective

207:     Input Parameter:
208: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

210:     Output Parameter:
211: .   fc - the number of messages

213:     Level: advanced

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

217: @*/
218: PetscErrorCode  PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
219: {
220:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

223:   *fc = vbinary->flowcontrol;
224:   return(0);
225: }

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

232:     Not Collective

234:     Input Parameter:
235: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
236: -   fc - the number of messages, defaults to 256

238:     Level: advanced

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

242: @*/
243: PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
244: {
245:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

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

255: /*@C
256:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

258:     Not Collective

260:     Input Parameter:
261: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

263:     Output Parameter:
264: .   fdes - file descriptor

266:     Level: advanced

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

274:     Fortran Note:
275:     This routine is not supported in Fortran.

277:   Concepts: file descriptor^getting
278:   Concepts: PetscViewerBinary^accessing file descriptor

280: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
281: @*/
282: PetscErrorCode  PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
283: {
284:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

287:   *fdes = vbinary->fdes;
288:   return(0);
289: }

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

296:     Not Collective

298:     Input Paramter:
299: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

301:     Options Database Key:
302: .   -viewer_binary_skip_info

304:     Level: advanced

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

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

313:    Concepts: PetscViewerBinary^accessing info file

315: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
316:           PetscViewerBinaryGetSkipOptions()
317: @*/
318: PetscErrorCode  PetscViewerBinarySkipInfo(PetscViewer viewer)
319: {
320:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

323:   vbinary->skipinfo = PETSC_TRUE;
324:   return(0);
325: }

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

332:     Not Collective

334:     Input Parameters:
335: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
336: -   skip - PETSC_TRUE means do not use

338:     Options Database Key:
339: .   -viewer_binary_skip_options

341:     Level: advanced

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

345:    Concepts: PetscViewerBinary^accessing info file

347: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
348:           PetscViewerBinaryGetSkipOptions()
349: @*/
350: PetscErrorCode  PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool  skip)
351: {
352:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

355:   vbinary->skipoptions = skip;
356:   return(0);
357: }

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

364:     Not Collective

366:     Input Parameter:
367: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

369:     Output Parameter:
370: .   skip - PETSC_TRUE means do not use

372:     Level: advanced

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

376:    Concepts: PetscViewerBinary^accessing info file

378: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
379:           PetscViewerBinarySetSkipOptions()
380: @*/
381: PetscErrorCode  PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool  *skip)
382: {
383:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

386:   *skip = vbinary->skipoptions;
387:   return(0);
388: }

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

395:     Not Collective

397:     Input Parameters:
398: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
399: -   skip - PETSC_TRUE means do not write header

401:     Options Database Key:
402: .   -viewer_binary_skip_header

404:     Level: advanced

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

408: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
409:           PetscViewerBinaryGetSkipHeader()
410: @*/
411: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool  skip)
412: {
413:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

416:   vbinary->skipheader = skip;
417:   return(0);
418: }

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

425:     Not Collective

427:     Input Parameter:
428: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

430:     Output Parameter:
431: .   skip - PETSC_TRUE means do not write header

433:     Level: advanced

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

437: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
438:           PetscViewerBinarySetSkipHeader()
439: @*/
440: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
441: {
442:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

445:   *skip = vbinary->skipheader;
446:   return(0);
447: }

451: /*@C
452:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
453:           info file associated with a binary file.

455:     Not Collective

457:     Input Parameter:
458: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

460:     Output Parameter:
461: .   file - file pointer

463:     Level: advanced

465:     Notes:
466:       For writable binary PetscViewers, the descriptor will only be valid for the
467:     first processor in the communicator that shares the PetscViewer.

469:     Fortran Note:
470:     This routine is not supported in Fortran.

472:   Concepts: PetscViewerBinary^accessing info file

474: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
475: @*/
476: PetscErrorCode  PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
477: {
478:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

481:   *file = vbinary->fdes_info;
482:   return(0);
483: }

487: PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
488: {
489:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
490:   PetscErrorCode     ierr;
491:   PetscMPIInt        rank;
492:   int                err;

495:   MPI_Comm_rank(((PetscObject)v)->comm,&rank);
496:   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
497:     close(vbinary->fdes);
498:     if (!rank && vbinary->storecompressed) {
499:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
500:       FILE *fp;
501:       /* compress the file */
502:       PetscStrcpy(par,"gzip -f ");
503:       PetscStrcat(par,vbinary->filename);
504: #if defined(PETSC_HAVE_POPEN)
505:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
506:       if (fgets(buf,1024,fp)) {
507:         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
508:       }
509:       PetscPClose(PETSC_COMM_SELF,fp);
510: #else
511:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
512: #endif
513:     }
514:   }
515:   if (vbinary->fdes_info) {
516:     err = fclose(vbinary->fdes_info);
517:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
518:   }
519:   PetscFree(vbinary->filename);
520:   PetscFree(vbinary);
521:   return(0);
522: }

524: #if defined(PETSC_HAVE_MPIIO)
527: PetscErrorCode PetscViewerDestroy_MPIIO(PetscViewer v)
528: {
529:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
530:   PetscErrorCode     ierr;
531:   int                err;

534:   if (vbinary->mfdes) {
535:     MPI_File_close(&vbinary->mfdes);
536:   }
537:   if (vbinary->fdes_info) {
538:     err = fclose(vbinary->fdes_info);
539:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
540:   }
541:   PetscFree(vbinary->filename);
542:   PetscFree(vbinary);
543:   return(0);
544: }
545: #endif

549: /*@C
550:    PetscViewerBinaryOpen - Opens a file for binary input/output.

552:    Collective on MPI_Comm

554:    Input Parameters:
555: +  comm - MPI communicator
556: .  name - name of file
557: -  type - type of file
558: $    FILE_MODE_WRITE - create new file for binary output
559: $    FILE_MODE_READ - open existing file for binary input
560: $    FILE_MODE_APPEND - open existing file for binary output

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

565:     Options Database Keys:
566: +    -viewer_binary_skip_info
567: .    -viewer_binary_skip_options
568: -    -viewer_binary_skip_header

570:    Level: beginner

572:    Note:
573:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

581:     For writing files it only opens the file on processor 0 in the communicator.
582:     For readable files it opens the file on all nodes that have the file. If
583:     node 0 does not have the file it generates an error even if other nodes
584:     do have the file.

586:    Concepts: binary files
587:    Concepts: PetscViewerBinary^creating
588:    Concepts: gzip
589:    Concepts: accessing remote file
590:    Concepts: remote file

592: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
593:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
594:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
595: @*/
596: PetscErrorCode  PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
597: {

601:   PetscViewerCreate(comm,binv);
602:   PetscViewerSetType(*binv,PETSCVIEWERBINARY);
603:   PetscViewerFileSetMode(*binv,type);
604:   PetscViewerFileSetName(*binv,name);
605:   return(0);
606: }

608: #if defined(PETSC_HAVE_MPIIO)
611: static PetscErrorCode PetscViewerBinaryMPIIO(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool  write)
612: {
613:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
614:   PetscErrorCode     ierr;
615:   MPI_Datatype       mdtype;
616:   PetscMPIInt        cnt = PetscMPIIntCast(count);
617:   MPI_Status         status;
618:   MPI_Aint           ul,dsize;

621:   PetscDataTypeToMPIDataType(dtype,&mdtype);
622:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char *)"native",MPI_INFO_NULL);
623:   if (write) {
624:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
625:   } else {
626:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
627:   }
628:   MPI_Type_get_extent(mdtype,&ul,&dsize);
629:   vbinary->moff += dsize*cnt;
630:   return(0);
631: }
632: #endif

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

639:    Collective on MPI_Comm

641:    Input Parameters:
642: +  viewer - the binary viewer
643: .  data - location to write the data
644: .  count - number of items of data to read
645: -  datatype - type of data to read

647:    Level: beginner

649:    Concepts: binary files

651: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
652:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
653:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
654: @*/
655: PetscErrorCode  PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
656: {
657:   PetscErrorCode     ierr;
658:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

660: #if defined(PETSC_HAVE_MPIIO)
661:   if (vbinary->MPIIO) {
662:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);
663:   } else {
664: #endif
665:     PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);
666: #if defined(PETSC_HAVE_MPIIO)
667:   }
668: #endif
669:   return(0);
670: }


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

678:    Collective on MPI_Comm

680:    Input Parameters:
681: +  viewer - the binary viewer
682: .  data - location of data
683: .  count - number of items of data to read
684: .  istemp - data may be overwritten
685: -  datatype - type of data to read

687:    Level: beginner

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

691:    Concepts: binary files

693: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
694:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
695:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
696: @*/
697: PetscErrorCode  PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool  istemp)
698: {
699:   PetscErrorCode     ierr;
700:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

703: #if defined(PETSC_HAVE_MPIIO)
704:   if (vbinary->MPIIO) {
705:     PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);
706:   } else {
707: #endif
708:     PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);
709: #if defined(PETSC_HAVE_MPIIO)
710:   }
711: #endif
712:   return(0);
713: }

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

720:    Collective on MPI_Comm

722:    Input Parameters:
723: +  viewer - the binary viewer
724: -  data - location of the array of strings


727:    Level: intermediate

729:    Concepts: binary files

731:     Notes: array of strings is null terminated

733: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
734:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
735:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
736: @*/
737: PetscErrorCode  PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
738: {
739:   PetscErrorCode     ierr;
740:   PetscInt           i,n = 0,*sizes;

742:   /* count number of strings */
743:   while (data[n++]);
744:   n--;
745:   PetscMalloc((n+1)*sizeof(PetscInt),&sizes);
746:   sizes[0] = n;
747:   for (i=0; i<n; i++) {
748:     size_t tmp;
749:     PetscStrlen(data[i],&tmp);
750:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
751:   }
752:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
753:   for (i=0; i<n; i++) {
754:     PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
755:   }
756:   PetscFree(sizes);
757:   return(0);
758: }

760: /*@C
761:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

763:    Collective on MPI_Comm

765:    Input Parameter:
766: .  viewer - the binary viewer

768:    Output Parameter:
769: .  data - location of the array of strings

771:    Level: intermediate

773:    Concepts: binary files

775:     Notes: array of strings is null terminated

777: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
778:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
779:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
780: @*/
781: PetscErrorCode  PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
782: {
783:   PetscErrorCode     ierr;
784:   PetscInt           i,n,*sizes,N = 0;

786:   /* count number of strings */
787:   PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);
788:   PetscMalloc(n*sizeof(PetscInt),&sizes);
789:   PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);
790:   for (i=0; i<n; i++) {
791:     N += sizes[i];
792:   }
793:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
794:   (*data)[0] = (char*)((*data) + n + 1);
795:   for (i=1; i<n; i++) {
796:     (*data)[i] = (*data)[i-1] + sizes[i-1];
797:   }
798:   PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);
799:   (*data)[n] = 0;
800:   PetscFree(sizes);
801:   return(0);
802: }

807: PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
808: {
809:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

812:   *name = vbinary->filename;
813:   return(0);
814: }

819: /*@C
820:      PetscViewerFileGetMode - Gets the type of file to be open

822:     Not Collective

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

827:   Output Parameter:
828: .  type - type of file
829: $    FILE_MODE_WRITE - create new file for binary output
830: $    FILE_MODE_READ - open existing file for binary input
831: $    FILE_MODE_APPEND - open existing file for binary output

833:   Level: advanced

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

837: @*/
838: PetscErrorCode  PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
839: {

845:   PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
846:   return(0);
847: }

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

855:     Logically Collective on PetscViewer

857:   Input Parameters:
858: .  viewer - the PetscViewer; must be a binary

860:     Options Database:
861:     -viewer_binary_mpiio : Flag for using MPI-IO

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

865:   Level: advanced

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

869: @*/
870: PetscErrorCode  PetscViewerBinarySetMPIIO(PetscViewer viewer)
871: {

876:   PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));
877:   return(0);
878: }


883: /*@C
884:      PetscViewerFileSetMode - Sets the type of file to be open

886:     Logically Collective on PetscViewer

888:   Input Parameters:
889: +  viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
890: -  type - type of file
891: $    FILE_MODE_WRITE - create new file for binary output
892: $    FILE_MODE_READ - open existing file for binary input
893: $    FILE_MODE_APPEND - open existing file for binary output

895:   Level: advanced

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

899: @*/
900: PetscErrorCode  PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
901: {

907:   PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
908:   return(0);
909: }

914: PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
915: {
916:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

919:   *type = vbinary->btype;
920:   return(0);
921: }

927: PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
928: {
929:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

932:   vbinary->btype = type;
933:   return(0);
934: }

937: /*
938:         Actually opens the file
939: */
943: PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
944: {
945:   PetscMPIInt         rank;
946:   PetscErrorCode      ierr;
947:   size_t              len;
948:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
949:   const char          *fname;
950:   char                bname[PETSC_MAX_PATH_LEN],*gz;
951:   PetscBool           found;
952:   PetscFileMode       type = vbinary->btype;

955:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
956:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
957:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);
958:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,PETSC_NULL);

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

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

965:   /* if ends in .gz strip that off and note user wants file compressed */
966:   vbinary->storecompressed = PETSC_FALSE;
967:   if (!rank && type == FILE_MODE_WRITE) {
968:     /* remove .gz if it ends library name */
969:     PetscStrstr(vbinary->filename,".gz",&gz);
970:     if (gz) {
971:       PetscStrlen(gz,&len);
972:       if (len == 3) {
973:         *gz = 0;
974:         vbinary->storecompressed = PETSC_TRUE;
975:       }
976:     }
977:   }

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

982:     if (type == FILE_MODE_READ){
983:       /* possibly get the file from remote site or compressed file */
984:       PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
985:       fname = bname;
986:       if (!rank && !found) {
987:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
988:       } else if (!found) {
989:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
990:         fname = 0;
991:       }
992:     } else {
993:       fname = vbinary->filename;
994:     }

996: #if defined(PETSC_HAVE_O_BINARY)
997:     if (type == FILE_MODE_WRITE) {
998:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
999:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1000:       }
1001:     } else if (type == FILE_MODE_READ && fname) {
1002:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) {
1003:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1004:       }
1005:     } else if (type == FILE_MODE_APPEND) {
1006:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) {
1007:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1008:       }
1009:     } else if (fname) {
1010:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1011:     }
1012: #else
1013:     if (type == FILE_MODE_WRITE) {
1014:       if ((vbinary->fdes = creat(fname,0666)) == -1) {
1015:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1016:       }
1017:     } else if (type == FILE_MODE_READ && fname) {
1018:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) {
1019:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1020:       }
1021:     } else if (type == FILE_MODE_APPEND) {
1022:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) {
1023:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1024:       }
1025:     } else if (fname) {
1026:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1027:     }
1028: #endif
1029:   } else vbinary->fdes = -1;
1030:   viewer->format = PETSC_VIEWER_NOFORMAT;

1032:   /*
1033:       try to open info file: all processors open this file if read only
1034:   */
1035:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1036:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];

1038:     PetscStrcpy(infoname,name);
1039:     /* remove .gz if it ends library name */
1040:     PetscStrstr(infoname,".gz",&gz);
1041:     if (gz) {
1042:       PetscStrlen(gz,&len);
1043:       if (len == 3) {
1044:         *gz = 0;
1045:       }
1046:     }

1048:     PetscStrcat(infoname,".info");
1049:     PetscFixFilename(infoname,iname);
1050:     if (type == FILE_MODE_READ) {
1051:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1052:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1053:     } else {
1054:       vbinary->fdes_info = fopen(infoname,"w");
1055:       if (!vbinary->fdes_info) {
1056:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1057:       }
1058:     }
1059:   }

1061: #if defined(PETSC_USE_LOG)
1062:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1063: #endif
1064:   return(0);
1065: }

1068: #if defined(PETSC_HAVE_MPIIO)
1072: PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[])
1073: {
1074:   PetscMPIInt         rank;
1075:   PetscErrorCode      ierr;
1076:   size_t              len;
1077:   PetscViewer_Binary  *vbinary = (PetscViewer_Binary*)viewer->data;
1078:   char                *gz;
1079:   PetscBool           found;
1080:   PetscFileMode       type = vbinary->btype;

1083:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerBinarySetFileType() before PetscViewerFileSetName()");
1084:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);
1085:   PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);

1087:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
1088:   PetscStrallocpy(name,&vbinary->filename);
1089:   vbinary->storecompressed = PETSC_FALSE;


1092:   /* only first processor opens file if writeable */
1093:   if (type == FILE_MODE_READ) {
1094:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1095:   } else if (type == FILE_MODE_WRITE) {
1096:     MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1097:   }
1098:   viewer->format = PETSC_VIEWER_NOFORMAT;

1100:   /*
1101:       try to open info file: all processors open this file if read only

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

1108:     PetscStrcpy(infoname,name);
1109:     /* remove .gz if it ends library name */
1110:     PetscStrstr(infoname,".gz",&gz);
1111:     if (gz) {
1112:       PetscStrlen(gz,&len);
1113:       if (len == 3) {
1114:         *gz = 0;
1115:       }
1116:     }

1118:     PetscStrcat(infoname,".info");
1119:     PetscFixFilename(infoname,iname);
1120:     if (type == FILE_MODE_READ) {
1121:       PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);
1122:       PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);
1123:     } else {
1124:       vbinary->fdes_info = fopen(infoname,"w");
1125:       if (!vbinary->fdes_info) {
1126:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1127:       }
1128:     }
1129:   }

1131: #if defined(PETSC_USE_LOG)
1132:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
1133: #endif
1134:   return(0);
1135: }

1141: PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer)
1142: {
1143:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1144:   PetscErrorCode     ierr;

1147:   if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()");
1148:   viewer->ops->destroy = PetscViewerDestroy_MPIIO;
1149:   vbinary->MPIIO       = PETSC_TRUE;
1150:   /*  vbinary->skipinfo    = PETSC_TRUE; */
1151:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);
1152:   return(0);
1153: }
1155: #endif

1160: PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1161: {
1162:   PetscErrorCode     ierr;
1163:   PetscViewer_Binary *vbinary;
1164: #if defined(PETSC_HAVE_MPIIO)
1165:   PetscBool          useMPIIO = PETSC_FALSE;
1166: #endif

1169:   PetscNewLog(v,PetscViewer_Binary,&vbinary);
1170:   v->data            = (void*)vbinary;
1171:   v->ops->destroy    = PetscViewerDestroy_Binary;
1172:   v->ops->flush      = 0;
1173:   v->iformat         = 0;
1174:   vbinary->fdes_info = 0;
1175:   vbinary->fdes      = 0;
1176:   vbinary->skipinfo        = PETSC_FALSE;
1177:   vbinary->skipoptions     = PETSC_TRUE;
1178:   vbinary->skipheader      = PETSC_FALSE;
1179:   v->ops->getsingleton     = PetscViewerGetSingleton_Binary;
1180:   v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary;
1181:   vbinary->btype           = (PetscFileMode) -1;
1182:   vbinary->storecompressed = PETSC_FALSE;
1183:   vbinary->filename        = 0;
1184:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

1186:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C",
1187:                                     "PetscViewerFileSetName_Binary",
1188:                                      PetscViewerFileSetName_Binary);
1189:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C",
1190:                                     "PetscViewerFileSetMode_Binary",
1191:                                      PetscViewerFileSetMode_Binary);
1192:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C",
1193:                                     "PetscViewerFileGetMode_Binary",
1194:                                      PetscViewerFileGetMode_Binary);
1195:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetName_C",
1196:                                     "PetscViewerFileGetName_Binary",
1197:                                      PetscViewerFileGetName_Binary);
1198: #if defined(PETSC_HAVE_MPIIO)
1199:   PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C",
1200:                                     "PetscViewerBinarySetMPIIO_Binary",
1201:                                      PetscViewerBinarySetMPIIO_Binary);

1203:   PetscOptionsGetBool(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);
1204:   if (useMPIIO) {
1205:     PetscViewerBinarySetMPIIO(v);
1206:   }
1207: #endif
1208:   return(0);
1209: }


1213: /* ---------------------------------------------------------------------*/
1214: /*
1215:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1216:   is attached to a communicator, in this case the attribute is a PetscViewer.
1217: */
1218: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1222: /*@C
1223:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1224:                      in a communicator.

1226:      Collective on MPI_Comm

1228:      Input Parameter:
1229: .    comm - the MPI communicator to share the binary PetscViewer

1231:      Level: intermediate

1233:    Options Database Keys:
1234: +    -viewer_binary_filename <name>
1235: .    -viewer_binary_skip_info
1236: -    -viewer_binary_skip_options

1238:    Environmental variables:
1239: -   PETSC_VIEWER_BINARY_FILENAME

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

1246: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1247:           PetscViewerDestroy()
1248: @*/
1249: PetscViewer  PETSC_VIEWER_BINARY_(MPI_Comm comm)
1250: {
1252:   PetscBool      flg;
1253:   PetscViewer    viewer;
1254:   char           fname[PETSC_MAX_PATH_LEN];
1255:   MPI_Comm       ncomm;

1258:   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);}
1259:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1260:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1261:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1262:   }
1263:   MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg);
1264:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1265:   if (!flg) { /* PetscViewer not yet created */
1266:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1267:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1268:     if (!flg) {
1269:       PetscStrcpy(fname,"binaryoutput");
1270:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1271:     }
1272:     PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1273:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1274:     PetscObjectRegisterDestroy((PetscObject)viewer);
1275:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1276:     MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1277:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1278:   }
1279:   PetscCommDestroy(&ncomm);
1280:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1281:   PetscFunctionReturn(viewer);
1282: }