Actual source code: binv.c

  1: #include <petsc/private/viewerimpl.h>

  3: typedef struct  {
  4:   int           fdes;                 /* file descriptor, ignored if using MPI IO */
  5: #if defined(PETSC_HAVE_MPIIO)
  6:   PetscBool     usempiio;
  7:   MPI_File      mfdes;                /* ignored unless using MPI IO */
  8:   MPI_File      mfsub;                /* subviewer support */
  9:   MPI_Offset    moff;
 10: #endif
 11:   char          *filename;            /* file name */
 12:   PetscFileMode filemode;             /* read/write/append mode */
 13:   FILE          *fdes_info;           /* optional file containing info on binary file*/
 14:   PetscBool     storecompressed;      /* gzip the write binary file when closing it*/
 15:   char          *ogzfilename;         /* gzip can be run after the filename has been updated */
 16:   PetscBool     skipinfo;             /* Don't create info file for writing; don't use for reading */
 17:   PetscBool     skipoptions;          /* don't use PETSc options database when loading */
 18:   PetscInt      flowcontrol;          /* allow only <flowcontrol> messages outstanding at a time while doing IO */
 19:   PetscBool     skipheader;           /* don't write header, only raw data */
 20:   PetscBool     matlabheaderwritten;  /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
 21:   PetscBool     setfromoptionscalled;
 22: } PetscViewer_Binary;

 24: #if defined(PETSC_HAVE_MPIIO)
 25: static PetscErrorCode PetscViewerBinarySyncMPIIO(PetscViewer viewer)
 26: {
 27:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
 28:   PetscErrorCode     ierr;

 31:   if (vbinary->filemode == FILE_MODE_READ) return(0);
 32:   if (vbinary->mfsub != MPI_FILE_NULL) {
 33:     MPI_File_sync(vbinary->mfsub);
 34:   }
 35:   if (vbinary->mfdes != MPI_FILE_NULL) {
 36:     MPI_Barrier(PetscObjectComm((PetscObject)viewer));
 37:     MPI_File_sync(vbinary->mfdes);
 38:   }
 39:   return(0);
 40: }
 41: #endif

 43: static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
 44: {
 45:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
 46:   PetscMPIInt        rank;
 47:   PetscErrorCode     ierr;

 50:   PetscViewerSetUp(viewer);

 52:   /* Return subviewer in process zero */
 53:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
 54:   if (rank == 0) {
 55:     PetscMPIInt flg;

 57:     MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
 58:     if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERBINARY requires a singleton MPI_Comm");
 59:     PetscViewerCreate(comm,outviewer);
 60:     PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
 61:     PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));
 62:     (*outviewer)->setupcalled = PETSC_TRUE;
 63:   } else {
 64:     *outviewer = NULL;
 65:   }

 67: #if defined(PETSC_HAVE_MPIIO)
 68:   if (vbinary->usempiio && *outviewer) {
 69:     PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
 70:     /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */
 71:     if (vbinary->mfsub == MPI_FILE_NULL) {
 72:       int amode;
 73:       switch (vbinary->filemode) {
 74:       case FILE_MODE_READ:   amode = MPI_MODE_RDONLY; break;
 75:       case FILE_MODE_WRITE:  amode = MPI_MODE_WRONLY; break;
 76:       case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY; break;
 77:       default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
 78:       }
 79:       MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);
 80:     }
 81:     /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */
 82:     obinary->mfdes = vbinary->mfsub;
 83:     obinary->mfsub = MPI_FILE_NULL;
 84:     obinary->moff  = vbinary->moff;
 85:   }
 86: #endif

 88: #if defined(PETSC_HAVE_MPIIO)
 89:   PetscViewerBinarySyncMPIIO(viewer);
 90: #endif
 91:   return(0);
 92: }

 94: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
 95: {
 96:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
 97:   PetscMPIInt        rank;
 98:   PetscErrorCode     ierr;
 99: #if defined(PETSC_HAVE_MPIIO)
100:   MPI_Offset         moff = 0;
101: #endif

104:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
105:   if (rank && *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");

107: #if defined(PETSC_HAVE_MPIIO)
108:   if (vbinary->usempiio && *outviewer) {
109:     PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
110:     if (obinary->mfdes != vbinary->mfsub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
111:     if (obinary->mfsub != MPI_FILE_NULL) {MPI_File_close(&obinary->mfsub);}
112:     moff = obinary->moff;
113:   }
114: #endif

116:   if (*outviewer) {
117:     PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
118:     if (obinary->fdes != vbinary->fdes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
119:     PetscFree((*outviewer)->data);
120:     PetscHeaderDestroy(outviewer);
121:   }

123: #if defined(PETSC_HAVE_MPIIO)
124:   if (vbinary->usempiio) {
125:     PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */
126:     MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));
127:     vbinary->moff = (MPI_Offset)ioff;
128:   }
129: #endif

131: #if defined(PETSC_HAVE_MPIIO)
132:   PetscViewerBinarySyncMPIIO(viewer);
133: #endif
134:   return(0);
135: }

137: #if defined(PETSC_HAVE_MPIIO)
138: /*@C
139:     PetscViewerBinaryGetMPIIOOffset - Gets the current global offset that should be passed to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()

141:     Not Collective

143:     Input Parameter:
144: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

146:     Output Parameter:
147: .   off - the current global offset

149:     Level: advanced

151:     Fortran Note:
152:     This routine is not supported in Fortran.

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

156: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
157: @*/
158: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
159: {
160:   PetscViewer_Binary *vbinary;

165:   vbinary = (PetscViewer_Binary*)viewer->data;
166:   *off = vbinary->moff;
167:   return(0);
168: }

170: /*@C
171:     PetscViewerBinaryAddMPIIOOffset - Adds to the current global offset

173:     Logically Collective

175:     Input Parameters:
176: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
177: -   off - the addition to the global offset

179:     Level: advanced

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

184:     Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()

186: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
187: @*/
188: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
189: {
190:   PetscViewer_Binary *vbinary;

195:   vbinary = (PetscViewer_Binary*)viewer->data;
196:   vbinary->moff += off;
197:   return(0);
198: }

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

203:     Not Collective

205:     Input Parameter:
206: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

208:     Output Parameter:
209: .   fdes - file descriptor

211:     Level: advanced

213:     Fortran Note:
214:     This routine is not supported in Fortran.

216: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
217: @*/
218: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
219: {
220:   PetscErrorCode     ierr;
221:   PetscViewer_Binary *vbinary;

226:   PetscViewerSetUp(viewer);
227:   vbinary = (PetscViewer_Binary*)viewer->data;
228:   *fdes = vbinary->mfdes;
229:   return(0);
230: }
231: #endif

233: /*@
234:     PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
235:         before PetscViewerFileSetName()

237:     Logically Collective on PetscViewer

239:     Input Parameters:
240: +   viewer - the PetscViewer; must be a binary
241: -   use - PETSC_TRUE means MPI-IO will be used

243:     Options Database:
244:     -viewer_binary_mpiio : Flag for using MPI-IO

246:     Level: advanced

248: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
249:           PetscViewerBinaryGetUseMPIIO()

251: @*/
252: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool use)
253: {

259:   PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,use));
260:   return(0);
261: }

