Actual source code: binv.c

petsc-master 2017-09-23
Report Typos and Errors

  2:  #include <petsc/private/viewerimpl.h>
  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     usempiio;
 15:   MPI_File      mfdes;                /* ignored unless using MPI IO */
 16:   MPI_Offset    moff;
 17: #endif
 18:   PetscFileMode btype;                /* read or write? */
 19:   FILE          *fdes_info;           /* optional file containing info on binary file*/
 20:   PetscBool     storecompressed;      /* gzip the write binary file when closing it*/
 21:   char          *filename;
 22:   PetscBool     skipinfo;             /* Don't create info file for writing; don't use for reading */
 23:   PetscBool     skipoptions;          /* don't use PETSc options database when loading */
 24:   PetscInt      flowcontrol;          /* allow only <flowcontrol> messages outstanding at a time while doing IO */
 25:   PetscBool     skipheader;           /* don't write header, only raw data */
 26:   PetscBool     matlabheaderwritten;  /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
 27:   PetscBool     setfromoptionscalled;
 28: } PetscViewer_Binary;

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

 37:   PetscViewerSetUp(viewer);
 38:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
 39:   if (!rank) {
 40:     PetscViewerCreate(PETSC_COMM_SELF,outviewer);
 41:     PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
 42:     obinary = (PetscViewer_Binary*)(*outviewer)->data;
 43:     PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
 44:   } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get subcomm viewer for binary files or sockets unless SubViewer contains the rank 0 process");
 45:   return(0);
 46: }

 48: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
 49: {
 51:   PetscErrorCode rank;

 54:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
 55:   if (!rank) {
 56:     PetscFree((*outviewer)->data);
 57:     PetscHeaderDestroy(outviewer);
 58:   }
 59:   return(0);
 60: }

 62: #if defined(PETSC_HAVE_MPIIO)
 63: /*@C
 64:     PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()

 66:     Not Collective

 68:     Input Parameter:
 69: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

 71:     Output Parameter:
 72: .    off - the current offset

 74:     Level: advanced

 76:     Fortran Note:
 77:     This routine is not supported in Fortran.

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

 81:   Concepts: file descriptor^getting
 82:   Concepts: PetscViewerBinary^accessing file descriptor

 84: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
 85: @*/
 86: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
 87: {
 88:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

 91:   *off = vbinary->moff;
 92:   return(0);
 93: }

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

 98:     Not Collective

100:     Input Parameters:
101: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
102: -    off - the addition to the offset

104:     Level: advanced

106:     Fortran Note:
107:     This routine is not supported in Fortran.

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

111:   Concepts: file descriptor^getting
112:   Concepts: PetscViewerBinary^accessing file descriptor

114: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
115: @*/
116: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
117: {
118:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

121:   vbinary->moff += off;
122:   return(0);
123: }

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

128:     Not Collective

130:     Input Parameter:
131: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

133:     Output Parameter:
134: .   fdes - file descriptor

136:     Level: advanced

138:     Fortran Note:
139:     This routine is not supported in Fortran.

141:   Concepts: file descriptor^getting
142:   Concepts: PetscViewerBinary^accessing file descriptor

144: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
145: @*/
146: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
147: {
148:   PetscErrorCode     ierr;
149:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

152:   PetscViewerSetUp(viewer);
153:   *fdes = vbinary->mfdes;
154:   return(0);
155: }

157: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool  *flg)
158: {
159:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
160: 
162:   *flg = vbinary->usempiio;
163:   return(0);
164: }
165: #endif


168: /*@C
169:     PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.

171:     Not Collective

173:     Input Parameter:
174: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

176:     Output Parameter:
177: -   flg - PETSC_TRUE if MPI-IO is being used

179:     Options Database:
180:     -viewer_binary_mpiio : Flag for using MPI-IO

182:     Level: advanced

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

187:     Fortran Note:
188:     This routine is not supported in Fortran.

190:   Concepts: file descriptor^getting
191:   Concepts: PetscViewerBinary^accessing file descriptor

193: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
194: @*/
195: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
196: {

200:   *flg = PETSC_FALSE;
201:   PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
202:   return(0);
203: }

