Actual source code: binv.c
petsc-3.13.6 2020-09-29
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
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
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
558: Options Database Key:
559: . -viewer_binary_skip_options
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
640: Level: advanced
642: Notes:
643: This must be called after PetscViewerSetType()
645: Can ONLY be called on 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: MPI_Aint lb,dsize;
1054: PetscBool useMPIIO;
1062: PetscViewerSetUp(viewer);
1064: PetscDataTypeToMPIDataType(dtype,&mdtype);
1065: MPI_Type_get_extent(mdtype,&lb,&dsize);
1066: MPI_Comm_rank(comm,&rank);
1067: MPI_Comm_size(comm,&size);
1069: PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);
1070: #if defined(PETSC_HAVE_MPIIO)
1071: if (useMPIIO) {
1072: MPI_File mfdes;
1073: MPI_Offset off;
1074: PetscMPIInt cnt;
1076: if (start == PETSC_DETERMINE) {
1077: MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);
1078: start -= count;
1079: }
1080: if (total == PETSC_DETERMINE) {
1081: total = start + count;
1082: MPI_Bcast(&total,1,MPIU_INT,size-1,comm);
1083: }
1084: PetscMPIIntCast(count,&cnt);
1085: PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
1086: PetscViewerBinaryGetMPIIOOffset(viewer,&off);
1087: off += (MPI_Offset)(start*dsize);
1088: if (write) {
1089: MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1090: } else {
1091: MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1092: }
1093: off = (MPI_Offset)(total*dsize);
1094: PetscViewerBinaryAddMPIIOOffset(viewer,off);
1095: return(0);
1096: }
1097: #endif
1098: {
1099: int fdes;
1100: char *workbuf = NULL;
1101: PetscInt maxcount=0,message_count,flowcontrolcount;
1102: PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j;
1103: MPI_Status status;
1105: PetscCommGetNewTag(comm,&tag);
1106: MPI_Reduce(&count,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);
1107: PetscMPIIntCast(maxcount,&maxcnt);
1108: PetscMPIIntCast(count,&cnt);
1110: PetscViewerBinaryGetDescriptor(viewer,&fdes);
1111: PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);
1112: if (!rank) {
1113: PetscMalloc(maxcnt*dsize,&workbuf);
1114: if (write) {
1115: PetscBinaryWrite(fdes,data,cnt,dtype);
1116: } else {
1117: PetscBinaryRead(fdes,data,cnt,NULL,dtype);
1118: }
1119: for (j=1; j<size; j++) {
1120: PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);
1121: if (write) {
1122: MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);
1123: MPI_Get_count(&status,mdtype,&rcnt);
1124: PetscBinaryWrite(fdes,workbuf,rcnt,dtype);
1125: } else {
1126: MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);
1127: PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);
1128: MPI_Send(workbuf,scnt,mdtype,j,tag,comm);
1129: }
1130: }
1131: PetscFree(workbuf);
1132: PetscViewerFlowControlEndMaster(viewer,&message_count);
1133: } else {
1134: PetscViewerFlowControlStepWorker(viewer,rank,&message_count);
1135: if (write) {
1136: MPI_Send(data,cnt,mdtype,0,tag,comm);
1137: } else {
1138: MPI_Send(&cnt,1,MPI_INT,0,tag,comm);
1139: MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);
1140: }
1141: PetscViewerFlowControlEndWorker(viewer,&message_count);
1142: }
1143: }
1144: return(0);
1145: }
1147: /*@C
1148: PetscViewerBinaryReadAll - reads from a binary file from all processes
1150: Collective
1152: Input Parameters:
1153: + viewer - the binary viewer
1154: . data - location of data
1155: . count - local number of items of data to read
1156: . start - local start, can be PETSC_DETERMINE
1157: . total - global number of items of data to read, can be PETSC_DETERMINE
1158: - dtype - type of data to read
1160: Level: advanced
1162: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll()
1163: @*/
1164: PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1165: {
1168: PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);
1169: return(0);
1170: }
1172: /*@C
1173: PetscViewerBinaryWriteAll - writes to a binary file from all processes
1175: Collective
1177: Input Parameters:
1178: + viewer - the binary viewer
1179: . data - location of data
1180: . count - local number of items of data to write
1181: . start - local start, can be PETSC_DETERMINE
1182: . total - global number of items of data to write, can be PETSC_DETERMINE
1183: - dtype - type of data to write
1185: Level: advanced
1187: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll()
1188: @*/
1189: PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1190: {
1193: PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);
1194: return(0);
1195: }
1197: /*@C
1198: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
1200: Collective
1202: Input Parameters:
1203: + viewer - the binary viewer
1204: - data - location of the array of strings
1207: Level: intermediate
1209: Notes:
1210: array of strings is null terminated
1212: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1213: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1214: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1215: @*/
1216: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
1217: {
1219: PetscInt i,n = 0,*sizes;
1220: size_t len;
1223: PetscViewerSetUp(viewer);
1224: /* count number of strings */
1225: while (data[n++]);
1226: n--;
1227: PetscMalloc1(n+1,&sizes);
1228: sizes[0] = n;
1229: for (i=0; i<n; i++) {
1230: PetscStrlen(data[i],&len);
1231: sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */
1232: }
1233: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);
1234: for (i=0; i<n; i++) {
1235: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);
1236: }
1237: PetscFree(sizes);
1238: return(0);
1239: }
1241: /*@C
1242: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1244: Collective
1246: Input Parameter:
1247: . viewer - the binary viewer
1249: Output Parameter:
1250: . data - location of the array of strings
1252: Level: intermediate
1254: Notes:
1255: array of strings is null terminated
1257: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1258: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1259: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1260: @*/
1261: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1262: {
1264: PetscInt i,n,*sizes,N = 0;
1267: PetscViewerSetUp(viewer);
1268: /* count number of strings */
1269: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1270: PetscMalloc1(n,&sizes);
1271: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1272: for (i=0; i<n; i++) N += sizes[i];
1273: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1274: (*data)[0] = (char*)((*data) + n + 1);
1275: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1276: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1277: (*data)[n] = NULL;
1278: PetscFree(sizes);
1279: return(0);
1280: }
1282: /*@C
1283: PetscViewerFileSetMode - Sets the open mode of file
1285: Logically Collective on PetscViewer
1287: Input Parameters:
1288: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1289: - mode - open mode of file
1290: $ FILE_MODE_WRITE - create new file for output
1291: $ FILE_MODE_READ - open existing file for input
1292: $ FILE_MODE_APPEND - open existing file for output
1294: Level: advanced
1296: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1298: @*/
1299: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)
1300: {
1306: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));
1307: return(0);
1308: }
1310: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)
1311: {
1312: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1315: if (viewer->setupcalled && vbinary->filemode != mode) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[mode]);
1316: vbinary->filemode = mode;
1317: return(0);
1318: }
1320: /*@C
1321: PetscViewerFileGetMode - Gets the open mode of file
1323: Not Collective
1325: Input Parameter:
1326: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1328: Output Parameter:
1329: . mode - open mode of file
1330: $ FILE_MODE_WRITE - create new file for binary output
1331: $ FILE_MODE_READ - open existing file for binary input
1332: $ FILE_MODE_APPEND - open existing file for binary output
1334: Level: advanced
1336: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1338: @*/
1339: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode)
1340: {
1346: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));
1347: return(0);
1348: }
1350: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode)
1351: {
1352: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1355: *mode = vbinary->filemode;
1356: return(0);
1357: }
1359: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1360: {
1361: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1362: PetscErrorCode ierr;
1365: if (viewer->setupcalled && vbinary->filename) {
1366: /* gzip can be run after the file with the previous filename has been closed */
1367: PetscFree(vbinary->ogzfilename);
1368: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1369: }
1370: PetscFree(vbinary->filename);
1371: PetscStrallocpy(name,&vbinary->filename);
1372: viewer->setupcalled = PETSC_FALSE;
1373: return(0);
1374: }
1376: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1377: {
1378: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1381: *name = vbinary->filename;
1382: return(0);
1383: }
1385: #if defined(PETSC_HAVE_MPIIO)
1386: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1387: {
1388: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1389: int amode;
1390: PetscErrorCode ierr;
1393: vbinary->storecompressed = PETSC_FALSE;
1395: vbinary->moff = 0;
1396: switch (vbinary->filemode) {
1397: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1398: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1399: case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break;
1400: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
1401: }
1402: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1403: /*
1404: The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero.
1405: */
1406: if (vbinary->filemode == FILE_MODE_WRITE) {MPI_File_set_size(vbinary->mfdes,0);}
1407: /*
1408: Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND,
1409: MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file.
1410: Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert
1411: the offset in etype units to an absolute byte position.
1412: */
1413: if (vbinary->filemode == FILE_MODE_APPEND) {MPI_File_get_position(vbinary->mfdes,&vbinary->moff);}
1414: return(0);
1415: }
1416: #endif
1418: static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)
1419: {
1420: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1421: const char *fname;
1422: char bname[PETSC_MAX_PATH_LEN],*gz;
1423: PetscBool found;
1424: PetscMPIInt rank;
1425: PetscErrorCode ierr;
1428: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1430: /* if file name ends in .gz strip that off and note user wants file compressed */
1431: vbinary->storecompressed = PETSC_FALSE;
1432: if (vbinary->filemode == FILE_MODE_WRITE) {
1433: PetscStrstr(vbinary->filename,".gz",&gz);
1434: if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;}
1435: }
1436: #if !defined(PETSC_HAVE_POPEN)
1437: if (vbinary->storecompressed) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP_SYS,"Cannot run gzip on this machine");
1438: #endif
1441: fname = vbinary->filename;
1442: if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */
1443: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);
1444: if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s",fname);
1445: fname = bname;
1446: }
1448: vbinary->fdes = -1;
1449: if (!rank) { /* only first processor opens file*/
1450: PetscFileMode mode = vbinary->filemode;
1451: if (mode == FILE_MODE_APPEND) {
1452: /* check if asked to append to a non-existing file */
1453: PetscTestFile(fname,'\0',&found);
1454: if (!found) mode = FILE_MODE_WRITE;
1455: }
1456: PetscBinaryOpen(fname,mode,&vbinary->fdes);
1457: }
1458: return(0);
1459: }
1461: static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)
1462: {
1463: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1464: PetscMPIInt rank;
1465: PetscBool found;
1466: PetscErrorCode ierr;
1469: vbinary->fdes_info = NULL;
1470: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1471: if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || !rank)) {
1472: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz;
1474: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1475: /* remove .gz if it ends file name */
1476: PetscStrstr(infoname,".gz",&gz);
1477: if (gz && gz[3] == 0) *gz = 0;
1479: PetscStrlcat(infoname,".info",sizeof(infoname));
1480: if (vbinary->filemode == FILE_MODE_READ) {
1481: PetscFixFilename(infoname,iname);
1482: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1483: if (found) {PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);}
1484: } else if (!rank) { /* write or append */
1485: const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w";
1486: vbinary->fdes_info = fopen(infoname,omode);
1487: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1488: }
1489: }
1490: return(0);
1491: }
1493: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer)
1494: {
1495: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1496: PetscBool usempiio;
1497: PetscErrorCode ierr;
1500: if (!vbinary->setfromoptionscalled) {PetscViewerSetFromOptions(viewer);}
1501: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1502: if (vbinary->filemode == (PetscFileMode)-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1503: PetscViewerFileClose_Binary(viewer);
1505: PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);
1506: if (usempiio) {
1507: #if defined(PETSC_HAVE_MPIIO)
1508: PetscViewerFileSetUp_BinaryMPIIO(viewer);
1509: #endif
1510: } else {
1511: PetscViewerFileSetUp_BinarySTDIO(viewer);
1512: }
1513: PetscViewerFileSetUp_BinaryInfo(viewer);
1515: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1516: return(0);
1517: }
1519: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1520: {
1521: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
1522: const char *fname = vbinary->filename ? vbinary->filename : "not yet set";
1523: const char *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set";
1524: PetscBool usempiio;
1525: PetscErrorCode ierr;
1528: PetscViewerBinaryGetUseMPIIO(v,&usempiio);
1529: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);
1530: PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");
1531: return(0);
1532: }
1534: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer)
1535: {
1536: PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data;
1537: char defaultname[PETSC_MAX_PATH_LEN];
1538: PetscBool flg;
1539: PetscErrorCode ierr;
1542: if (viewer->setupcalled) return(0);
1543: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1544: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1545: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1546: if (flg) { PetscViewerFileSetName_Binary(viewer,defaultname); }
1547: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);
1548: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);
1549: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);
1550: #if defined(PETSC_HAVE_MPIIO)
1551: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);
1552: #else
1553: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1554: #endif
1555: PetscOptionsTail();
1556: binary->setfromoptionscalled = PETSC_TRUE;
1557: return(0);
1558: }
1560: /*MC
1561: PETSCVIEWERBINARY - A viewer that saves to binary files
1564: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1565: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1566: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1567: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1569: Level: beginner
1571: M*/
1573: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1574: {
1575: PetscErrorCode ierr;
1576: PetscViewer_Binary *vbinary;
1579: PetscNewLog(v,&vbinary);
1580: v->data = (void*)vbinary;
1582: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1583: v->ops->destroy = PetscViewerDestroy_Binary;
1584: v->ops->view = PetscViewerView_Binary;
1585: v->ops->setup = PetscViewerSetUp_Binary;
1586: v->ops->flush = NULL; /* Should we support Flush() ? */
1587: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1588: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1589: v->ops->read = PetscViewerBinaryRead;
1591: vbinary->fdes = -1;
1592: #if defined(PETSC_HAVE_MPIIO)
1593: vbinary->usempiio = PETSC_FALSE;
1594: vbinary->mfdes = MPI_FILE_NULL;
1595: vbinary->mfsub = MPI_FILE_NULL;
1596: #endif
1597: vbinary->filename = NULL;
1598: vbinary->filemode = (PetscFileMode)-1;
1599: vbinary->fdes_info = NULL;
1600: vbinary->skipinfo = PETSC_FALSE;
1601: vbinary->skipoptions = PETSC_TRUE;
1602: vbinary->skipheader = PETSC_FALSE;
1603: vbinary->storecompressed = PETSC_FALSE;
1604: vbinary->ogzfilename = NULL;
1605: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1607: vbinary->setfromoptionscalled = PETSC_FALSE;
1609: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1610: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1611: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1612: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1613: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1614: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1615: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1616: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1617: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1618: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1619: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1620: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1621: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1622: #if defined(PETSC_HAVE_MPIIO)
1623: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1624: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1625: #endif
1626: return(0);
1627: }
1629: /* ---------------------------------------------------------------------*/
1630: /*
1631: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1632: is attached to a communicator, in this case the attribute is a PetscViewer.
1633: */
1634: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1636: /*@C
1637: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1638: in a communicator.
1640: Collective
1642: Input Parameter:
1643: . comm - the MPI communicator to share the binary PetscViewer
1645: Level: intermediate
1647: Options Database Keys:
1648: + -viewer_binary_filename <name>
1649: . -viewer_binary_skip_info
1650: . -viewer_binary_skip_options
1651: . -viewer_binary_skip_header
1652: - -viewer_binary_mpiio
1654: Environmental variables:
1655: - PETSC_VIEWER_BINARY_FILENAME
1657: Notes:
1658: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1659: an error code. The binary PetscViewer is usually used in the form
1660: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1662: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1663: PetscViewerDestroy()
1664: @*/
1665: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1666: {
1668: PetscBool flg;
1669: PetscViewer viewer;
1670: char fname[PETSC_MAX_PATH_LEN];
1671: MPI_Comm ncomm;
1674: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1675: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1676: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL);
1677: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1678: }
1679: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1680: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1681: if (!flg) { /* PetscViewer not yet created */
1682: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1683: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1684: if (!flg) {
1685: PetscStrcpy(fname,"binaryoutput");
1686: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1687: }
1688: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1689: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1690: PetscObjectRegisterDestroy((PetscObject)viewer);
1691: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1692: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1693: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1694: }
1695: PetscCommDestroy(&ncomm);
1696: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1697: PetscFunctionReturn(viewer);
1698: }