263: #if defined(PETSC_HAVE_MPIIO)
264: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool use)
265: {
266:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
268:   if (viewer->setupcalled && vbinary->usempiio != use) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change MPIIO to %s after setup",PetscBools[use]);
269:   vbinary->usempiio = use;
270:   return(0);
271: }
272: #endif

274: /*@
275:     PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.

277:     Not Collective

279:     Input Parameter:
280: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

282:     Output Parameter:
283: .   use - PETSC_TRUE if MPI-IO is being used

285:     Options Database:
286:     -viewer_binary_mpiio : Flag for using MPI-IO

288:     Level: advanced

290:     Note:
291:     If MPI-IO is not available, this function will always return PETSC_FALSE

293:     Fortran Note:
294:     This routine is not supported in Fortran.

296: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
297: @*/
298: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *use)
299: {

305:   *use = PETSC_FALSE;
306:   PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,use));
307:   return(0);
308: }

310: #if defined(PETSC_HAVE_MPIIO)
311: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool  *use)
312: {
313:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

316:   *use = vbinary->usempiio;
317:   return(0);
318: }
319: #endif

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

324:     Not Collective

326:     Input Parameters:
327: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
328: -   fc - the number of messages, defaults to 256 if this function was not called

330:     Level: advanced

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

334: @*/
335: PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
336: {

342:   PetscTryMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
343:   return(0);
344: }

346: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
347: {
348:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

351:   if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %" PetscInt_FMT " was set",fc);
352:   vbinary->flowcontrol = fc;
353:   return(0);
354: }

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

359:     Not Collective

361:     Input Parameter:
362: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

364:     Output Parameter:
365: .   fc - the number of messages

367:     Level: advanced

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

371: @*/
372: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
373: {

379:   PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
380:   return(0);
381: }

383: static PetscErrorCode  PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
384: {
385:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

388:   *fc = vbinary->flowcontrol;
389:   return(0);
390: }

392: /*@C
393:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

395:     Collective On PetscViewer

397:     Input Parameter:
398: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

400:     Output Parameter:
401: .   fdes - file descriptor

403:     Level: advanced

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

411:     Fortran Note:
412:     This routine is not supported in Fortran.

414:     Developer Notes:
415:     This must be called on all processes because Dave May changed
416:     the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.

418: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
419: @*/
420: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
421: {
422:   PetscErrorCode     ierr;
423:   PetscViewer_Binary *vbinary;

428:   PetscViewerSetUp(viewer);
429:   vbinary = (PetscViewer_Binary*)viewer->data;
430:   *fdes = vbinary->fdes;
431:   return(0);
432: }

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

437:     Not Collective

439:     Input Parameter:
440: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

442:     Options Database Key:
443: .   -viewer_binary_skip_info - true indicates do not generate .info file

445:     Level: advanced

447:     Notes:
448:     This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
449:     you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
450:     viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().

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

455: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
456:           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
457: @*/
458: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
459: {

463:   PetscViewerBinarySetSkipInfo(viewer,PETSC_TRUE);
464:   return(0);
465: }