205: static PetscErrorCode  PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
206: {
207:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

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

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

217:     Not Collective

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

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

225:     Level: advanced

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

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

235:   PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
236:   return(0);
237: }

239: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
240: {
241:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

244:   if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
245:   vbinary->flowcontrol = fc;
246:   return(0);
247: }

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

252:     Not Collective

254:     Input Parameter:
255: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
256: -   fc - the number of messages, defaults to 256 if this function was not called

258:     Level: advanced

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

262: @*/
263: PetscErrorCode  PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
264: {

268:   PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
269:   return(0);
270: }

272: /*@C
273:     PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.

275:     Collective On PetscViewer

277:     Input Parameter:
278: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

280:     Output Parameter:
281: .   fdes - file descriptor

283:     Level: advanced

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

291:     Fortran Note:
292:     This routine is not supported in Fortran.

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


298:   Concepts: file descriptor^getting
299:   Concepts: PetscViewerBinary^accessing file descriptor

301: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
302: @*/
303: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
304: {
305:   PetscErrorCode     ierr;
306:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

309:   PetscViewerSetUp(viewer);
310:   *fdes = vbinary->fdes;
311:   return(0);
312: }

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

317:     Not Collective

319:     Input Paramter:
320: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

322:     Options Database Key:
323: .   -viewer_binary_skip_info

325:     Level: advanced

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

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

334:    Concepts: PetscViewerBinary^accessing info file

336: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
337:           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
338: @*/
339: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
340: {
341:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

344:   vbinary->skipinfo = PETSC_TRUE;
345:   return(0);
346: }

348: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
349: {
350:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

353:   vbinary->skipinfo = skip;
354:   return(0);
355: }

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

360:     Not Collective

362:     Input Paramter:
363: .   viewer - PetscViewer context, obtained from PetscViewerCreate()

365:     Options Database Key:
366: .   -viewer_binary_skip_info

368:     Level: advanced

370:     Concepts: PetscViewerBinary^accessing info file

372: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
373:           PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
374: @*/
375: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
376: {

380:   PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
381:   return(0);
382: }

384: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
385: {
386:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

389:   *skip  = vbinary->skipinfo;
390:   return(0);
391: }

393: /*@
394:     PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file

396:     Not Collective

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

401:     Output Parameter:
402: .   skip - PETSC_TRUE implies the .info file was not generated

404:     Level: advanced

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

408:     Concepts: PetscViewerBinary^accessing info file

410: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
411:           PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
412: @*/
413: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
414: {

418:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
419:   return(0);
420: }

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

427:   vbinary->skipoptions = skip;
428:   return(0);
429: }

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

434:     Not Collective

436:     Input Parameters:
437: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
438: -   skip - PETSC_TRUE means do not use

440:     Options Database Key:
441: .   -viewer_binary_skip_options

443:     Level: advanced

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

447:    Concepts: PetscViewerBinary^accessing info file

449: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
450:           PetscViewerBinaryGetSkipOptions()
451: @*/
452: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
453: {

457:   PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
458:   return(0);
459: }

461: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
462: {
463:   PetscViewer_Binary *vbinary;

467:   vbinary = (PetscViewer_Binary*)viewer->data;
468:   *skip   = vbinary->skipoptions;
469:   return(0);
470: }

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

475:     Not Collective

477:     Input Parameter:
478: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

480:     Output Parameter:
481: .   skip - PETSC_TRUE means do not use

483:     Level: advanced

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

487:    Concepts: PetscViewerBinary^accessing info file

489: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
490:           PetscViewerBinarySetSkipOptions()
491: @*/
492: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
493: {

497:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
498:   return(0);
499: }

501: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
502: {
503:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

506:   vbinary->skipheader = skip;
507:   return(0);
508: }

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

513:     Not Collective

515:     Input Parameters:
516: +   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
517: -   skip - PETSC_TRUE means do not write header

519:     Options Database Key:
520: .   -viewer_binary_skip_header

522:     Level: advanced

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

526:            Can ONLY be called on a binary viewer

528: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
529:           PetscViewerBinaryGetSkipHeader()
530: @*/
531: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
532: {

536:   PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
537:   return(0);
538: }

540: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool  *skip)
541: {
542:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

545:   *skip = vbinary->skipheader;
546:   return(0);
547: }

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

