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, %D 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: }