467: /*@
468:     PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it

470:     Not Collective

472:     Input Parameters:
473: +   viewer - PetscViewer context, obtained from PetscViewerCreate()
474: -   skip - PETSC_TRUE implies the .info file will not be generated

476:     Options Database Key:
477: .   -viewer_binary_skip_info - true indicates do not generate .info file

479:     Level: advanced

481: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
482:           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
483: @*/
484: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
485: {

491:   PetscTryMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
492:   return(0);
493: }

495: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
496: {
497:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

500:   vbinary->skipinfo = skip;
501:   return(0);
502: }

504: /*@
505:     PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file

507:     Not Collective

509:     Input Parameter:
510: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

512:     Output Parameter:
513: .   skip - PETSC_TRUE implies the .info file was not generated

515:     Level: advanced

517:     Notes:
518:     This must be called after PetscViewerSetType()

520: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
521:           PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
522: @*/
523: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
524: {

530:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
531:   return(0);
532: }

534: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
535: {
536:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

539:   *skip  = vbinary->skipinfo;
540:   return(0);
541: }

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

546:     Not Collective

548:     Input Parameters:
549: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
550: -   skip - PETSC_TRUE means do not use the options from the options database

552:     Options Database Key:
553: .   -viewer_binary_skip_options - true means do not use the options from the options database

555:     Level: advanced

557:     Notes:
558:     This must be called after PetscViewerSetType()

560: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
561:           PetscViewerBinaryGetSkipOptions()
562: @*/
563: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
564: {

570:   PetscTryMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
571:   return(0);
572: }

574: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
575: {
576:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

579:   vbinary->skipoptions = skip;
580:   return(0);
581: }

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

586:     Not Collective

588:     Input Parameter:
589: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

591:     Output Parameter:
592: .   skip - PETSC_TRUE means do not use

594:     Level: advanced

596:     Notes:
597:     This must be called after PetscViewerSetType()

599: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
600:           PetscViewerBinarySetSkipOptions()
601: @*/
602: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
603: {

609:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
610:   return(0);
611: }

613: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
614: {
615:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

618:   *skip = vbinary->skipoptions;
619:   return(0);
620: }

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

625:     Not Collective

627:     Input Parameters:
628: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
629: -   skip - PETSC_TRUE means do not write header

631:     Options Database Key:
632: .   -viewer_binary_skip_header - PETSC_TRUE means do not write header

634:     Level: advanced

636:     Notes:
637:       This must be called after PetscViewerSetType()

639:       Is ignored on anything but a binary viewer

641: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
642:           PetscViewerBinaryGetSkipHeader()
643: @*/
644: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
645: {

651:   PetscTryMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
652:   return(0);
653: }

655: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
656: {
657:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

660:   vbinary->skipheader = skip;
661:   return(0);
662: }

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

667:     Not Collective

669:     Input Parameter:
670: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

672:     Output Parameter:
673: .   skip - PETSC_TRUE means do not write header

675:     Level: advanced

677:     Notes:
678:     This must be called after PetscViewerSetType()

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

682: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
683:           PetscViewerBinarySetSkipHeader()
684: @*/
685: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
686: {

692:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
693:   return(0);
694: }

696: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool  *skip)
697: {
698:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

701:   *skip = vbinary->skipheader;
702:   return(0);
703: }

705: /*@C
706:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
707:           info file associated with a binary file.

709:     Not Collective

711:     Input Parameter:
712: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

714:     Output Parameter:
715: .   file - file pointer  Always returns NULL if not a binary viewer

717:     Level: advanced

719:     Notes:
720:       For writable binary PetscViewers, the descriptor will only be valid for the
721:     first processor in the communicator that shares the PetscViewer.

723:     Fortran Note:
724:     This routine is not supported in Fortran.

726: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
727: @*/
728: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
729: {

735:   *file = NULL;
736:   PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
737:   return(0);
738: }

740: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
741: {
742:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
743:   PetscErrorCode     ierr;

746:   PetscViewerSetUp(viewer);
747:   *file = vbinary->fdes_info;
748:   if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
749:     if (vbinary->fdes_info) {
750:       FILE *info = vbinary->fdes_info;
751:       PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
752:       PetscFPrintf(PETSC_COMM_SELF,info,"#$$ Set.filename = '%s';\n",vbinary->filename);
753:       PetscFPrintf(PETSC_COMM_SELF,info,"#$$ fd = PetscOpenFile(Set.filename);\n");
754:       PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
755:     }
756:     vbinary->matlabheaderwritten = PETSC_TRUE;
757:   }
758:   return(0);
759: }

761: #if defined(PETSC_HAVE_MPIIO)
762: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
763: {
764:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
765:   PetscErrorCode     ierr;

768:   if (vbinary->mfdes != MPI_FILE_NULL) {
769:     MPI_File_close(&vbinary->mfdes);
770:   }
771:   if (vbinary->mfsub != MPI_FILE_NULL) {
772:     MPI_File_close(&vbinary->mfsub);
773:   }
774:   vbinary->moff = 0;
775:   return(0);
776: }
777: #endif