552:     Not Collective

554:     Input Parameter:
555: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

557:     Output Parameter:
558: .   skip - PETSC_TRUE means do not write header

560:     Level: advanced

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

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

566: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
567:           PetscViewerBinarySetSkipHeader()
568: @*/
569: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool  *skip)
570: {

574:   *skip = PETSC_FALSE;
575:   PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
576:   return(0);
577: }

579: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
580: {
581:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
582:   PetscErrorCode     ierr;
583:   MPI_Comm           comm;

586:   PetscViewerSetUp(viewer);
587:   *file = vbinary->fdes_info;
588:   if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
589:     vbinary->matlabheaderwritten = PETSC_TRUE;
590:     PetscObjectGetComm((PetscObject)viewer,&comm);
591:     PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
592:     PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
593:     PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
594:     PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
595:   }
596:   return(0);
597: }

599: /*@C
600:     PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
601:           info file associated with a binary file.

603:     Not Collective

605:     Input Parameter:
606: .   viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()

608:     Output Parameter:
609: .   file - file pointer  Always returns NULL if not a binary viewer

611:     Level: advanced

613:     Notes:
614:       For writable binary PetscViewers, the descriptor will only be valid for the
615:     first processor in the communicator that shares the PetscViewer.

617:     Fortran Note:
618:     This routine is not supported in Fortran.

620:   Concepts: PetscViewerBinary^accessing info file

622: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
623: @*/
624: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
625: {

629:   *file = NULL;
630:   PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
631:   return(0);
632: }

634: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
635: {
636:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
637:   PetscErrorCode     ierr;
638:   PetscMPIInt        rank;
639:   int                err;

642:   MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
643:   if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
644:     close(vbinary->fdes);
645:     if (!rank && vbinary->storecompressed) {
646:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
647:       FILE *fp;
648:       /* compress the file */
649:       PetscStrcpy(par,"gzip -f ");
650:       PetscStrcat(par,vbinary->filename);
651: #if defined(PETSC_HAVE_POPEN)
652:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
653:       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
654:       PetscPClose(PETSC_COMM_SELF,fp,NULL);
655: #else
656:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
657: #endif
658:     }
659:   }
660:   if (vbinary->fdes_info) {
661:     err = fclose(vbinary->fdes_info);
662:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
663:   }
664:   return(0);
665: }

667: #if defined(PETSC_HAVE_MPIIO)
668: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
669: {
670:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
671:   int                err;
672:   PetscErrorCode     ierr;

675:   if (vbinary->mfdes) {
676:     MPI_File_close(&vbinary->mfdes);
677:   }
678:   if (vbinary->fdes_info) {
679:     err = fclose(vbinary->fdes_info);
680:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
681:   }
682:   return(0);
683: }
684: #endif

686: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
687: {
688:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
689:   PetscErrorCode     ierr;

692:   if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
693:     MPI_Comm comm;
694:     FILE     *info;

696:     PetscObjectGetComm((PetscObject)v,&comm);
697:     PetscViewerBinaryGetInfoPointer(v,&info);
698:     PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
699:     PetscFPrintf(comm,info,"#$$ close(fd);\n");
700:     PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
701:   }
702: #if defined(PETSC_HAVE_MPIIO)
703:   if (vbinary->usempiio) {
704:     PetscViewerFileClose_BinaryMPIIO(v);
705:   } else {
706: #endif
707:     PetscViewerFileClose_Binary(v);
708: #if defined(PETSC_HAVE_MPIIO)
709:   }
710: #endif
711:   if (vbinary->filename) { PetscFree(vbinary->filename); }
712:   PetscFree(vbinary);
713:   return(0);
714: }

