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) {
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.
157: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
158: @*/
159: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
160: {
161: PetscViewer_Binary *vbinary;
166: vbinary = (PetscViewer_Binary*)viewer->data;
167: *off = vbinary->moff;
168: return(0);
169: }
171: /*@C
172: PetscViewerBinaryAddMPIIOOffset - Adds to the current global offset
174: Logically Collective
176: Input Parameters:
177: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
178: - off - the addition to the global offset
180: Level: advanced
182: Fortran Note:
183: This routine is not supported in Fortran.
185: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()
188: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
189: @*/
190: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
191: {
192: PetscViewer_Binary *vbinary;
197: vbinary = (PetscViewer_Binary*)viewer->data;
198: vbinary->moff += off;
199: return(0);
200: }
202: /*@C
203: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
205: Not Collective
207: Input Parameter:
208: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
210: Output Parameter:
211: . fdes - file descriptor
213: Level: advanced
215: Fortran Note:
216: This routine is not supported in Fortran.
219: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
220: @*/
221: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
222: {
223: PetscErrorCode ierr;
224: PetscViewer_Binary *vbinary;
229: PetscViewerSetUp(viewer);
230: vbinary = (PetscViewer_Binary*)viewer->data;
231: *fdes = vbinary->mfdes;
232: return(0);
233: }
234: #endif
236: /*@
237: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
238: before PetscViewerFileSetName()
240: Logically Collective on PetscViewer
242: Input Parameters:
243: + viewer - the PetscViewer; must be a binary
244: - use - PETSC_TRUE means MPI-IO will be used
246: Options Database:
247: -viewer_binary_mpiio : Flag for using MPI-IO
249: Level: advanced
251: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
252: PetscViewerBinaryGetUseMPIIO()
254: @*/
255: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool use)
256: {
262: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,use));
263: return(0);
264: }
266: #if defined(PETSC_HAVE_MPIIO)
267: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool use)
268: {
269: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
271: if (viewer->setupcalled && vbinary->usempiio != use) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change MPIIO to %s after setup",PetscBools[use]);
272: vbinary->usempiio = use;
273: return(0);
274: }
275: #endif
277: /*@
278: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
280: Not Collective
282: Input Parameter:
283: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
285: Output Parameter:
286: - use - PETSC_TRUE if MPI-IO is being used
288: Options Database:
289: -viewer_binary_mpiio : Flag for using MPI-IO
291: Level: advanced
293: Note:
294: If MPI-IO is not available, this function will always return PETSC_FALSE
296: Fortran Note:
297: This routine is not supported in Fortran.
300: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
301: @*/
302: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *use)
303: {
309: *use = PETSC_FALSE;
310: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,use));
311: return(0);
312: }
314: #if defined(PETSC_HAVE_MPIIO)
315: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *use)
316: {
317: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
320: *use = vbinary->usempiio;
321: return(0);
322: }
323: #endif
325: /*@
326: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
328: Not Collective
330: Input Parameter:
331: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
332: - fc - the number of messages, defaults to 256 if this function was not called
334: Level: advanced
336: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
338: @*/
339: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
340: {
346: PetscTryMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
347: return(0);
348: }
350: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
351: {
352: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
355: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
356: vbinary->flowcontrol = fc;
357: return(0);
358: }
360: /*@
361: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
363: Not Collective
365: Input Parameter:
366: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
368: Output Parameter:
369: . fc - the number of messages
371: Level: advanced
373: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
375: @*/
376: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
377: {
383: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
384: return(0);
385: }
387: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
388: {
389: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
392: *fc = vbinary->flowcontrol;
393: return(0);
394: }
396: /*@C
397: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
399: Collective On PetscViewer
401: Input Parameter:
402: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
404: Output Parameter:
405: . fdes - file descriptor
407: Level: advanced
409: Notes:
410: For writable binary PetscViewers, the descriptor will only be valid for the
411: first processor in the communicator that shares the PetscViewer. For readable
412: files it will only be valid on nodes that have the file. If node 0 does not
413: have the file it generates an error even if another node does have the file.
415: Fortran Note:
416: This routine is not supported in Fortran.
418: Developer Notes:
419: This must be called on all processes because Dave May changed
420: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
424: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
425: @*/
426: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
427: {
428: PetscErrorCode ierr;
429: PetscViewer_Binary *vbinary;
434: PetscViewerSetUp(viewer);
435: vbinary = (PetscViewer_Binary*)viewer->data;
436: *fdes = vbinary->fdes;
437: return(0);
438: }
440: /*@
441: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
443: Not Collective
445: Input Parameter:
446: . viewer - PetscViewer context, obtained from PetscViewerCreate()
448: Options Database Key:
449: . -viewer_binary_skip_info - true indicates do not generate .info file
451: Level: advanced
453: Notes:
454: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
455: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
456: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
458: The .info contains meta information about the data in the binary file, for example the block size if it was
459: set for a vector or matrix.
461: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
462: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
463: @*/
464: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
465: {
469: PetscViewerBinarySetSkipInfo(viewer,PETSC_TRUE);
470: return(0);
471: }
473: /*@
474: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
476: Not Collective
478: Input Parameter:
479: + viewer - PetscViewer context, obtained from PetscViewerCreate()
480: - skip - PETSC_TRUE implies the .info file will not be generated
482: Options Database Key:
483: . -viewer_binary_skip_info - true indicates do not generate .info file
485: Level: advanced
487: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
488: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
489: @*/
490: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
491: {
497: PetscTryMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
498: return(0);
499: }
501: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
502: {
503: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
506: vbinary->skipinfo = skip;
507: return(0);
508: }
510: /*@
511: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
513: Not Collective
515: Input Parameter:
516: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
518: Output Parameter:
519: . skip - PETSC_TRUE implies the .info file was not generated
521: Level: advanced
523: Notes:
524: This must be called after PetscViewerSetType()
526: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
527: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
528: @*/
529: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
530: {
536: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
537: return(0);
538: }
540: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
541: {
542: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
545: *skip = vbinary->skipinfo;
546: return(0);
547: }
549: /*@
550: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
552: Not Collective
554: Input Parameters:
555: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
556: - skip - PETSC_TRUE means do not use the options from the options database
558: Options Database Key:
559: . -viewer_binary_skip_options - true means do not use the options from the options database
561: Level: advanced
563: Notes:
564: This must be called after PetscViewerSetType()
566: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
567: PetscViewerBinaryGetSkipOptions()
568: @*/
569: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
570: {
576: PetscTryMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
577: return(0);
578: }
580: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
581: {
582: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
585: vbinary->skipoptions = skip;
586: return(0);
587: }
589: /*@
590: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
592: Not Collective
594: Input Parameter:
595: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
597: Output Parameter:
598: . skip - PETSC_TRUE means do not use
600: Level: advanced
602: Notes:
603: This must be called after PetscViewerSetType()
605: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
606: PetscViewerBinarySetSkipOptions()
607: @*/
608: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
609: {
615: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
616: return(0);
617: }
619: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
620: {
621: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
624: *skip = vbinary->skipoptions;
625: return(0);
626: }
628: /*@
629: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
631: Not Collective
633: Input Parameters:
634: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
635: - skip - PETSC_TRUE means do not write header
637: Options Database Key:
638: . -viewer_binary_skip_header - PETSC_TRUE means do not write header
640: Level: advanced
642: Notes:
643: This must be called after PetscViewerSetType()
645: Is ignored on anything but a binary viewer
647: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
648: PetscViewerBinaryGetSkipHeader()
649: @*/
650: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
651: {
657: PetscTryMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
658: return(0);
659: }
661: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
662: {
663: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
666: vbinary->skipheader = skip;
667: return(0);
668: }
670: /*@
671: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
673: Not Collective
675: Input Parameter:
676: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
678: Output Parameter:
679: . skip - PETSC_TRUE means do not write header
681: Level: advanced
683: Notes:
684: This must be called after PetscViewerSetType()
686: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
688: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
689: PetscViewerBinarySetSkipHeader()
690: @*/
691: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
692: {
698: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
699: return(0);
700: }
702: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
703: {
704: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
707: *skip = vbinary->skipheader;
708: return(0);
709: }
711: /*@C
712: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
713: info file associated with a binary file.
715: Not Collective
717: Input Parameter:
718: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
720: Output Parameter:
721: . file - file pointer Always returns NULL if not a binary viewer
723: Level: advanced
725: Notes:
726: For writable binary PetscViewers, the descriptor will only be valid for the
727: first processor in the communicator that shares the PetscViewer.
729: Fortran Note:
730: This routine is not supported in Fortran.
732: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
733: @*/
734: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
735: {
741: *file = NULL;
742: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
743: return(0);
744: }
746: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
747: {
748: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
749: PetscErrorCode ierr;
752: PetscViewerSetUp(viewer);
753: *file = vbinary->fdes_info;
754: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
755: if (vbinary->fdes_info) {
756: FILE *info = vbinary->fdes_info;
757: PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
758: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ Set.filename = '%s';\n",vbinary->filename);
759: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ fd = PetscOpenFile(Set.filename);\n");
760: PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
761: }
762: vbinary->matlabheaderwritten = PETSC_TRUE;
763: }
764: return(0);
765: }
768: #if defined(PETSC_HAVE_MPIIO)
769: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
770: {
771: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
772: PetscErrorCode ierr;
775: if (vbinary->mfdes != MPI_FILE_NULL) {
776: MPI_File_close(&vbinary->mfdes);
777: }
778: if (vbinary->mfsub != MPI_FILE_NULL) {
779: MPI_File_close(&vbinary->mfsub);
780: }
781: vbinary->moff = 0;
782: return(0);
783: }
784: #endif
786: static PetscErrorCode PetscViewerFileClose_BinarySTDIO(PetscViewer v)
787: {
788: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
789: PetscErrorCode ierr;
792: if (vbinary->fdes != -1) {
793: PetscBinaryClose(vbinary->fdes);
794: vbinary->fdes = -1;
795: if (vbinary->storecompressed) {
796: char cmd[8+PETSC_MAX_PATH_LEN],out[64+PETSC_MAX_PATH_LEN] = "";
797: const char *gzfilename = vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename;
798: /* compress the file */
799: PetscStrncpy(cmd,"gzip -f ",sizeof(cmd));
800: PetscStrlcat(cmd,gzfilename,sizeof(cmd));
801: #if defined(PETSC_HAVE_POPEN)
802: {
803: FILE *fp;
804: PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);
805: if (fgets(out,(int)(sizeof(out)-1),fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",cmd,out);
806: PetscPClose(PETSC_COMM_SELF,fp);
807: }
808: #endif
809: }
810: }
811: PetscFree(vbinary->ogzfilename);
812: return(0);
813: }
815: static PetscErrorCode PetscViewerFileClose_BinaryInfo(PetscViewer v)
816: {
817: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
818: PetscErrorCode ierr;
821: if (v->format == PETSC_VIEWER_BINARY_MATLAB && vbinary->matlabheaderwritten) {
822: if (vbinary->fdes_info) {
823: FILE *info = vbinary->fdes_info;
824: PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
825: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ close(fd);\n");
826: PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
827: }
828: }
829: if (vbinary->fdes_info) {
830: FILE *info = vbinary->fdes_info;
831: vbinary->fdes_info = NULL;
832: if (fclose(info)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
833: }
834: return(0);
835: }
837: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
838: {
839: PetscErrorCode ierr;
842: #if defined(PETSC_HAVE_MPIIO)
843: PetscViewerFileClose_BinaryMPIIO(v);
844: #endif
845: PetscViewerFileClose_BinarySTDIO(v);
846: PetscViewerFileClose_BinaryInfo(v);
847: return(0);
848: }
850: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
851: {
852: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
853: PetscErrorCode ierr;
856: PetscViewerFileClose_Binary(v);
857: PetscFree(vbinary->filename);
858: PetscFree(vbinary);
860: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",NULL);
861: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",NULL);
862: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",NULL);
863: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",NULL);
864: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",NULL);
865: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",NULL);
866: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",NULL);
867: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",NULL);
868: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",NULL);
869: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",NULL);
870: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",NULL);
871: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",NULL);
872: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",NULL);
873: #if defined(PETSC_HAVE_MPIIO)
874: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",NULL);
875: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",NULL);
876: #endif
877: return(0);
878: }
880: /*@C
881: PetscViewerBinaryOpen - Opens a file for binary input/output.
883: Collective
885: Input Parameters:
886: + comm - MPI communicator
887: . name - name of file
888: - mode - open mode of file
889: $ FILE_MODE_WRITE - create new file for binary output
890: $ FILE_MODE_READ - open existing file for binary input
891: $ FILE_MODE_APPEND - open existing file for binary output
893: Output Parameter:
894: . viewer - PetscViewer for binary input/output to use with the specified file
896: Options Database Keys:
897: + -viewer_binary_filename <name> -
898: . -viewer_binary_skip_info -
899: . -viewer_binary_skip_options -
900: . -viewer_binary_skip_header -
901: - -viewer_binary_mpiio -
903: Level: beginner
905: Note:
906: This PetscViewer should be destroyed with PetscViewerDestroy().
908: For reading files, the filename may begin with ftp:// or http:// and/or
909: end with .gz; in this case file is brought over and uncompressed.
911: For creating files, if the file name ends with .gz it is automatically
912: compressed when closed.
914: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
915: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
916: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
917: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
918: @*/
919: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode mode,PetscViewer *viewer)
920: {
924: PetscViewerCreate(comm,viewer);
925: PetscViewerSetType(*viewer,PETSCVIEWERBINARY);
926: PetscViewerFileSetMode(*viewer,mode);
927: PetscViewerFileSetName(*viewer,name);
928: PetscViewerSetFromOptions(*viewer);
929: return(0);
930: }
932: #if defined(PETSC_HAVE_MPIIO)
933: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
934: {
935: MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
936: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
937: MPI_File mfdes = vbinary->mfdes;
938: PetscErrorCode ierr;
939: MPI_Datatype mdtype;
940: PetscMPIInt rank,cnt;
941: MPI_Status status;
942: MPI_Aint ul,dsize;
945: MPI_Comm_rank(comm,&rank);
946: PetscMPIIntCast(num,&cnt);
947: PetscDataTypeToMPIDataType(dtype,&mdtype);
948: if (write) {
949: if (!rank) {
950: MPIU_File_write_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
951: }
952: } else {
953: if (!rank) {
954: MPIU_File_read_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
955: if (cnt > 0) {MPI_Get_count(&status,mdtype,&cnt);}
956: }
957: MPI_Bcast(&cnt,1,MPI_INT,0,comm);
958: MPI_Bcast(data,cnt,mdtype,0,comm);
959: }
960: MPI_Type_get_extent(mdtype,&ul,&dsize);
961: vbinary->moff += dsize*cnt;
962: if (count) *count = cnt;
963: return(0);
964: }
965: #endif
967: /*@C
968: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
970: Collective
972: Input Parameters:
973: + viewer - the binary viewer
974: . data - location of the data to be written
975: . num - number of items of data to read
976: - dtype - type of data to read
978: Output Parameters:
979: . count - number of items of data actually read, or NULL.
981: Level: beginner
983: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
984: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
985: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
986: @*/
987: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
988: {
989: PetscErrorCode ierr;
990: PetscViewer_Binary *vbinary;
995: PetscViewerSetUp(viewer);
996: vbinary = (PetscViewer_Binary*)viewer->data;
997: #if defined(PETSC_HAVE_MPIIO)
998: if (vbinary->usempiio) {
999: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
1000: } else {
1001: #endif
1002: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);
1003: #if defined(PETSC_HAVE_MPIIO)
1004: }
1005: #endif
1006: return(0);
1007: }
1009: /*@C
1010: PetscViewerBinaryWrite - writes to a binary file, only from the first process
1012: Collective
1014: Input Parameters:
1015: + viewer - the binary viewer
1016: . data - location of data
1017: . count - number of items of data to write
1018: - dtype - type of data to write
1020: Level: beginner
1022: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1023: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
1024: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1025: @*/
1026: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,const void *data,PetscInt count,PetscDataType dtype)
1027: {
1028: PetscErrorCode ierr;
1029: PetscViewer_Binary *vbinary;
1034: PetscViewerSetUp(viewer);
1035: vbinary = (PetscViewer_Binary*)viewer->data;
1036: #if defined(PETSC_HAVE_MPIIO)
1037: if (vbinary->usempiio) {
1038: PetscViewerBinaryWriteReadMPIIO(viewer,(void*)data,count,NULL,dtype,PETSC_TRUE);
1039: } else {
1040: #endif
1041: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);
1042: #if defined(PETSC_HAVE_MPIIO)
1043: }
1044: #endif
1045: return(0);
1046: }
1048: static PetscErrorCode PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1049: {
1050: MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
1051: PetscMPIInt size,rank;
1052: MPI_Datatype mdtype;
1053: PETSC_UNUSED MPI_Aint lb;
1054: MPI_Aint dsize;
1055: PetscBool useMPIIO;
1056: PetscErrorCode ierr;
1063: PetscViewerSetUp(viewer);
1065: PetscDataTypeToMPIDataType(dtype,&mdtype);
1066: MPI_Type_get_extent(mdtype,&lb,&dsize);
1067: MPI_Comm_rank(comm,&rank);
1068: MPI_Comm_size(comm,&size);
1070: PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);
1071: #if defined(PETSC_HAVE_MPIIO)
1072: if (useMPIIO) {
1073: MPI_File mfdes;
1074: MPI_Offset off;
1075: PetscMPIInt cnt;
1077: if (start == PETSC_DETERMINE) {
1078: MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);
1079: start -= count;
1080: }
1081: if (total == PETSC_DETERMINE) {
1082: total = start + count;
1083: MPI_Bcast(&total,1,MPIU_INT,size-1,comm);
1084: }
1085: PetscMPIIntCast(count,&cnt);
1086: PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
1087: PetscViewerBinaryGetMPIIOOffset(viewer,&off);
1088: off += (MPI_Offset)(start*dsize);
1089: if (write) {
1090: MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1091: } else {
1092: MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1093: }
1094: off = (MPI_Offset)(total*dsize);
1095: PetscViewerBinaryAddMPIIOOffset(viewer,off);
1096: return(0);
1097: }
1098: #endif
1099: {
1100: int fdes;
1101: char *workbuf = NULL;
1102: PetscInt tcount = !rank ? 0 : count,maxcount=0,message_count,flowcontrolcount;
1103: PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j;
1104: MPI_Status status;
1106: PetscCommGetNewTag(comm,&tag);
1107: MPI_Reduce(&tcount,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);
1108: PetscMPIIntCast(maxcount,&maxcnt);
1109: PetscMPIIntCast(count,&cnt);
1111: PetscViewerBinaryGetDescriptor(viewer,&fdes);
1112: PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);
1113: if (!rank) {
1114: PetscMalloc(maxcnt*dsize,&workbuf);
1115: if (write) {
1116: PetscBinaryWrite(fdes,data,cnt,dtype);
1117: } else {
1118: PetscBinaryRead(fdes,data,cnt,NULL,dtype);
1119: }
1120: for (j=1; j<size; j++) {
1121: PetscViewerFlowControlStepMain(viewer,j,&message_count,flowcontrolcount);
1122: if (write) {
1123: MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);
1124: MPI_Get_count(&status,mdtype,&rcnt);
1125: PetscBinaryWrite(fdes,workbuf,rcnt,dtype);
1126: } else {
1127: MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);
1128: PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);
1129: MPI_Send(workbuf,scnt,mdtype,j,tag,comm);
1130: }
1131: }
1132: PetscFree(workbuf);
1133: PetscViewerFlowControlEndMain(viewer,&message_count);
1134: } else {
1135: PetscViewerFlowControlStepWorker(viewer,rank,&message_count);
1136: if (write) {
1137: MPI_Send(data,cnt,mdtype,0,tag,comm);
1138: } else {
1139: MPI_Send(&cnt,1,MPI_INT,0,tag,comm);
1140: MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);
1141: }
1142: PetscViewerFlowControlEndWorker(viewer,&message_count);
1143: }
1144: }
1145: return(0);
1146: }
1148: /*@C
1149: PetscViewerBinaryReadAll - reads from a binary file from all processes
1151: Collective
1153: Input Parameters:
1154: + viewer - the binary viewer
1155: . data - location of data
1156: . count - local number of items of data to read
1157: . start - local start, can be PETSC_DETERMINE
1158: . total - global number of items of data to read, can be PETSC_DETERMINE
1159: - dtype - type of data to read
1161: Level: advanced
1163: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll()
1164: @*/
1165: PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1166: {
1169: PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);
1170: return(0);
1171: }
1173: /*@C
1174: PetscViewerBinaryWriteAll - writes to a binary file from all processes
1176: Collective
1178: Input Parameters:
1179: + viewer - the binary viewer
1180: . data - location of data
1181: . count - local number of items of data to write
1182: . start - local start, can be PETSC_DETERMINE
1183: . total - global number of items of data to write, can be PETSC_DETERMINE
1184: - dtype - type of data to write
1186: Level: advanced
1188: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll()
1189: @*/
1190: PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1191: {
1194: PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);
1195: return(0);
1196: }
1198: /*@C
1199: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
1201: Collective
1203: Input Parameters:
1204: + viewer - the binary viewer
1205: - data - location of the array of strings
1208: Level: intermediate
1210: Notes:
1211: array of strings is null terminated
1213: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1214: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1215: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1216: @*/
1217: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
1218: {
1220: PetscInt i,n = 0,*sizes;
1221: size_t len;
1224: PetscViewerSetUp(viewer);
1225: /* count number of strings */
1226: while (data[n++]);
1227: n--;
1228: PetscMalloc1(n+1,&sizes);
1229: sizes[0] = n;
1230: for (i=0; i<n; i++) {
1231: PetscStrlen(data[i],&len);
1232: sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */
1233: }
1234: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);
1235: for (i=0; i<n; i++) {
1236: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);
1237: }
1238: PetscFree(sizes);
1239: return(0);
1240: }
1242: /*@C
1243: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1245: Collective
1247: Input Parameter:
1248: . viewer - the binary viewer
1250: Output Parameter:
1251: . data - location of the array of strings
1253: Level: intermediate
1255: Notes:
1256: array of strings is null terminated
1258: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1259: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1260: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1261: @*/
1262: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1263: {
1265: PetscInt i,n,*sizes,N = 0;
1268: PetscViewerSetUp(viewer);
1269: /* count number of strings */
1270: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1271: PetscMalloc1(n,&sizes);
1272: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1273: for (i=0; i<n; i++) N += sizes[i];
1274: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1275: (*data)[0] = (char*)((*data) + n + 1);
1276: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1277: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1278: (*data)[n] = NULL;
1279: PetscFree(sizes);
1280: return(0);
1281: }
1283: /*@C
1284: PetscViewerFileSetMode - Sets the open mode of file
1286: Logically Collective on PetscViewer
1288: Input Parameters:
1289: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1290: - mode - open mode of file
1291: $ FILE_MODE_WRITE - create new file for output
1292: $ FILE_MODE_READ - open existing file for input
1293: $ FILE_MODE_APPEND - open existing file for output
1295: Level: advanced
1297: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1299: @*/
1300: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)
1301: {
1307: if (mode == FILE_MODE_UNDEFINED) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot set FILE_MODE_UNDEFINED");
1308: 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);
1309: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));
1310: return(0);
1311: }
1313: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)
1314: {
1315: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1318: if (viewer->setupcalled && vbinary->filemode != mode) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[mode]);
1319: vbinary->filemode = mode;
1320: return(0);
1321: }
1323: /*@C
1324: PetscViewerFileGetMode - Gets the open mode of file
1326: Not Collective
1328: Input Parameter:
1329: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1331: Output Parameter:
1332: . mode - open mode of file
1333: $ FILE_MODE_WRITE - create new file for binary output
1334: $ FILE_MODE_READ - open existing file for binary input
1335: $ FILE_MODE_APPEND - open existing file for binary output
1337: Level: advanced
1339: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1341: @*/
1342: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode)
1343: {
1349: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));
1350: return(0);
1351: }
1353: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode)
1354: {
1355: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1358: *mode = vbinary->filemode;
1359: return(0);
1360: }
1362: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1363: {
1364: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1365: PetscErrorCode ierr;
1368: if (viewer->setupcalled && vbinary->filename) {
1369: /* gzip can be run after the file with the previous filename has been closed */
1370: PetscFree(vbinary->ogzfilename);
1371: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1372: }
1373: PetscFree(vbinary->filename);
1374: PetscStrallocpy(name,&vbinary->filename);
1375: viewer->setupcalled = PETSC_FALSE;
1376: return(0);
1377: }
1379: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1380: {
1381: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1384: *name = vbinary->filename;
1385: return(0);
1386: }
1388: #if defined(PETSC_HAVE_MPIIO)
1389: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1390: {
1391: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1392: int amode;
1393: PetscErrorCode ierr;
1396: vbinary->storecompressed = PETSC_FALSE;
1398: vbinary->moff = 0;
1399: switch (vbinary->filemode) {
1400: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1401: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1402: case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break;
1403: case FILE_MODE_UNDEFINED: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerSetUp()");
1404: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
1405: }
1406: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1407: /*
1408: The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero.
1409: */
1410: if (vbinary->filemode == FILE_MODE_WRITE) {MPI_File_set_size(vbinary->mfdes,0);}
1411: /*
1412: Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND,
1413: MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file.
1414: Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert
1415: the offset in etype units to an absolute byte position.
1416: */
1417: if (vbinary->filemode == FILE_MODE_APPEND) {MPI_File_get_position(vbinary->mfdes,&vbinary->moff);}
1418: return(0);
1419: }
1420: #endif
1422: static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)
1423: {
1424: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1425: const char *fname;
1426: char bname[PETSC_MAX_PATH_LEN],*gz;
1427: PetscBool found;
1428: PetscMPIInt rank;
1429: PetscErrorCode ierr;
1432: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1434: /* if file name ends in .gz strip that off and note user wants file compressed */
1435: vbinary->storecompressed = PETSC_FALSE;
1436: if (vbinary->filemode == FILE_MODE_WRITE) {
1437: PetscStrstr(vbinary->filename,".gz",&gz);
1438: if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;}
1439: }
1440: #if !defined(PETSC_HAVE_POPEN)
1441: if (vbinary->storecompressed) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP_SYS,"Cannot run gzip on this machine");
1442: #endif
1445: fname = vbinary->filename;
1446: if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */
1447: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);
1448: if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s",fname);
1449: fname = bname;
1450: }
1452: vbinary->fdes = -1;
1453: if (!rank) { /* only first processor opens file*/
1454: PetscFileMode mode = vbinary->filemode;
1455: if (mode == FILE_MODE_APPEND) {
1456: /* check if asked to append to a non-existing file */
1457: PetscTestFile(fname,'\0',&found);
1458: if (!found) mode = FILE_MODE_WRITE;
1459: }
1460: PetscBinaryOpen(fname,mode,&vbinary->fdes);
1461: }
1462: return(0);
1463: }
1465: static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)
1466: {
1467: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1468: PetscMPIInt rank;
1469: PetscBool found;
1470: PetscErrorCode ierr;
1473: vbinary->fdes_info = NULL;
1474: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1475: if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || !rank)) {
1476: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz;
1478: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1479: /* remove .gz if it ends file name */
1480: PetscStrstr(infoname,".gz",&gz);
1481: if (gz && gz[3] == 0) *gz = 0;
1483: PetscStrlcat(infoname,".info",sizeof(infoname));
1484: if (vbinary->filemode == FILE_MODE_READ) {
1485: PetscFixFilename(infoname,iname);
1486: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1487: if (found) {PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);}
1488: } else if (!rank) { /* write or append */
1489: const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w";
1490: vbinary->fdes_info = fopen(infoname,omode);
1491: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1492: }
1493: }
1494: return(0);
1495: }
1497: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer)
1498: {
1499: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1500: PetscBool usempiio;
1501: PetscErrorCode ierr;
1504: if (!vbinary->setfromoptionscalled) {PetscViewerSetFromOptions(viewer);}
1505: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1506: if (vbinary->filemode == (PetscFileMode)-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1507: PetscViewerFileClose_Binary(viewer);
1509: PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);
1510: if (usempiio) {
1511: #if defined(PETSC_HAVE_MPIIO)
1512: PetscViewerFileSetUp_BinaryMPIIO(viewer);
1513: #endif
1514: } else {
1515: PetscViewerFileSetUp_BinarySTDIO(viewer);
1516: }
1517: PetscViewerFileSetUp_BinaryInfo(viewer);
1519: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1520: return(0);
1521: }
1523: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1524: {
1525: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
1526: const char *fname = vbinary->filename ? vbinary->filename : "not yet set";
1527: const char *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set";
1528: PetscBool usempiio;
1529: PetscErrorCode ierr;
1532: PetscViewerBinaryGetUseMPIIO(v,&usempiio);
1533: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);
1534: PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");
1535: return(0);
1536: }
1538: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer)
1539: {
1540: PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data;
1541: char defaultname[PETSC_MAX_PATH_LEN];
1542: PetscBool flg;
1543: PetscErrorCode ierr;
1546: if (viewer->setupcalled) return(0);
1547: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1548: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1549: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,sizeof(defaultname),&flg);
1550: if (flg) { PetscViewerFileSetName_Binary(viewer,defaultname); }
1551: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);
1552: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);
1553: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);
1554: #if defined(PETSC_HAVE_MPIIO)
1555: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);
1556: #else
1557: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1558: #endif
1559: PetscOptionsTail();
1560: binary->setfromoptionscalled = PETSC_TRUE;
1561: return(0);
1562: }
1564: /*MC
1565: PETSCVIEWERBINARY - A viewer that saves to binary files
1568: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1569: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1570: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1571: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1573: Level: beginner
1575: M*/
1577: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1578: {
1579: PetscErrorCode ierr;
1580: PetscViewer_Binary *vbinary;
1583: PetscNewLog(v,&vbinary);
1584: v->data = (void*)vbinary;
1586: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1587: v->ops->destroy = PetscViewerDestroy_Binary;
1588: v->ops->view = PetscViewerView_Binary;
1589: v->ops->setup = PetscViewerSetUp_Binary;
1590: v->ops->flush = NULL; /* Should we support Flush() ? */
1591: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1592: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1593: v->ops->read = PetscViewerBinaryRead;
1595: vbinary->fdes = -1;
1596: #if defined(PETSC_HAVE_MPIIO)
1597: vbinary->usempiio = PETSC_FALSE;
1598: vbinary->mfdes = MPI_FILE_NULL;
1599: vbinary->mfsub = MPI_FILE_NULL;
1600: #endif
1601: vbinary->filename = NULL;
1602: vbinary->filemode = FILE_MODE_UNDEFINED;
1603: vbinary->fdes_info = NULL;
1604: vbinary->skipinfo = PETSC_FALSE;
1605: vbinary->skipoptions = PETSC_TRUE;
1606: vbinary->skipheader = PETSC_FALSE;
1607: vbinary->storecompressed = PETSC_FALSE;
1608: vbinary->ogzfilename = NULL;
1609: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1611: vbinary->setfromoptionscalled = PETSC_FALSE;
1613: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1614: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1615: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1616: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1617: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1618: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1619: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1620: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1621: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1622: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1623: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1624: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1625: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1626: #if defined(PETSC_HAVE_MPIIO)
1627: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1628: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1629: #endif
1630: return(0);
1631: }
1633: /* ---------------------------------------------------------------------*/
1634: /*
1635: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1636: is attached to a communicator, in this case the attribute is a PetscViewer.
1637: */
1638: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1640: /*@C
1641: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1642: in a communicator.
1644: Collective
1646: Input Parameter:
1647: . comm - the MPI communicator to share the binary PetscViewer
1649: Level: intermediate
1651: Options Database Keys:
1652: + -viewer_binary_filename <name> - filename in which to store the binary data, defaults to binaryoutput
1653: . -viewer_binary_skip_info - true means do not create .info file for this viewer
1654: . -viewer_binary_skip_options - true means do not use the options database for this viewer
1655: . -viewer_binary_skip_header - true means do not store the usual header information in the binary file
1656: - -viewer_binary_mpiio - true means use the file via MPI-IO, maybe faster for large files and many MPI ranks
1658: Environmental variables:
1659: - PETSC_VIEWER_BINARY_FILENAME - filename in which to store the binary data, defaults to binaryoutput
1661: Notes:
1662: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1663: an error code. The binary PetscViewer is usually used in the form
1664: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1666: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1667: PetscViewerDestroy()
1668: @*/
1669: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1670: {
1672: PetscBool flg;
1673: PetscViewer viewer;
1674: char fname[PETSC_MAX_PATH_LEN];
1675: MPI_Comm ncomm;
1678: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1679: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1680: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL);
1681: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1682: }
1683: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1684: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1685: if (!flg) { /* PetscViewer not yet created */
1686: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1687: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1688: if (!flg) {
1689: PetscStrcpy(fname,"binaryoutput");
1690: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1691: }
1692: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1693: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1694: PetscObjectRegisterDestroy((PetscObject)viewer);
1695: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1696: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1697: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1698: }
1699: PetscCommDestroy(&ncomm);
1700: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);}
1701: PetscFunctionReturn(viewer);
1702: }