779: static PetscErrorCode PetscViewerFileClose_BinarySTDIO(PetscViewer v)
780: {
781:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
782:   PetscErrorCode     ierr;

785:   if (vbinary->fdes != -1) {
786:     PetscBinaryClose(vbinary->fdes);
787:     vbinary->fdes = -1;
788:     if (vbinary->storecompressed) {
789:       char cmd[8+PETSC_MAX_PATH_LEN],out[64+PETSC_MAX_PATH_LEN] = "";
790:       const char *gzfilename = vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename;
791:       /* compress the file */
792:       PetscStrncpy(cmd,"gzip -f ",sizeof(cmd));
793:       PetscStrlcat(cmd,gzfilename,sizeof(cmd));
794: #if defined(PETSC_HAVE_POPEN)
795:       {
796:         FILE *fp;
797:         PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);
798:         if (fgets(out,(int)(sizeof(out)-1),fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",cmd,out);
799:         PetscPClose(PETSC_COMM_SELF,fp);
800:       }
801: #endif
802:     }
803:   }
804:   PetscFree(vbinary->ogzfilename);
805:   return(0);
806: }

808: static PetscErrorCode PetscViewerFileClose_BinaryInfo(PetscViewer v)
809: {
810:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
811:   PetscErrorCode     ierr;

814:   if (v->format == PETSC_VIEWER_BINARY_MATLAB && vbinary->matlabheaderwritten) {
815:     if (vbinary->fdes_info) {
816:       FILE *info = vbinary->fdes_info;
817:       PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
818:       PetscFPrintf(PETSC_COMM_SELF,info,"#$$ close(fd);\n");
819:       PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
820:     }
821:   }
822:   if (vbinary->fdes_info) {
823:     FILE *info = vbinary->fdes_info;
824:     vbinary->fdes_info = NULL;
825:     if (fclose(info)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
826:   }
827:   return(0);
828: }

830: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
831: {
832:   PetscErrorCode     ierr;

835: #if defined(PETSC_HAVE_MPIIO)
836:   PetscViewerFileClose_BinaryMPIIO(v);
837: #endif
838:   PetscViewerFileClose_BinarySTDIO(v);
839:   PetscViewerFileClose_BinaryInfo(v);
840:   return(0);
841: }

843: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
844: {
845:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
846:   PetscErrorCode     ierr;

849:   PetscViewerFileClose_Binary(v);
850:   PetscFree(vbinary->filename);
851:   PetscFree(vbinary);

853:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",NULL);
854:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",NULL);
855:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",NULL);
856:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",NULL);
857:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",NULL);
858:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",NULL);
859:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",NULL);
860:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",NULL);
861:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",NULL);
862:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",NULL);
863:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",NULL);
864:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",NULL);
865:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",NULL);
866: #if defined(PETSC_HAVE_MPIIO)
867:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",NULL);
868:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",NULL);
869: #endif
870:   return(0);
871: }

873: /*@C
874:    PetscViewerBinaryOpen - Opens a file for binary input/output.

876:    Collective

878:    Input Parameters:
879: +  comm - MPI communicator
880: .  name - name of file
881: -  mode - open mode of file
882: $    FILE_MODE_WRITE - create new file for binary output
883: $    FILE_MODE_READ - open existing file for binary input
884: $    FILE_MODE_APPEND - open existing file for binary output

886:    Output Parameter:
887: .  viewer - PetscViewer for binary input/output to use with the specified file

889:     Options Database Keys:
890: +    -viewer_binary_filename <name> -
891: .    -viewer_binary_skip_info -
892: .    -viewer_binary_skip_options -
893: .    -viewer_binary_skip_header -
894: -    -viewer_binary_mpiio -

896:    Level: beginner

898:    Note:
899:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

907: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
908:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
909:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
910:           PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
911: @*/
912: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode mode,PetscViewer *viewer)
913: {

917:   PetscViewerCreate(comm,viewer);
918:   PetscViewerSetType(*viewer,PETSCVIEWERBINARY);
919:   PetscViewerFileSetMode(*viewer,mode);
920:   PetscViewerFileSetName(*viewer,name);
921:   PetscViewerSetFromOptions(*viewer);
922:   return(0);
923: }

925: #if defined(PETSC_HAVE_MPIIO)
926: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
927: {
928:   MPI_Comm           comm = PetscObjectComm((PetscObject)viewer);
929:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
930:   MPI_File           mfdes = vbinary->mfdes;
931:   PetscErrorCode     ierr;
932:   MPI_Datatype       mdtype;
933:   PetscMPIInt        rank,cnt;
934:   MPI_Status         status;
935:   MPI_Aint           ul,dsize;

938:   MPI_Comm_rank(comm,&rank);
939:   PetscMPIIntCast(num,&cnt);
940:   PetscDataTypeToMPIDataType(dtype,&mdtype);
941:   if (write) {
942:     if (rank == 0) {
943:       MPIU_File_write_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
944:     }
945:   } else {
946:     if (rank == 0) {
947:       MPIU_File_read_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
948:       if (cnt > 0) {MPI_Get_count(&status,mdtype,&cnt);}
949:     }
950:     MPI_Bcast(&cnt,1,MPI_INT,0,comm);
951:     MPI_Bcast(data,cnt,mdtype,0,comm);
952:   }
953:   MPI_Type_get_extent(mdtype,&ul,&dsize);
954:   vbinary->moff += dsize*cnt;
955:   if (count) *count = cnt;
956:   return(0);
957: }
958: #endif

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

963:    Collective

965:    Input Parameters:
966: +  viewer - the binary viewer
967: .  data - location of the data to be written
968: .  num - number of items of data to read
969: -  dtype - type of data to read

971:    Output Parameters:
972: .  count - number of items of data actually read, or NULL.

974:    Level: beginner

976: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
977:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
978:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
979: @*/
980: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
981: {
982:   PetscErrorCode     ierr;
983:   PetscViewer_Binary *vbinary;

988:   PetscViewerSetUp(viewer);
989:   vbinary = (PetscViewer_Binary*)viewer->data;
990: #if defined(PETSC_HAVE_MPIIO)
991:   if (vbinary->usempiio) {
992:     PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
993:   } else {
994: #endif
995:     PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);
996: #if defined(PETSC_HAVE_MPIIO)
997:   }
998: #endif
999:   return(0);
1000: }

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