716: /*@C
717:    PetscViewerBinaryOpen - Opens a file for binary input/output.

719:    Collective on MPI_Comm

721:    Input Parameters:
722: +  comm - MPI communicator
723: .  name - name of file
724: -  type - type of file
725: $    FILE_MODE_WRITE - create new file for binary output
726: $    FILE_MODE_READ - open existing file for binary input
727: $    FILE_MODE_APPEND - open existing file for binary output

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

732:     Options Database Keys:
733: +    -viewer_binary_filename <name>
734: .    -viewer_binary_skip_info
735: .    -viewer_binary_skip_options
736: .    -viewer_binary_skip_header
737: -    -viewer_binary_mpiio

739:    Level: beginner

741:    Note:
742:    This PetscViewer should be destroyed with PetscViewerDestroy().

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

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

750:     For writing files it only opens the file on processor 0 in the communicator.
751:     For readable files it opens the file on all nodes that have the file. If
752:     node 0 does not have the file it generates an error even if other nodes
753:     do have the file.

755:    Concepts: binary files
756:    Concepts: PetscViewerBinary^creating
757:    Concepts: gzip
758:    Concepts: accessing remote file
759:    Concepts: remote file

761: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
762:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
763:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
764:           PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
765: @*/
766: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
767: {

771:   PetscViewerCreate(comm,binv);
772:   PetscViewerSetType(*binv,PETSCVIEWERBINARY);
773:   PetscViewerFileSetMode(*binv,type);
774:   PetscViewerFileSetName(*binv,name);
775:   PetscViewerSetFromOptions(*binv);
776:   return(0);
777: }

779: #if defined(PETSC_HAVE_MPIIO)
780: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
781: {
782:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
783:   PetscErrorCode     ierr;
784:   MPI_Datatype       mdtype;
785:   PetscMPIInt        cnt;
786:   MPI_Status         status;
787:   MPI_Aint           ul,dsize;

790:   PetscMPIIntCast(num,&cnt);
791:   PetscDataTypeToMPIDataType(dtype,&mdtype);
792:   MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
793:   if (write) {
794:     MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
795:   } else {
796:     MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
797:   }
798:   MPI_Type_get_extent(mdtype,&ul,&dsize);

800:   vbinary->moff += dsize*cnt;
801:   if (count) *count = num;
802:   return(0);
803: }
804: #endif

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

809:    Collective on MPI_Comm

811:    Input Parameters:
812: +  viewer - the binary viewer
813: .  data - location of the data to be written
814: .  num - number of items of data to read
815: -  dtype - type of data to read

817:    Output Parameters:
818: .  count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.

820:    Level: beginner

822:    Concepts: binary files

824:    Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.

826: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
827:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
828:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
829: @*/
830: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
831: {
832:   PetscErrorCode     ierr;
833:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

835:   PetscViewerSetUp(viewer);
836: #if defined(PETSC_HAVE_MPIIO)
837:   if (vbinary->usempiio) {
838:     PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
839:   } else {
840: #endif
841:     PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
842:     if (count) *count = num;
843: #if defined(PETSC_HAVE_MPIIO)
844:   }
845: #endif
846:   return(0);
847: }

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

852:    Collective on MPI_Comm

854:    Input Parameters:
855: +  viewer - the binary viewer
856: .  data - location of data
857: .  count - number of items of data to write
858: .  dtype - type of data to write
859: -  istemp - data may be overwritten

861:    Level: beginner

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

865:    Concepts: binary files

867: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
868:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
869:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
870: @*/
871: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
872: {
873:   PetscErrorCode     ierr;
874:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

877:   PetscViewerSetUp(viewer);
878: #if defined(PETSC_HAVE_MPIIO)
879:   if (vbinary->usempiio) {
880:     PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
881:   } else {
882: #endif
883:     PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
884: #if defined(PETSC_HAVE_MPIIO)
885:   }
886: #endif
887:   return(0);
888: }

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

893:    Collective on MPI_Comm

895:    Input Parameters:
896: +  viewer - the binary viewer
897: -  data - location of the array of strings


900:    Level: intermediate

902:    Concepts: binary files

904:     Notes: array of strings is null terminated

906: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
907:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
908:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
909: @*/
910: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
911: {
913:   PetscInt       i,n = 0,*sizes;

915:   PetscViewerSetUp(viewer);
916:   /* count number of strings */
917:   while (data[n++]) ;
918:   n--;
919:   PetscMalloc1(n+1,&sizes);
920:   sizes[0] = n;
921:   for (i=0; i<n; i++) {
922:     size_t tmp;
923:     PetscStrlen(data[i],&tmp);
924:     sizes[i+1] = tmp + 1;   /* size includes space for the null terminator */
925:   }
926:   PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
927:   for (i=0; i<n; i++) {
928:     PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
929:   }
930:   PetscFree(sizes);
931:   return(0);
932: }

