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;
29: if (vbinary->filemode == FILE_MODE_READ) return 0;
30: if (vbinary->mfsub != MPI_FILE_NULL) {
31: MPI_File_sync(vbinary->mfsub);
32: }
33: if (vbinary->mfdes != MPI_FILE_NULL) {
34: MPI_Barrier(PetscObjectComm((PetscObject)viewer));
35: MPI_File_sync(vbinary->mfdes);
36: }
37: return 0;
38: }
39: #endif
41: static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
42: {
43: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
44: PetscMPIInt rank;
46: PetscViewerSetUp(viewer);
48: /* Return subviewer in process zero */
49: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
50: if (rank == 0) {
51: PetscMPIInt flg;
53: MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
55: PetscViewerCreate(comm,outviewer);
56: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
57: PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));
58: (*outviewer)->setupcalled = PETSC_TRUE;
59: } else {
60: *outviewer = NULL;
61: }
63: #if defined(PETSC_HAVE_MPIIO)
64: if (vbinary->usempiio && *outviewer) {
65: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
66: /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */
67: if (vbinary->mfsub == MPI_FILE_NULL) {
68: int amode;
69: switch (vbinary->filemode) {
70: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
71: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY; break;
72: case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY; break;
73: default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
74: }
75: MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);
76: }
77: /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */
78: obinary->mfdes = vbinary->mfsub;
79: obinary->mfsub = MPI_FILE_NULL;
80: obinary->moff = vbinary->moff;
81: }
82: #endif
84: #if defined(PETSC_HAVE_MPIIO)
85: PetscViewerBinarySyncMPIIO(viewer);
86: #endif
87: return 0;
88: }
90: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
91: {
92: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
93: PetscMPIInt rank;
94: #if defined(PETSC_HAVE_MPIIO)
95: MPI_Offset moff = 0;
96: #endif
98: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
101: #if defined(PETSC_HAVE_MPIIO)
102: if (vbinary->usempiio && *outviewer) {
103: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
105: if (obinary->mfsub != MPI_FILE_NULL) MPI_File_close(&obinary->mfsub);
106: moff = obinary->moff;
107: }
108: #endif
110: if (*outviewer) {
111: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
113: PetscFree((*outviewer)->data);
114: PetscHeaderDestroy(outviewer);
115: }
117: #if defined(PETSC_HAVE_MPIIO)
118: if (vbinary->usempiio) {
119: PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */
120: MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));
121: vbinary->moff = (MPI_Offset)ioff;
122: }
123: #endif
125: #if defined(PETSC_HAVE_MPIIO)
126: PetscViewerBinarySyncMPIIO(viewer);
127: #endif
128: return 0;
129: }
131: #if defined(PETSC_HAVE_MPIIO)
132: /*@C
133: PetscViewerBinaryGetMPIIOOffset - Gets the current global offset that should be passed to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()
135: Not Collective
137: Input Parameter:
138: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
140: Output Parameter:
141: . off - the current global offset
143: Level: advanced
145: Fortran Note:
146: This routine is not supported in Fortran.
148: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
150: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
151: @*/
152: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
153: {
154: PetscViewer_Binary *vbinary;
158: vbinary = (PetscViewer_Binary*)viewer->data;
159: *off = vbinary->moff;
160: return 0;
161: }
163: /*@C
164: PetscViewerBinaryAddMPIIOOffset - Adds to the current global offset
166: Logically Collective
168: Input Parameters:
169: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
170: - off - the addition to the global offset
172: Level: advanced
174: Fortran Note:
175: This routine is not supported in Fortran.
177: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()
179: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
180: @*/
181: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
182: {
183: PetscViewer_Binary *vbinary;
187: vbinary = (PetscViewer_Binary*)viewer->data;
188: vbinary->moff += off;
189: return 0;
190: }
192: /*@C
193: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
195: Not Collective
197: Input Parameter:
198: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
200: Output Parameter:
201: . fdes - file descriptor
203: Level: advanced
205: Fortran Note:
206: This routine is not supported in Fortran.
208: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
209: @*/
210: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
211: {
212: PetscViewer_Binary *vbinary;
216: PetscViewerSetUp(viewer);
217: vbinary = (PetscViewer_Binary*)viewer->data;
218: *fdes = vbinary->mfdes;
219: return 0;
220: }
221: #endif
223: /*@
224: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
225: before PetscViewerFileSetName()
227: Logically Collective on PetscViewer
229: Input Parameters:
230: + viewer - the PetscViewer; must be a binary
231: - use - PETSC_TRUE means MPI-IO will be used
233: Options Database:
234: -viewer_binary_mpiio : Flag for using MPI-IO
236: Level: advanced
238: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
239: PetscViewerBinaryGetUseMPIIO()
241: @*/
242: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool use)
243: {
246: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,use));
247: return 0;
248: }
250: #if defined(PETSC_HAVE_MPIIO)
251: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool use)
252: {
253: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
255: vbinary->usempiio = use;
256: return 0;
257: }
258: #endif
260: /*@
261: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
263: Not Collective
265: Input Parameter:
266: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
268: Output Parameter:
269: . use - PETSC_TRUE if MPI-IO is being used
271: Options Database:
272: -viewer_binary_mpiio : Flag for using MPI-IO
274: Level: advanced
276: Note:
277: If MPI-IO is not available, this function will always return PETSC_FALSE
279: Fortran Note:
280: This routine is not supported in Fortran.
282: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
283: @*/
284: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *use)
285: {
288: *use = PETSC_FALSE;
289: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,use));
290: return 0;
291: }
293: #if defined(PETSC_HAVE_MPIIO)
294: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *use)
295: {
296: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
298: *use = vbinary->usempiio;
299: return 0;
300: }
301: #endif
303: /*@
304: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
306: Not Collective
308: Input Parameters:
309: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
310: - fc - the number of messages, defaults to 256 if this function was not called
312: Level: advanced
314: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
316: @*/
317: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
318: {
321: PetscTryMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
322: return 0;
323: }
325: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
326: {
327: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
330: vbinary->flowcontrol = fc;
331: return 0;
332: }
334: /*@
335: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
337: Not Collective
339: Input Parameter:
340: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
342: Output Parameter:
343: . fc - the number of messages
345: Level: advanced
347: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
349: @*/
350: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
351: {
354: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
355: return 0;
356: }
358: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
359: {
360: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
362: *fc = vbinary->flowcontrol;
363: return 0;
364: }
366: /*@C
367: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
369: Collective On PetscViewer
371: Input Parameter:
372: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
374: Output Parameter:
375: . fdes - file descriptor
377: Level: advanced
379: Notes:
380: For writable binary PetscViewers, the descriptor will only be valid for the
381: first processor in the communicator that shares the PetscViewer. For readable
382: files it will only be valid on nodes that have the file. If node 0 does not
383: have the file it generates an error even if another node does have the file.
385: Fortran Note:
386: This routine is not supported in Fortran.
388: Developer Notes:
389: This must be called on all processes because Dave May changed
390: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
392: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
393: @*/
394: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
395: {
396: PetscViewer_Binary *vbinary;
400: PetscViewerSetUp(viewer);
401: vbinary = (PetscViewer_Binary*)viewer->data;
402: *fdes = vbinary->fdes;
403: return 0;
404: }
406: /*@
407: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
409: Not Collective
411: Input Parameter:
412: . viewer - PetscViewer context, obtained from PetscViewerCreate()
414: Options Database Key:
415: . -viewer_binary_skip_info - true indicates do not generate .info file
417: Level: advanced
419: Notes:
420: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
421: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
422: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
424: The .info contains meta information about the data in the binary file, for example the block size if it was
425: set for a vector or matrix.
427: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
428: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
429: @*/
430: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
431: {
432: PetscViewerBinarySetSkipInfo(viewer,PETSC_TRUE);
433: return 0;
434: }
436: /*@
437: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
439: Not Collective
441: Input Parameters:
442: + viewer - PetscViewer context, obtained from PetscViewerCreate()
443: - skip - PETSC_TRUE implies the .info file will not be generated
445: Options Database Key:
446: . -viewer_binary_skip_info - true indicates do not generate .info file
448: Level: advanced
450: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
451: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
452: @*/
453: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
454: {
457: PetscTryMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
458: return 0;
459: }
461: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
462: {
463: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
465: vbinary->skipinfo = skip;
466: return 0;
467: }
469: /*@
470: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
472: Not Collective
474: Input Parameter:
475: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
477: Output Parameter:
478: . skip - PETSC_TRUE implies the .info file was not generated
480: Level: advanced
482: Notes:
483: This must be called after PetscViewerSetType()
485: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
486: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
487: @*/
488: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
489: {
492: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
493: return 0;
494: }
496: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
497: {
498: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
500: *skip = vbinary->skipinfo;
501: return 0;
502: }
504: /*@
505: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
507: Not Collective
509: Input Parameters:
510: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
511: - skip - PETSC_TRUE means do not use the options from the options database
513: Options Database Key:
514: . -viewer_binary_skip_options - true means do not use the options from the options database
516: Level: advanced
518: Notes:
519: This must be called after PetscViewerSetType()
521: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
522: PetscViewerBinaryGetSkipOptions()
523: @*/
524: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
525: {
528: PetscTryMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
529: return 0;
530: }
532: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
533: {
534: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
536: vbinary->skipoptions = skip;
537: return 0;
538: }
540: /*@
541: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
543: Not Collective
545: Input Parameter:
546: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
548: Output Parameter:
549: . skip - PETSC_TRUE means do not use
551: Level: advanced
553: Notes:
554: This must be called after PetscViewerSetType()
556: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
557: PetscViewerBinarySetSkipOptions()
558: @*/
559: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
560: {
563: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
564: return 0;
565: }
567: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
568: {
569: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
571: *skip = vbinary->skipoptions;
572: return 0;
573: }
575: /*@
576: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
578: Not Collective
580: Input Parameters:
581: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
582: - skip - PETSC_TRUE means do not write header
584: Options Database Key:
585: . -viewer_binary_skip_header - PETSC_TRUE means do not write header
587: Level: advanced
589: Notes:
590: This must be called after PetscViewerSetType()
592: Is ignored on anything but a binary viewer
594: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
595: PetscViewerBinaryGetSkipHeader()
596: @*/
597: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
598: {
601: PetscTryMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
602: return 0;
603: }
605: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
606: {
607: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
609: vbinary->skipheader = skip;
610: return 0;
611: }
613: /*@
614: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
616: Not Collective
618: Input Parameter:
619: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
621: Output Parameter:
622: . skip - PETSC_TRUE means do not write header
624: Level: advanced
626: Notes:
627: This must be called after PetscViewerSetType()
629: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
631: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
632: PetscViewerBinarySetSkipHeader()
633: @*/
634: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
635: {
638: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
639: return 0;
640: }
642: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
643: {
644: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
646: *skip = vbinary->skipheader;
647: return 0;
648: }
650: /*@C
651: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
652: info file associated with a binary file.
654: Not Collective
656: Input Parameter:
657: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
659: Output Parameter:
660: . file - file pointer Always returns NULL if not a binary viewer
662: Level: advanced
664: Notes:
665: For writable binary PetscViewers, the descriptor will only be valid for the
666: first processor in the communicator that shares the PetscViewer.
668: Fortran Note:
669: This routine is not supported in Fortran.
671: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
672: @*/
673: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
674: {
677: *file = NULL;
678: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
679: return 0;
680: }
682: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
683: {
684: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
686: PetscViewerSetUp(viewer);
687: *file = vbinary->fdes_info;
688: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
689: if (vbinary->fdes_info) {
690: FILE *info = vbinary->fdes_info;
691: PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
692: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ Set.filename = '%s';\n",vbinary->filename);
693: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ fd = PetscOpenFile(Set.filename);\n");
694: PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
695: }
696: vbinary->matlabheaderwritten = PETSC_TRUE;
697: }
698: return 0;
699: }
701: #if defined(PETSC_HAVE_MPIIO)
702: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
703: {
704: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
706: if (vbinary->mfdes != MPI_FILE_NULL) {
707: MPI_File_close(&vbinary->mfdes);
708: }
709: if (vbinary->mfsub != MPI_FILE_NULL) {
710: MPI_File_close(&vbinary->mfsub);
711: }
712: vbinary->moff = 0;
713: return 0;
714: }
715: #endif
717: static PetscErrorCode PetscViewerFileClose_BinarySTDIO(PetscViewer v)
718: {
719: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
721: if (vbinary->fdes != -1) {
722: PetscBinaryClose(vbinary->fdes);
723: vbinary->fdes = -1;
724: if (vbinary->storecompressed) {
725: char cmd[8+PETSC_MAX_PATH_LEN],out[64+PETSC_MAX_PATH_LEN] = "";
726: const char *gzfilename = vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename;
727: /* compress the file */
728: PetscStrncpy(cmd,"gzip -f ",sizeof(cmd));
729: PetscStrlcat(cmd,gzfilename,sizeof(cmd));
730: #if defined(PETSC_HAVE_POPEN)
731: {
732: FILE *fp;
733: PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);
735: PetscPClose(PETSC_COMM_SELF,fp);
736: }
737: #endif
738: }
739: }
740: PetscFree(vbinary->ogzfilename);
741: return 0;
742: }
744: static PetscErrorCode PetscViewerFileClose_BinaryInfo(PetscViewer v)
745: {
746: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
748: if (v->format == PETSC_VIEWER_BINARY_MATLAB && vbinary->matlabheaderwritten) {
749: if (vbinary->fdes_info) {
750: FILE *info = vbinary->fdes_info;
751: PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
752: PetscFPrintf(PETSC_COMM_SELF,info,"#$$ close(fd);\n");
753: PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
754: }
755: }
756: if (vbinary->fdes_info) {
757: FILE *info = vbinary->fdes_info;
758: vbinary->fdes_info = NULL;
760: }
761: return 0;
762: }
764: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
765: {
766: #if defined(PETSC_HAVE_MPIIO)
767: PetscViewerFileClose_BinaryMPIIO(v);
768: #endif
769: PetscViewerFileClose_BinarySTDIO(v);
770: PetscViewerFileClose_BinaryInfo(v);
771: return 0;
772: }
774: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
775: {
776: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
778: PetscViewerFileClose_Binary(v);
779: PetscFree(vbinary->filename);
780: PetscFree(vbinary);
782: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",NULL);
783: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",NULL);
784: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",NULL);
785: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",NULL);
786: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",NULL);
787: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",NULL);
788: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",NULL);
789: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",NULL);
790: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",NULL);
791: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",NULL);
792: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",NULL);
793: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",NULL);
794: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",NULL);
795: #if defined(PETSC_HAVE_MPIIO)
796: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",NULL);
797: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",NULL);
798: #endif
799: return 0;
800: }
802: /*@C
803: PetscViewerBinaryOpen - Opens a file for binary input/output.
805: Collective
807: Input Parameters:
808: + comm - MPI communicator
809: . name - name of file
810: - mode - open mode of file
811: $ FILE_MODE_WRITE - create new file for binary output
812: $ FILE_MODE_READ - open existing file for binary input
813: $ FILE_MODE_APPEND - open existing file for binary output
815: Output Parameter:
816: . viewer - PetscViewer for binary input/output to use with the specified file
818: Options Database Keys:
819: + -viewer_binary_filename <name> -
820: . -viewer_binary_skip_info -
821: . -viewer_binary_skip_options -
822: . -viewer_binary_skip_header -
823: - -viewer_binary_mpiio -
825: Level: beginner
827: Note:
828: This PetscViewer should be destroyed with PetscViewerDestroy().
830: For reading files, the filename may begin with ftp:// or http:// and/or
831: end with .gz; in this case file is brought over and uncompressed.
833: For creating files, if the file name ends with .gz it is automatically
834: compressed when closed.
836: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
837: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
838: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
839: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
840: @*/
841: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode mode,PetscViewer *viewer)
842: {
843: PetscViewerCreate(comm,viewer);
844: PetscViewerSetType(*viewer,PETSCVIEWERBINARY);
845: PetscViewerFileSetMode(*viewer,mode);
846: PetscViewerFileSetName(*viewer,name);
847: PetscViewerSetFromOptions(*viewer);
848: return 0;
849: }
851: #if defined(PETSC_HAVE_MPIIO)
852: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
853: {
854: MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
855: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
856: MPI_File mfdes = vbinary->mfdes;
857: MPI_Datatype mdtype;
858: PetscMPIInt rank,cnt;
859: MPI_Status status;
860: MPI_Aint ul,dsize;
862: MPI_Comm_rank(comm,&rank);
863: PetscMPIIntCast(num,&cnt);
864: PetscDataTypeToMPIDataType(dtype,&mdtype);
865: if (write) {
866: if (rank == 0) {
867: MPIU_File_write_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
868: }
869: } else {
870: if (rank == 0) {
871: MPIU_File_read_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);
872: if (cnt > 0) MPI_Get_count(&status,mdtype,&cnt);
873: }
874: MPI_Bcast(&cnt,1,MPI_INT,0,comm);
875: MPI_Bcast(data,cnt,mdtype,0,comm);
876: }
877: MPI_Type_get_extent(mdtype,&ul,&dsize);
878: vbinary->moff += dsize*cnt;
879: if (count) *count = cnt;
880: return 0;
881: }
882: #endif
884: /*@C
885: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
887: Collective
889: Input Parameters:
890: + viewer - the binary viewer
891: . data - location of the data to be written
892: . num - number of items of data to read
893: - dtype - type of data to read
895: Output Parameters:
896: . count - number of items of data actually read, or NULL.
898: Level: beginner
900: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
901: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
902: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
903: @*/
904: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
905: {
906: PetscViewer_Binary *vbinary;
910: PetscViewerSetUp(viewer);
911: vbinary = (PetscViewer_Binary*)viewer->data;
912: #if defined(PETSC_HAVE_MPIIO)
913: if (vbinary->usempiio) {
914: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
915: } else {
916: #endif
917: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);
918: #if defined(PETSC_HAVE_MPIIO)
919: }
920: #endif
921: return 0;
922: }
924: /*@C
925: PetscViewerBinaryWrite - writes to a binary file, only from the first process
927: Collective
929: Input Parameters:
930: + viewer - the binary viewer
931: . data - location of data
932: . count - number of items of data to write
933: - dtype - type of data to write
935: Level: beginner
937: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
938: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
939: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
940: @*/
941: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,const void *data,PetscInt count,PetscDataType dtype)
942: {
943: PetscViewer_Binary *vbinary;
947: PetscViewerSetUp(viewer);
948: vbinary = (PetscViewer_Binary*)viewer->data;
949: #if defined(PETSC_HAVE_MPIIO)
950: if (vbinary->usempiio) {
951: PetscViewerBinaryWriteReadMPIIO(viewer,(void*)data,count,NULL,dtype,PETSC_TRUE);
952: } else {
953: #endif
954: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);
955: #if defined(PETSC_HAVE_MPIIO)
956: }
957: #endif
958: return 0;
959: }
961: static PetscErrorCode PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
962: {
963: MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
964: PetscMPIInt size,rank;
965: MPI_Datatype mdtype;
966: PETSC_UNUSED MPI_Aint lb;
967: MPI_Aint dsize;
968: PetscBool useMPIIO;
974: PetscViewerSetUp(viewer);
976: PetscDataTypeToMPIDataType(dtype,&mdtype);
977: MPI_Type_get_extent(mdtype,&lb,&dsize);
978: MPI_Comm_rank(comm,&rank);
979: MPI_Comm_size(comm,&size);
981: PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);
982: #if defined(PETSC_HAVE_MPIIO)
983: if (useMPIIO) {
984: MPI_File mfdes;
985: MPI_Offset off;
986: PetscMPIInt cnt;
988: if (start == PETSC_DETERMINE) {
989: MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);
990: start -= count;
991: }
992: if (total == PETSC_DETERMINE) {
993: total = start + count;
994: MPI_Bcast(&total,1,MPIU_INT,size-1,comm);
995: }
996: PetscMPIIntCast(count,&cnt);
997: PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);
998: PetscViewerBinaryGetMPIIOOffset(viewer,&off);
999: off += (MPI_Offset)(start*dsize);
1000: if (write) {
1001: MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1002: } else {
1003: MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);
1004: }
1005: off = (MPI_Offset)(total*dsize);
1006: PetscViewerBinaryAddMPIIOOffset(viewer,off);
1007: return 0;
1008: }
1009: #endif
1010: {
1011: int fdes;
1012: char *workbuf = NULL;
1013: PetscInt tcount = rank == 0 ? 0 : count,maxcount=0,message_count,flowcontrolcount;
1014: PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j;
1015: MPI_Status status;
1017: PetscCommGetNewTag(comm,&tag);
1018: MPI_Reduce(&tcount,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);
1019: PetscMPIIntCast(maxcount,&maxcnt);
1020: PetscMPIIntCast(count,&cnt);
1022: PetscViewerBinaryGetDescriptor(viewer,&fdes);
1023: PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);
1024: if (rank == 0) {
1025: PetscMalloc(maxcnt*dsize,&workbuf);
1026: if (write) {
1027: PetscBinaryWrite(fdes,data,cnt,dtype);
1028: } else {
1029: PetscBinaryRead(fdes,data,cnt,NULL,dtype);
1030: }
1031: for (j=1; j<size; j++) {
1032: PetscViewerFlowControlStepMain(viewer,j,&message_count,flowcontrolcount);
1033: if (write) {
1034: MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);
1035: MPI_Get_count(&status,mdtype,&rcnt);
1036: PetscBinaryWrite(fdes,workbuf,rcnt,dtype);
1037: } else {
1038: MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);
1039: PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);
1040: MPI_Send(workbuf,scnt,mdtype,j,tag,comm);
1041: }
1042: }
1043: PetscFree(workbuf);
1044: PetscViewerFlowControlEndMain(viewer,&message_count);
1045: } else {
1046: PetscViewerFlowControlStepWorker(viewer,rank,&message_count);
1047: if (write) {
1048: MPI_Send(data,cnt,mdtype,0,tag,comm);
1049: } else {
1050: MPI_Send(&cnt,1,MPI_INT,0,tag,comm);
1051: MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);
1052: }
1053: PetscViewerFlowControlEndWorker(viewer,&message_count);
1054: }
1055: }
1056: return 0;
1057: }
1059: /*@C
1060: PetscViewerBinaryReadAll - reads from a binary file from all processes
1062: Collective
1064: Input Parameters:
1065: + viewer - the binary viewer
1066: . data - location of data
1067: . count - local number of items of data to read
1068: . start - local start, can be PETSC_DETERMINE
1069: . total - global number of items of data to read, can be PETSC_DETERMINE
1070: - dtype - type of data to read
1072: Level: advanced
1074: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll()
1075: @*/
1076: PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1077: {
1078: PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);
1079: return 0;
1080: }
1082: /*@C
1083: PetscViewerBinaryWriteAll - writes to a binary file from all processes
1085: Collective
1087: Input Parameters:
1088: + viewer - the binary viewer
1089: . data - location of data
1090: . count - local number of items of data to write
1091: . start - local start, can be PETSC_DETERMINE
1092: . total - global number of items of data to write, can be PETSC_DETERMINE
1093: - dtype - type of data to write
1095: Level: advanced
1097: .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll()
1098: @*/
1099: PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1100: {
1101: PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);
1102: return 0;
1103: }
1105: /*@C
1106: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
1108: Collective
1110: Input Parameters:
1111: + viewer - the binary viewer
1112: - data - location of the array of strings
1114: Level: intermediate
1116: Notes:
1117: array of strings is null terminated
1119: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1120: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1121: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1122: @*/
1123: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
1124: {
1125: PetscInt i,n = 0,*sizes;
1126: size_t len;
1128: PetscViewerSetUp(viewer);
1129: /* count number of strings */
1130: while (data[n++]);
1131: n--;
1132: PetscMalloc1(n+1,&sizes);
1133: sizes[0] = n;
1134: for (i=0; i<n; i++) {
1135: PetscStrlen(data[i],&len);
1136: sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */
1137: }
1138: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);
1139: for (i=0; i<n; i++) {
1140: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);
1141: }
1142: PetscFree(sizes);
1143: return 0;
1144: }
1146: /*@C
1147: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1149: Collective
1151: Input Parameter:
1152: . viewer - the binary viewer
1154: Output Parameter:
1155: . data - location of the array of strings
1157: Level: intermediate
1159: Notes:
1160: array of strings is null terminated
1162: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1163: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1164: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1165: @*/
1166: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1167: {
1168: PetscInt i,n,*sizes,N = 0;
1170: PetscViewerSetUp(viewer);
1171: /* count number of strings */
1172: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1173: PetscMalloc1(n,&sizes);
1174: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1175: for (i=0; i<n; i++) N += sizes[i];
1176: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1177: (*data)[0] = (char*)((*data) + n + 1);
1178: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1179: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1180: (*data)[n] = NULL;
1181: PetscFree(sizes);
1182: return 0;
1183: }
1185: /*@C
1186: PetscViewerFileSetMode - Sets the open mode of file
1188: Logically Collective on PetscViewer
1190: Input Parameters:
1191: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1192: - mode - open mode of file
1193: $ FILE_MODE_WRITE - create new file for output
1194: $ FILE_MODE_READ - open existing file for input
1195: $ FILE_MODE_APPEND - open existing file for output
1197: Level: advanced
1199: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1201: @*/
1202: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)
1203: {
1208: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));
1209: return 0;
1210: }
1212: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)
1213: {
1214: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1217: vbinary->filemode = mode;
1218: return 0;
1219: }
1221: /*@C
1222: PetscViewerFileGetMode - Gets the open mode of file
1224: Not Collective
1226: Input Parameter:
1227: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1229: Output Parameter:
1230: . mode - open mode of file
1231: $ FILE_MODE_WRITE - create new file for binary output
1232: $ FILE_MODE_READ - open existing file for binary input
1233: $ FILE_MODE_APPEND - open existing file for binary output
1235: Level: advanced
1237: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1239: @*/
1240: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode)
1241: {
1244: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));
1245: return 0;
1246: }
1248: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode)
1249: {
1250: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1252: *mode = vbinary->filemode;
1253: return 0;
1254: }
1256: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1257: {
1258: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1260: if (viewer->setupcalled && vbinary->filename) {
1261: /* gzip can be run after the file with the previous filename has been closed */
1262: PetscFree(vbinary->ogzfilename);
1263: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1264: }
1265: PetscFree(vbinary->filename);
1266: PetscStrallocpy(name,&vbinary->filename);
1267: viewer->setupcalled = PETSC_FALSE;
1268: return 0;
1269: }
1271: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1272: {
1273: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1275: *name = vbinary->filename;
1276: return 0;
1277: }
1279: #if defined(PETSC_HAVE_MPIIO)
1280: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1281: {
1282: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1283: int amode;
1285: vbinary->storecompressed = PETSC_FALSE;
1287: vbinary->moff = 0;
1288: switch (vbinary->filemode) {
1289: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1290: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1291: case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break;
1292: case FILE_MODE_UNDEFINED: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerSetUp()");
1293: default: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
1294: }
1295: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1296: /*
1297: The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero.
1298: */
1299: if (vbinary->filemode == FILE_MODE_WRITE) MPI_File_set_size(vbinary->mfdes,0);
1300: /*
1301: Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND,
1302: MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file.
1303: Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert
1304: the offset in etype units to an absolute byte position.
1305: */
1306: if (vbinary->filemode == FILE_MODE_APPEND) MPI_File_get_position(vbinary->mfdes,&vbinary->moff);
1307: return 0;
1308: }
1309: #endif
1311: static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)
1312: {
1313: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1314: const char *fname;
1315: char bname[PETSC_MAX_PATH_LEN],*gz;
1316: PetscBool found;
1317: PetscMPIInt rank;
1319: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1321: /* if file name ends in .gz strip that off and note user wants file compressed */
1322: vbinary->storecompressed = PETSC_FALSE;
1323: if (vbinary->filemode == FILE_MODE_WRITE) {
1324: PetscStrstr(vbinary->filename,".gz",&gz);
1325: if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;}
1326: }
1327: #if !defined(PETSC_HAVE_POPEN)
1329: #endif
1331: fname = vbinary->filename;
1332: if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */
1333: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);
1335: fname = bname;
1336: }
1338: vbinary->fdes = -1;
1339: if (rank == 0) { /* only first processor opens file*/
1340: PetscFileMode mode = vbinary->filemode;
1341: if (mode == FILE_MODE_APPEND) {
1342: /* check if asked to append to a non-existing file */
1343: PetscTestFile(fname,'\0',&found);
1344: if (!found) mode = FILE_MODE_WRITE;
1345: }
1346: PetscBinaryOpen(fname,mode,&vbinary->fdes);
1347: }
1348: return 0;
1349: }
1351: static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)
1352: {
1353: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1354: PetscMPIInt rank;
1355: PetscBool found;
1357: vbinary->fdes_info = NULL;
1358: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1359: if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || rank == 0)) {
1360: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz;
1362: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1363: /* remove .gz if it ends file name */
1364: PetscStrstr(infoname,".gz",&gz);
1365: if (gz && gz[3] == 0) *gz = 0;
1367: PetscStrlcat(infoname,".info",sizeof(infoname));
1368: if (vbinary->filemode == FILE_MODE_READ) {
1369: PetscFixFilename(infoname,iname);
1370: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1371: if (found) PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1372: } else if (rank == 0) { /* write or append */
1373: const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w";
1374: vbinary->fdes_info = fopen(infoname,omode);
1376: }
1377: }
1378: return 0;
1379: }
1381: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer)
1382: {
1383: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1384: PetscBool usempiio;
1386: if (!vbinary->setfromoptionscalled) PetscViewerSetFromOptions(viewer);
1389: PetscViewerFileClose_Binary(viewer);
1391: PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);
1392: if (usempiio) {
1393: #if defined(PETSC_HAVE_MPIIO)
1394: PetscViewerFileSetUp_BinaryMPIIO(viewer);
1395: #endif
1396: } else {
1397: PetscViewerFileSetUp_BinarySTDIO(viewer);
1398: }
1399: PetscViewerFileSetUp_BinaryInfo(viewer);
1401: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1402: return 0;
1403: }
1405: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1406: {
1407: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
1408: const char *fname = vbinary->filename ? vbinary->filename : "not yet set";
1409: const char *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set";
1410: PetscBool usempiio;
1412: PetscViewerBinaryGetUseMPIIO(v,&usempiio);
1413: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);
1414: PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");
1415: return 0;
1416: }
1418: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer)
1419: {
1420: PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data;
1421: char defaultname[PETSC_MAX_PATH_LEN];
1422: PetscBool flg;
1424: if (viewer->setupcalled) return 0;
1425: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1426: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1427: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,sizeof(defaultname),&flg);
1428: if (flg) PetscViewerFileSetName_Binary(viewer,defaultname);
1429: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);
1430: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);
1431: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);
1432: #if defined(PETSC_HAVE_MPIIO)
1433: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);
1434: #else
1435: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1436: #endif
1437: PetscOptionsTail();
1438: binary->setfromoptionscalled = PETSC_TRUE;
1439: return 0;
1440: }
1442: /*MC
1443: PETSCVIEWERBINARY - A viewer that saves to binary files
1445: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1446: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1447: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1448: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1450: Level: beginner
1452: M*/
1454: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1455: {
1456: PetscViewer_Binary *vbinary;
1458: PetscNewLog(v,&vbinary);
1459: v->data = (void*)vbinary;
1461: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1462: v->ops->destroy = PetscViewerDestroy_Binary;
1463: v->ops->view = PetscViewerView_Binary;
1464: v->ops->setup = PetscViewerSetUp_Binary;
1465: v->ops->flush = NULL; /* Should we support Flush() ? */
1466: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1467: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1468: v->ops->read = PetscViewerBinaryRead;
1470: vbinary->fdes = -1;
1471: #if defined(PETSC_HAVE_MPIIO)
1472: vbinary->usempiio = PETSC_FALSE;
1473: vbinary->mfdes = MPI_FILE_NULL;
1474: vbinary->mfsub = MPI_FILE_NULL;
1475: #endif
1476: vbinary->filename = NULL;
1477: vbinary->filemode = FILE_MODE_UNDEFINED;
1478: vbinary->fdes_info = NULL;
1479: vbinary->skipinfo = PETSC_FALSE;
1480: vbinary->skipoptions = PETSC_TRUE;
1481: vbinary->skipheader = PETSC_FALSE;
1482: vbinary->storecompressed = PETSC_FALSE;
1483: vbinary->ogzfilename = NULL;
1484: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1486: vbinary->setfromoptionscalled = PETSC_FALSE;
1488: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1489: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1490: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1491: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1492: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1493: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1494: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1495: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1496: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1497: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1498: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1499: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1500: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1501: #if defined(PETSC_HAVE_MPIIO)
1502: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1503: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1504: #endif
1505: return 0;
1506: }
1508: /* ---------------------------------------------------------------------*/
1509: /*
1510: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1511: is attached to a communicator, in this case the attribute is a PetscViewer.
1512: */
1513: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1515: /*@C
1516: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1517: in a communicator.
1519: Collective
1521: Input Parameter:
1522: . comm - the MPI communicator to share the binary PetscViewer
1524: Level: intermediate
1526: Options Database Keys:
1527: + -viewer_binary_filename <name> - filename in which to store the binary data, defaults to binaryoutput
1528: . -viewer_binary_skip_info - true means do not create .info file for this viewer
1529: . -viewer_binary_skip_options - true means do not use the options database for this viewer
1530: . -viewer_binary_skip_header - true means do not store the usual header information in the binary file
1531: - -viewer_binary_mpiio - true means use the file via MPI-IO, maybe faster for large files and many MPI ranks
1533: Environmental variables:
1534: - PETSC_VIEWER_BINARY_FILENAME - filename in which to store the binary data, defaults to binaryoutput
1536: Notes:
1537: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1538: an error code. The binary PetscViewer is usually used in the form
1539: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1541: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1542: PetscViewerDestroy()
1543: @*/
1544: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1545: {
1547: PetscBool flg;
1548: PetscViewer viewer;
1549: char fname[PETSC_MAX_PATH_LEN];
1550: MPI_Comm ncomm;
1552: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
1553: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1554: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL);
1555: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
1556: }
1557: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1558: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
1559: if (!flg) { /* PetscViewer not yet created */
1560: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1561: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
1562: if (!flg) {
1563: PetscStrcpy(fname,"binaryoutput");
1564: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
1565: }
1566: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1567: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
1568: PetscObjectRegisterDestroy((PetscObject)viewer);
1569: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
1570: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1571: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return NULL;}
1572: }
1573: PetscCommDestroy(&ncomm);
1574: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");return NULL;}
1575: return viewer;
1576: }