1005:    Collective

1007:    Input Parameters:
1008: +  viewer - the binary viewer
1009: .  data - location of data
1010: .  count - number of items of data to write
1011: -  dtype - type of data to write

1013:    Level: beginner

1015: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1016:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
1017:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1018: @*/
1019: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,const void *data,PetscInt count,PetscDataType dtype)
1020: {
1021:   PetscErrorCode     ierr;
1022:   PetscViewer_Binary *vbinary;

1027:   PetscViewerSetUp(viewer);
1028:   vbinary = (PetscViewer_Binary*)viewer->data;
1029: #if defined(PETSC_HAVE_MPIIO)
1030:   if (vbinary->usempiio) {
1031:     PetscViewerBinaryWriteReadMPIIO(viewer,(void*)data,count,NULL,dtype,PETSC_TRUE);
1032:   } else {
1033: #endif
1034:     PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);
1035: #if defined(PETSC_HAVE_MPIIO)
1036:   }
1037: #endif
1038:   return(0);
1039: }

1041: static PetscErrorCode PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1042: {
1043:   MPI_Comm              comm = PetscObjectComm((PetscObject)viewer);
1044:   PetscMPIInt           size,rank;
1045:   MPI_Datatype          mdtype;
1046:   PETSC_UNUSED MPI_Aint lb;
1047:   MPI_Aint              dsize;
1048:   PetscBool             useMPIIO;
1049:   PetscErrorCode        ierr;

1056:   PetscViewerSetUp(viewer);

1058:   PetscDataTypeToMPIDataType(dtype,&mdtype);
1059:   MPI_Type_get_extent(mdtype,&lb,&dsize);
1060:   MPI_Comm_rank(comm,&rank);
1061:   MPI_Comm_size(comm,&size);

1063:   PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);
1064: #if defined(PETSC_HAVE_MPIIO)
1065:   if (useMPIIO) {
1066:     MPI_File       mfdes;
1067:     MPI_Offset     off;
1068:     PetscMPIInt    cnt;

1070:     if (start == PETSC_DETERMINE) {
1071:       MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);
1072:       start -= count;
1073:     }
1074:     if (total == PETSC_DETERMINE) {
1075:       total = start + count;
1076:       MPI_Bcast(&total,1,MPIU_INT,size-1,comm);
1077:     }
1078:     PetscMPIIntCast(count,&cnt);
1079:     PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
1080:     PetscViewerBinaryGetMPIIOOffset(viewer,&off);
1081:     off += (MPI_Offset)(start*dsize);
1082:     if (write) {
1083:       MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1084:     } else {
1085:       MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1086:     }
1087:     off  = (MPI_Offset)(total*dsize);
1088:     PetscViewerBinaryAddMPIIOOffset(viewer,off);
1089:     return(0);
1090:   }
1091: #endif
1092:   {
1093:     int         fdes;
1094:     char        *workbuf = NULL;
1095:     PetscInt    tcount = rank == 0 ? 0 : count,maxcount=0,message_count,flowcontrolcount;
1096:     PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j;
1097:     MPI_Status  status;

1099:     PetscCommGetNewTag(comm,&tag);
1100:     MPI_Reduce(&tcount,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);
1101:     PetscMPIIntCast(maxcount,&maxcnt);
1102:     PetscMPIIntCast(count,&cnt);

1104:     PetscViewerBinaryGetDescriptor(viewer,&fdes);
1105:     PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);
1106:     if (rank == 0) {
1107:       PetscMalloc(maxcnt*dsize,&workbuf);
1108:       if (write) {
1109:         PetscBinaryWrite(fdes,data,cnt,dtype);
1110:       } else {
1111:         PetscBinaryRead(fdes,data,cnt,NULL,dtype);
1112:       }
1113:       for (j=1; j<size; j++) {
1114:         PetscViewerFlowControlStepMain(viewer,j,&message_count,flowcontrolcount);
1115:         if (write) {
1116:           MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);
1117:           MPI_Get_count(&status,mdtype,&rcnt);
1118:           PetscBinaryWrite(fdes,workbuf,rcnt,dtype);
1119:         } else {
1120:           MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);
1121:           PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);
1122:           MPI_Send(workbuf,scnt,mdtype,j,tag,comm);
1123:         }
1124:       }
1125:       PetscFree(workbuf);
1126:       PetscViewerFlowControlEndMain(viewer,&message_count);
1127:     } else {
1128:       PetscViewerFlowControlStepWorker(viewer,rank,&message_count);
1129:       if (write) {
1130:         MPI_Send(data,cnt,mdtype,0,tag,comm);
1131:       } else {
1132:         MPI_Send(&cnt,1,MPI_INT,0,tag,comm);
1133:         MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);
1134:       }
1135:       PetscViewerFlowControlEndWorker(viewer,&message_count);
1136:     }
1137:   }
1138:   return(0);
1139: }