934: /*@C
935:    PetscViewerBinaryReadStringArray - reads a binary file an array of strings

937:    Collective on MPI_Comm

939:    Input Parameter:
940: .  viewer - the binary viewer

942:    Output Parameter:
943: .  data - location of the array of strings

945:    Level: intermediate

947:    Concepts: binary files

949:     Notes: array of strings is null terminated

951: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
952:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
953:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
954: @*/
955: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
956: {
958:   PetscInt       i,n,*sizes,N = 0;

960:   PetscViewerSetUp(viewer);
961:   /* count number of strings */
962:   PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
963:   PetscMalloc1(n,&sizes);
964:   PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
965:   for (i=0; i<n; i++) N += sizes[i];
966:   PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
967:   (*data)[0] = (char*)((*data) + n + 1);
968:   for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
969:   PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);

971:   (*data)[n] = 0;

973:   PetscFree(sizes);
974:   return(0);
975: }

977: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
978: {
979:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

982:   *name = vbinary->filename;
983:   return(0);
984: }

986: /*@C
987:      PetscViewerFileGetMode - Gets the type of file to be open

989:     Not Collective

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

994:   Output Parameter:
995: .  type - type of file
996: $    FILE_MODE_WRITE - create new file for binary output
997: $    FILE_MODE_READ - open existing file for binary input
998: $    FILE_MODE_APPEND - open existing file for binary output

1000:   Level: advanced

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

1004: @*/
1005: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1006: {

1012:   PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1013:   return(0);
1014: }

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

1020:     Logically Collective on PetscViewer

1022:     Input Parameters:
1023: +   viewer - the PetscViewer; must be a binary
1024: -   flg - PETSC_TRUE means MPI-IO will be used

1026:     Options Database:
1027:     -viewer_binary_mpiio : Flag for using MPI-IO

1029:     Level: advanced

1031: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1032:           PetscViewerBinaryGetUseMPIIO()

1034: @*/
1035: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1036: {

1041:   PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1042:   return(0);
1043: }

1045: /*@C
1046:      PetscViewerFileSetMode - Sets the type of file to be open

1048:     Logically Collective on PetscViewer

1050:   Input Parameters:
1051: +  viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII  PetscViewer
1052: -  type - type of file
1053: $    FILE_MODE_WRITE - create new file for binary output
1054: $    FILE_MODE_READ - open existing file for binary input
1055: $    FILE_MODE_APPEND - open existing file for binary output

1057:   Level: advanced

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

1061: @*/
1062: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1063: {

1069:   PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1070:   return(0);
1071: }

1073: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1074: {
1075:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1078:   *type = vbinary->btype;
1079:   return(0);
1080: }

1082: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1083: {
1084:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;

1087:   vbinary->btype = type;
1088:   return(0);
1089: }

1091: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1092: {
1093:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1094:   PetscErrorCode     ierr;

1097:   if (vbinary->filename) { PetscFree(vbinary->filename); }
1098:   PetscStrallocpy(name,&vbinary->filename);
1099:   return(0);
1100: }
1101: /*
1102:         Actually opens the file
1103: */
1104: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1105: {
1106:   PetscMPIInt        rank;
1107:   PetscErrorCode     ierr;
1108:   size_t             len;
1109:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1110:   const char         *fname;
1111:   char               bname[PETSC_MAX_PATH_LEN],*gz;
1112:   PetscBool          found;
1113:   PetscFileMode      type = vbinary->btype;

1116:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1117:   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1118:   PetscViewerFileClose_Binary(viewer);

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

1122:   /* if ends in .gz strip that off and note user wants file compressed */
1123:   vbinary->storecompressed = PETSC_FALSE;
1124:   if (!rank && type == FILE_MODE_WRITE) {
1125:     /* remove .gz if it ends library name */
1126:     PetscStrstr(vbinary->filename,".gz",&gz);
1127:     if (gz) {
1128:       PetscStrlen(gz,&len);
1129:       if (len == 3) {
1130:         *gz = 0;
1131:         vbinary->storecompressed = PETSC_TRUE;
1132:       }
1133:     }
1134:   }

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

1139:     if (type == FILE_MODE_READ) {
1140:       /* possibly get the file from remote site or compressed file */
1141:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1142:       fname = bname;
1143:       if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1144:       else if (!found) {
1145:         PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
1146:         fname = 0;
1147:       }
1148:     } else fname = vbinary->filename;

1150: #if defined(PETSC_HAVE_O_BINARY)
1151:     if (type == FILE_MODE_WRITE) {
1152:       if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1153:     } else if (type == FILE_MODE_READ && fname) {
1154:       if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1155:     } else if (type == FILE_MODE_APPEND) {
1156:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1157:     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1158: #else
1159:     if (type == FILE_MODE_WRITE) {
1160:       if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1161:     } else if (type == FILE_MODE_READ && fname) {
1162:       if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1163:     } else if (type == FILE_MODE_APPEND) {
1164:       if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1165:     } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1166: #endif
1167:   } else vbinary->fdes = -1;

1169:   /*
1170:       try to open info file: all processors open this file if read only
1171:   */
1172:   if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1173:     char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];

1175:     PetscStrcpy(infoname,vbinary->filename);
1176:     /* remove .gz if it ends library name */
1177:     PetscStrstr(infoname,".gz",&gz);
1178:     if (gz) {
1179:       PetscStrlen(gz,&len);
1180:       if (len == 3) *gz = 0;
1181:     }

1183:     PetscStrcat(infoname,".info");
1184:     PetscFixFilename(infoname,iname);
1185:     if (type == FILE_MODE_READ) {
1186:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1187:       PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1188:     } else {
1189:       vbinary->fdes_info = fopen(infoname,"w");
1190:       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1191:     }
1192:   }
1193: #if defined(PETSC_USE_LOG)
1194:   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1195: #endif
1196:   return(0);
1197: }

1199: #if defined(PETSC_HAVE_MPIIO)
1200: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1201: {
1202:   PetscMPIInt        rank;
1203:   PetscErrorCode     ierr;
1204:   size_t             len;
1205:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1206:   char               *gz;
1207:   PetscBool          found;
1208:   PetscFileMode      type = vbinary->btype;

1211:   if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1212:   if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1213:   PetscViewerFileClose_BinaryMPIIO(viewer);

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

1217:   vbinary->storecompressed = PETSC_FALSE;

1219:   /* only first processor opens file if writeable */
1220:   if (type == FILE_MODE_READ) {
1221:     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1222:   } else if (type == FILE_MODE_WRITE) {
1223:     MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1224:   }

1226:   /*
1227:       try to open info file: all processors open this file if read only

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

1234:     PetscStrcpy(infoname,vbinary->filename);
1235:     /* remove .gz if it ends library name */
1236:     PetscStrstr(infoname,".gz",&gz);
1237:     if (gz) {
1238:       PetscStrlen(gz,&len);
1239:       if (len == 3) *gz = 0;
1240:     }

1242:     PetscStrcat(infoname,".info");
1243:     PetscFixFilename(infoname,iname);
1244:     if (type == FILE_MODE_READ) {
1245:       PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1246:       PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1247:     } else {
1248:       vbinary->fdes_info = fopen(infoname,"w");
1249:       if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1250:     }
1251:   }
1252: #if defined(PETSC_USE_LOG)
1253:   PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1254: #endif
1255:   return(0);
1256: }

1258: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1259: {
1260:   PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1262:   vbinary->usempiio = flg;
1263:   return(0);
1264: }
1265: #endif

1267: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1268: {
1269:   PetscErrorCode     ierr;
1270:   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;

1273:   if (binary->filename) {
1274:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1275:   }
1276:   return(0);
1277: }

1279: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1280: {
1281:   PetscErrorCode     ierr;
1282:   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;

1285:   if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1286: 
1287: #if defined(PETSC_HAVE_MPIIO)
1288:   if (binary->usempiio) {
1289:     PetscViewerFileSetUp_BinaryMPIIO(v);
1290:   } else {
1291: #endif
1292:     PetscViewerFileSetUp_Binary(v);
1293: #if defined(PETSC_HAVE_MPIIO)
1294:   }
1295: #endif
1296:   return(0);
1297: }