1141: /*@C
1142:    PetscViewerBinaryReadAll - reads from a binary file from all processes

1144:    Collective

1146:    Input Parameters:
1147: +  viewer - the binary viewer
1148: .  data - location of data
1149: .  count - local number of items of data to read
1150: .  start - local start, can be PETSC_DETERMINE
1151: .  total - global number of items of data to read, can be PETSC_DETERMINE
1152: -  dtype - type of data to read

1154:    Level: advanced

1156: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll()
1157: @*/
1158: PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1159: {
1162:   PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);
1163:   return(0);
1164: }

1166: /*@C
1167:    PetscViewerBinaryWriteAll - writes to a binary file from all processes

1169:    Collective

1171:    Input Parameters:
1172: +  viewer - the binary viewer
1173: .  data - location of data
1174: .  count - local number of items of data to write
1175: .  start - local start, can be PETSC_DETERMINE
1176: .  total - global number of items of data to write, can be PETSC_DETERMINE
1177: -  dtype - type of data to write

1179:    Level: advanced

1181: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll()
1182: @*/
1183: PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1184: {
1187:   PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);
1188:   return(0);
1189: }

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

1194:    Collective

1196:    Input Parameters:
1197: +  viewer - the binary viewer
1198: -  data - location of the array of strings

1200:    Level: intermediate

1202:     Notes:
1203:     array of strings is null terminated

1205: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1206:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1207:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1208: @*/
1209: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
1210: {
1212:   PetscInt       i,n = 0,*sizes;
1213:   size_t         len;

1216:   PetscViewerSetUp(viewer);
1217:   /* count number of strings */
1218:   while (data[n++]);
1219:   n--;
1220:   PetscMalloc1(n+1,&sizes);
1221:   sizes[0] = n;
1222:   for (i=0; i<n; i++) {
1223:     PetscStrlen(data[i],&len);
1224:     sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */
1225:   }
1226:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);
1227:   for (i=0; i<n; i++) {
1228:     PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);
1229:   }
1230:   PetscFree(sizes);
1231:   return(0);
1232: }

1234: /*@C
1235:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

1237:    Collective

1239:    Input Parameter:
1240: .  viewer - the binary viewer

1242:    Output Parameter:
1243: .  data - location of the array of strings

1245:    Level: intermediate

1247:     Notes:
1248:     array of strings is null terminated

1250: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1251:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1252:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1253: @*/
1254: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1255: {
1257:   PetscInt       i,n,*sizes,N = 0;

1260:   PetscViewerSetUp(viewer);
1261:   /* count number of strings */
1262:   PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1263:   PetscMalloc1(n,&sizes);
1264:   PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1265:   for (i=0; i<n; i++) N += sizes[i];
1266:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1267:   (*data)[0] = (char*)((*data) + n + 1);
1268:   for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1269:   PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1270:   (*data)[n] = NULL;
1271:   PetscFree(sizes);
1272:   return(0);
1273: }

1275: /*@C
1276:      PetscViewerFileSetMode - Sets the open mode of file

1278:     Logically Collective on PetscViewer

1280:   Input Parameters:
1281: +  viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII  PetscViewer
1282: -  mode - open mode of file
1283: $    FILE_MODE_WRITE - create new file for output
1284: $    FILE_MODE_READ - open existing file for input
1285: $    FILE_MODE_APPEND - open existing file for output

1287:   Level: advanced

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

1291: @*/
1292: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)
1293: {

1299:   if (mode == FILE_MODE_UNDEFINED) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot set FILE_MODE_UNDEFINED");
1300:   else if (mode < FILE_MODE_UNDEFINED || mode > FILE_MODE_APPEND_UPDATE) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Invalid file mode %d",(int)mode);
1301:   PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));
1302:   return(0);
1303: }

1305: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)
1306: {
1307:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1310:   if (viewer->setupcalled && vbinary->filemode != mode) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[mode]);
1311:   vbinary->filemode = mode;
1312:   return(0);
1313: }

1315: /*@C
1316:      PetscViewerFileGetMode - Gets the open mode of file

1318:     Not Collective

1320:   Input Parameter:
1321: .  viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII  PetscViewer

1323:   Output Parameter:
1324: .  mode - open mode of file
1325: $    FILE_MODE_WRITE - create new file for binary output
1326: $    FILE_MODE_READ - open existing file for binary input
1327: $    FILE_MODE_APPEND - open existing file for binary output

1329:   Level: advanced

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

1333: @*/
1334: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode)
1335: {

1341:   PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));
1342:   return(0);
1343: }

1345: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode)
1346: {
1347:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1350:   *mode = vbinary->filemode;
1351:   return(0);
1352: }

1354: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1355: {
1356:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1357:   PetscErrorCode     ierr;

1360:   if (viewer->setupcalled && vbinary->filename) {
1361:     /* gzip can be run after the file with the previous filename has been closed */
1362:     PetscFree(vbinary->ogzfilename);
1363:     PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1364:   }
1365:   PetscFree(vbinary->filename);
1366:   PetscStrallocpy(name,&vbinary->filename);
1367:   viewer->setupcalled = PETSC_FALSE;
1368:   return(0);
1369: }

1371: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1372: {
1373:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1376:   *name = vbinary->filename;
1377:   return(0);
1378: }

1380: #if defined(PETSC_HAVE_MPIIO)
1381: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1382: {
1383:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1384:   int                amode;
1385:   PetscErrorCode     ierr;

1388:   vbinary->storecompressed = PETSC_FALSE;

1390:   vbinary->moff = 0;
1391:   switch (vbinary->filemode) {
1392:   case FILE_MODE_READ:   amode = MPI_MODE_RDONLY; break;
1393:   case FILE_MODE_WRITE:  amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1394:   case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break;
1395:   case FILE_MODE_UNDEFINED: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerSetUp()");
1396:   default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
1397:   }
1398:   MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1399:   /*
1400:       The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero.
1401:   */
1402:   if (vbinary->filemode == FILE_MODE_WRITE) {MPI_File_set_size(vbinary->mfdes,0);}
1403:   /*
1404:       Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND,
1405:       MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file.
1406:       Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert
1407:       the offset in etype units to an absolute byte position.
1408:    */
1409:   if (vbinary->filemode == FILE_MODE_APPEND) {MPI_File_get_position(vbinary->mfdes,&vbinary->moff);}
1410:   return(0);
1411: }
1412: #endif

1414: static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)
1415: {
1416:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1417:   const char         *fname;
1418:   char               bname[PETSC_MAX_PATH_LEN],*gz;
1419:   PetscBool          found;
1420:   PetscMPIInt        rank;
1421:   PetscErrorCode     ierr;

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

1426:   /* if file name ends in .gz strip that off and note user wants file compressed */
1427:   vbinary->storecompressed = PETSC_FALSE;
1428:   if (vbinary->filemode == FILE_MODE_WRITE) {
1429:     PetscStrstr(vbinary->filename,".gz",&gz);
1430:     if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;}
1431:   }
1432: #if !defined(PETSC_HAVE_POPEN)
1433:   if (vbinary->storecompressed) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP_SYS,"Cannot run gzip on this machine");
1434: #endif

1436:   fname = vbinary->filename;
1437:   if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */
1438:     PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);
1439:     if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s",fname);
1440:     fname = bname;
1441:   }

1443:   vbinary->fdes = -1;
1444:   if (rank == 0) { /* only first processor opens file*/
1445:     PetscFileMode mode = vbinary->filemode;
1446:     if (mode == FILE_MODE_APPEND) {
1447:       /* check if asked to append to a non-existing file */
1448:       PetscTestFile(fname,'\0',&found);
1449:       if (!found) mode = FILE_MODE_WRITE;
1450:     }
1451:     PetscBinaryOpen(fname,mode,&vbinary->fdes);
1452:   }
1453:   return(0);
1454: }

1456: static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)
1457: {
1458:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1459:   PetscMPIInt        rank;
1460:   PetscBool          found;
1461:   PetscErrorCode     ierr;

1464:   vbinary->fdes_info = NULL;
1465:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1466:   if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || rank == 0)) {
1467:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz;

1469:     PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1470:     /* remove .gz if it ends file name */
1471:     PetscStrstr(infoname,".gz",&gz);
1472:     if (gz && gz[3] == 0) *gz = 0;

1474:     PetscStrlcat(infoname,".info",sizeof(infoname));
1475:     if (vbinary->filemode == FILE_MODE_READ) {
1476:       PetscFixFilename(infoname,iname);
1477:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1478:       if (found) {PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);}
1479:     } else if (rank == 0) { /* write or append */
1480:       const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w";
1481:       vbinary->fdes_info = fopen(infoname,omode);
1482:       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1483:     }
1484:   }
1485:   return(0);
1486: }

1488: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer)
1489: {
1490:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1491:   PetscBool          usempiio;
1492:   PetscErrorCode     ierr;

1495:   if (!vbinary->setfromoptionscalled) {PetscViewerSetFromOptions(viewer);}
1496:   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1497:   if (vbinary->filemode == (PetscFileMode)-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1498:   PetscViewerFileClose_Binary(viewer);

1500:   PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);
1501:   if (usempiio) {
1502: #if defined(PETSC_HAVE_MPIIO)
1503:     PetscViewerFileSetUp_BinaryMPIIO(viewer);
1504: #endif
1505:   } else {
1506:     PetscViewerFileSetUp_BinarySTDIO(viewer);
1507:   }
1508:   PetscViewerFileSetUp_BinaryInfo(viewer);

1510:   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1511:   return(0);
1512: }