1299: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1300: {
1301:   PetscErrorCode     ierr;
1302:   PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1303:   char               defaultname[PETSC_MAX_PATH_LEN];
1304:   PetscBool          flg;

1307:   PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1308:   PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1309:   PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1310:   if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1311:   PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1312:   PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1313:   PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1314: #if defined(PETSC_HAVE_MPIIO)
1315:   PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1316: #elif defined(PETSC_HAVE_MPIUNI)
1317:   PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1318: #endif
1319:   PetscOptionsTail();
1320:   binary->setfromoptionscalled = PETSC_TRUE;
1321:   return(0);
1322: }

1324: /*MC
1325:    PETSCVIEWERBINARY - A viewer that saves to binary files


1328: .seealso:  PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1329:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1330:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1331:            PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()

1333:   Level: beginner

1335: M*/

1337: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1338: {
1339:   PetscErrorCode     ierr;
1340:   PetscViewer_Binary *vbinary;

1343:   PetscNewLog(v,&vbinary);
1344:   v->data                  = (void*)vbinary;
1345:   v->ops->setfromoptions   = PetscViewerSetFromOptions_Binary;
1346:   v->ops->destroy          = PetscViewerDestroy_Binary;
1347:   v->ops->view             = PetscViewerView_Binary;
1348:   v->ops->setup            = PetscViewerSetUp_Binary;
1349:   v->ops->flush            = NULL;
1350:   vbinary->fdes_info       = 0;
1351:   vbinary->fdes            = 0;
1352:   vbinary->skipinfo        = PETSC_FALSE;
1353:   vbinary->skipoptions     = PETSC_TRUE;
1354:   vbinary->skipheader      = PETSC_FALSE;
1355:   vbinary->setfromoptionscalled = PETSC_FALSE;
1356:   v->ops->getsubviewer     = PetscViewerGetSubViewer_Binary;
1357:   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1358:   v->ops->read             = PetscViewerBinaryRead;
1359:   vbinary->btype           = (PetscFileMode) -1;
1360:   vbinary->storecompressed = PETSC_FALSE;
1361:   vbinary->filename        = 0;
1362:   vbinary->flowcontrol     = 256; /* seems a good number for Cray XT-5 */

1364:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1365:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1366:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1367:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1368:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1369:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1370:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1371:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1372:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1373:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1374:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1375:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1376:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1377: #if defined(PETSC_HAVE_MPIIO)
1378:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1379:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1380: #endif
1381:   return(0);
1382: }

1384: /* ---------------------------------------------------------------------*/
1385: /*
1386:     The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1387:   is attached to a communicator, in this case the attribute is a PetscViewer.
1388: */
1389: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;

1391: /*@C
1392:      PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1393:                      in a communicator.

1395:      Collective on MPI_Comm

1397:      Input Parameter:
1398: .    comm - the MPI communicator to share the binary PetscViewer

1400:      Level: intermediate

1402:    Options Database Keys:
1403: +    -viewer_binary_filename <name>
1404: .    -viewer_binary_skip_info
1405: .    -viewer_binary_skip_options
1406: .    -viewer_binary_skip_header
1407: -    -viewer_binary_mpiio

1409:    Environmental variables:
1410: -   PETSC_VIEWER_BINARY_FILENAME

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

1417: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1418:           PetscViewerDestroy()
1419: @*/
1420: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1421: {
1423:   PetscBool      flg;
1424:   PetscViewer    viewer;
1425:   char           fname[PETSC_MAX_PATH_LEN];
1426:   MPI_Comm       ncomm;

1429:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1430:   if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1431:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1432:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1433:   }
1434:   MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1435:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1436:   if (!flg) { /* PetscViewer not yet created */
1437:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1438:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1439:     if (!flg) {
1440:       PetscStrcpy(fname,"binaryoutput");
1441:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1442:     }
1443:     PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1444:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1445:     PetscObjectRegisterDestroy((PetscObject)viewer);
1446:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1447:     MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1448:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1449:   }
1450:   PetscCommDestroy(&ncomm);
1451:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1452:   PetscFunctionReturn(viewer);
1453: }