1514: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1515: {
1516:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
1517:   const char         *fname = vbinary->filename ? vbinary->filename : "not yet set";
1518:   const char         *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set";
1519:   PetscBool          usempiio;
1520:   PetscErrorCode     ierr;

1523:   PetscViewerBinaryGetUseMPIIO(v,&usempiio);
1524:   PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);
1525:   PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");
1526:   return(0);
1527: }

1529: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer)
1530: {
1531:   PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data;
1532:   char               defaultname[PETSC_MAX_PATH_LEN];
1533:   PetscBool          flg;
1534:   PetscErrorCode     ierr;

1537:   if (viewer->setupcalled) return(0);
1538:   PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1539:   PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1540:   PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,sizeof(defaultname),&flg);
1541:   if (flg) { PetscViewerFileSetName_Binary(viewer,defaultname); }
1542:   PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);
1543:   PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);
1544:   PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);
1545: #if defined(PETSC_HAVE_MPIIO)
1546:   PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);
1547: #else
1548:   PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1549: #endif
1550:   PetscOptionsTail();
1551:   binary->setfromoptionscalled = PETSC_TRUE;
1552:   return(0);
1553: }

1555: /*MC
1556:    PETSCVIEWERBINARY - A viewer that saves to binary files

1558: .seealso:  PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1559:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1560:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1561:            PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()

1563:   Level: beginner

1565: M*/

1567: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1568: {
1569:   PetscErrorCode     ierr;
1570:   PetscViewer_Binary *vbinary;

1573:   PetscNewLog(v,&vbinary);
1574:   v->data = (void*)vbinary;

1576:   v->ops->setfromoptions   = PetscViewerSetFromOptions_Binary;
1577:   v->ops->destroy          = PetscViewerDestroy_Binary;
1578:   v->ops->view             = PetscViewerView_Binary;
1579:   v->ops->setup            = PetscViewerSetUp_Binary;
1580:   v->ops->flush            = NULL; /* Should we support Flush() ? */
1581:   v->ops->getsubviewer     = PetscViewerGetSubViewer_Binary;
1582:   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1583:   v->ops->read             = PetscViewerBinaryRead;

1585:   vbinary->fdes            = -1;
1586: #if defined(PETSC_HAVE_MPIIO)
1587:   vbinary->usempiio        = PETSC_FALSE;
1588:   vbinary->mfdes           = MPI_FILE_NULL;
1589:   vbinary->mfsub           = MPI_FILE_NULL;
1590: #endif
1591:   vbinary->filename        = NULL;
1592:   vbinary->filemode        = FILE_MODE_UNDEFINED;
1593:   vbinary->fdes_info       = NULL;
1594:   vbinary->skipinfo        = PETSC_FALSE;
1595:   vbinary->skipoptions     = PETSC_TRUE;
1596:   vbinary->skipheader      = PETSC_FALSE;
1597:   vbinary->storecompressed = PETSC_FALSE;
1598:   vbinary->ogzfilename     = NULL;
1599:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

1601:   vbinary->setfromoptionscalled = PETSC_FALSE;

1603:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1604:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1605:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1606:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1607:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1608:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1609:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1610:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1611:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1612:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1613:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1614:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1615:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1616: #if defined(PETSC_HAVE_MPIIO)
1617:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1618:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1619: #endif
1620:   return(0);
1621: }

1623: /* ---------------------------------------------------------------------*/
1624: /*
1625:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1626:   is attached to a communicator, in this case the attribute is a PetscViewer.
1627: */
1628: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1630: /*@C
1631:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1632:                      in a communicator.

1634:      Collective

1636:      Input Parameter:
1637: .    comm - the MPI communicator to share the binary PetscViewer

1639:      Level: intermediate

1641:    Options Database Keys:
1642: +    -viewer_binary_filename <name> - filename in which to store the binary data, defaults to binaryoutput
1643: .    -viewer_binary_skip_info - true means do not create .info file for this viewer
1644: .    -viewer_binary_skip_options - true means do not use the options database for this viewer
1645: .    -viewer_binary_skip_header - true means do not store the usual header information in the binary file
1646: -    -viewer_binary_mpiio - true means use the file via MPI-IO, maybe faster for large files and many MPI ranks

1648:    Environmental variables:
1649: -   PETSC_VIEWER_BINARY_FILENAME - filename in which to store the binary data, defaults to binaryoutput

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

1656: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1657:           PetscViewerDestroy()
1658: @*/
1659: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1660: {
1662:   PetscBool      flg;
1663:   PetscViewer    viewer;
1664:   char           fname[PETSC_MAX_PATH_LEN];
1665:   MPI_Comm       ncomm;

1668:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1669:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1670:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL);
1671:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1672:   }
1673:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1674:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1675:   if (!flg) { /* PetscViewer not yet created */
1676:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1677:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1678:     if (!flg) {
1679:       PetscStrcpy(fname,"binaryoutput");
1680:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1681:     }
1682:     PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1683:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1684:     PetscObjectRegisterDestroy((PetscObject)viewer);
1685:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1686:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1687:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1688:   }
1689:   PetscCommDestroy(&ncomm);
1690:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1691:   PetscFunctionReturn(viewer);
1692: }