Actual source code: binv.c
petsc-3.11.4 2019-09-28
2: #include <petsc/private/viewerimpl.h>
3: #include <fcntl.h>
4: #if defined(PETSC_HAVE_UNISTD_H)
5: #include <unistd.h>
6: #endif
7: #if defined(PETSC_HAVE_IO_H)
8: #include <io.h>
9: #endif
11: typedef struct {
12: int fdes; /* file descriptor, ignored if using MPI IO */
13: #if defined(PETSC_HAVE_MPIIO)
14: PetscBool usempiio;
15: MPI_File mfdes; /* ignored unless using MPI IO */
16: MPI_File mfsub; /* subviewer support */
17: MPI_Offset moff;
18: #endif
19: PetscFileMode btype; /* read or write? */
20: FILE *fdes_info; /* optional file containing info on binary file*/
21: PetscBool storecompressed; /* gzip the write binary file when closing it*/
22: char *filename;
23: char *ogzfilename; /* gzip can be run after the filename has been updated */
24: PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */
25: PetscBool skipoptions; /* don't use PETSc options database when loading */
26: PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
27: PetscBool skipheader; /* don't write header, only raw data */
28: PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
29: PetscBool setfromoptionscalled;
30: } PetscViewer_Binary;
32: static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
33: {
34: int rank;
35: PetscErrorCode ierr;
36: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
39: PetscViewerSetUp(viewer);
41: /* Return subviewer in process zero */
42: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
43: if (!rank) {
44: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
45: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
46: PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));
47: (*outviewer)->setupcalled = PETSC_TRUE;
48: } else {
49: *outviewer = NULL;
50: }
52: #if defined(PETSC_HAVE_MPIIO)
53: if (vbinary->usempiio && *outviewer) {
54: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
55: /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */
56: if (vbinary->mfsub == MPI_FILE_NULL) {
57: int amode;
58: switch (vbinary->btype) {
59: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
60: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY; break;
61: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->btype]);
62: }
63: MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);
64: }
65: /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */
66: obinary->mfdes = vbinary->mfsub;
67: obinary->mfsub = MPI_FILE_NULL;
68: obinary->moff = vbinary->moff;
69: }
70: #endif
71: return(0);
72: }
74: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
75: {
76: PetscErrorCode rank;
77: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
78: PetscErrorCode ierr;
79: #if defined(PETSC_HAVE_MPIIO)
80: MPI_Offset moff = 0;
81: #endif
84: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
85: if (rank && *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
87: #if defined(PETSC_HAVE_MPIIO)
88: if (vbinary->usempiio && *outviewer) {
89: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
90: if (obinary->mfdes != vbinary->mfsub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
91: moff = obinary->moff;
92: }
93: #endif
95: if (*outviewer) {
96: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
97: if (obinary->fdes != vbinary->fdes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
98: PetscFree((*outviewer)->data);
99: PetscHeaderDestroy(outviewer);
100: }
102: #if defined(PETSC_HAVE_MPIIO)
103: if (vbinary->usempiio) {
104: PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */
105: MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));
106: vbinary->moff = (MPI_Offset)ioff;
107: }
108: #endif
109: return(0);
110: }
112: #if defined(PETSC_HAVE_MPIIO)
113: /*@C
114: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
116: Not Collective
118: Input Parameter:
119: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
121: Output Parameter:
122: . off - the current offset
124: Level: advanced
126: Fortran Note:
127: This routine is not supported in Fortran.
129: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
131: Concepts: file descriptor^getting
132: Concepts: PetscViewerBinary^accessing file descriptor
134: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
135: @*/
136: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
137: {
138: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
141: *off = vbinary->moff;
142: return(0);
143: }
145: /*@C
146: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
148: Not Collective
150: Input Parameters:
151: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
152: - off - the addition to the offset
154: Level: advanced
156: Fortran Note:
157: This routine is not supported in Fortran.
159: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
161: Concepts: file descriptor^getting
162: Concepts: PetscViewerBinary^accessing file descriptor
164: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
165: @*/
166: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
167: {
168: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
171: vbinary->moff += off;
172: return(0);
173: }
175: /*@C
176: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
178: Not Collective
180: Input Parameter:
181: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
183: Output Parameter:
184: . fdes - file descriptor
186: Level: advanced
188: Fortran Note:
189: This routine is not supported in Fortran.
191: Concepts: file descriptor^getting
192: Concepts: PetscViewerBinary^accessing file descriptor
194: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
195: @*/
196: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
197: {
198: PetscErrorCode ierr;
199: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
202: PetscViewerSetUp(viewer);
203: *fdes = vbinary->mfdes;
204: return(0);
205: }
207: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg)
208: {
209: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
212: *flg = vbinary->usempiio;
213: return(0);
214: }
215: #endif
218: /*@C
219: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
221: Not Collective
223: Input Parameter:
224: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
226: Output Parameter:
227: - flg - PETSC_TRUE if MPI-IO is being used
229: Options Database:
230: -viewer_binary_mpiio : Flag for using MPI-IO
232: Level: advanced
234: Note:
235: If MPI-IO is not available, this function will always return PETSC_FALSE
237: Fortran Note:
238: This routine is not supported in Fortran.
240: Concepts: file descriptor^getting
241: Concepts: PetscViewerBinary^accessing file descriptor
243: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
244: @*/
245: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
246: {
250: *flg = PETSC_FALSE;
251: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
252: return(0);
253: }
255: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
256: {
257: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
260: *fc = vbinary->flowcontrol;
261: return(0);
262: }
264: /*@C
265: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
267: Not Collective
269: Input Parameter:
270: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
272: Output Parameter:
273: . fc - the number of messages
275: Level: advanced
277: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
279: @*/
280: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
281: {
285: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
286: return(0);
287: }
289: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
290: {
291: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
294: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
295: vbinary->flowcontrol = fc;
296: return(0);
297: }
299: /*@C
300: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
302: Not Collective
304: Input Parameter:
305: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
306: - fc - the number of messages, defaults to 256 if this function was not called
308: Level: advanced
310: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
312: @*/
313: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
314: {
318: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
319: return(0);
320: }
322: /*@C
323: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
325: Collective On PetscViewer
327: Input Parameter:
328: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
330: Output Parameter:
331: . fdes - file descriptor
333: Level: advanced
335: Notes:
336: For writable binary PetscViewers, the descriptor will only be valid for the
337: first processor in the communicator that shares the PetscViewer. For readable
338: files it will only be valid on nodes that have the file. If node 0 does not
339: have the file it generates an error even if another node does have the file.
341: Fortran Note:
342: This routine is not supported in Fortran.
344: Developer Notes:
345: This must be called on all processes because Dave May changed
346: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
349: Concepts: file descriptor^getting
350: Concepts: PetscViewerBinary^accessing file descriptor
352: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
353: @*/
354: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
355: {
356: PetscErrorCode ierr;
357: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
360: PetscViewerSetUp(viewer);
361: *fdes = vbinary->fdes;
362: return(0);
363: }
365: /*@
366: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
368: Not Collective
370: Input Paramter:
371: . viewer - PetscViewer context, obtained from PetscViewerCreate()
373: Options Database Key:
374: . -viewer_binary_skip_info
376: Level: advanced
378: Notes:
379: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
380: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
381: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
383: The .info contains meta information about the data in the binary file, for example the block size if it was
384: set for a vector or matrix.
386: Concepts: PetscViewerBinary^accessing info file
388: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
389: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
390: @*/
391: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
392: {
393: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
396: vbinary->skipinfo = PETSC_TRUE;
397: return(0);
398: }
400: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
401: {
402: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
405: vbinary->skipinfo = skip;
406: return(0);
407: }
409: /*@
410: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
412: Not Collective
414: Input Paramter:
415: . viewer - PetscViewer context, obtained from PetscViewerCreate()
417: Options Database Key:
418: . -viewer_binary_skip_info
420: Level: advanced
422: Concepts: PetscViewerBinary^accessing info file
424: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
425: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
426: @*/
427: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
428: {
432: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
433: return(0);
434: }
436: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
437: {
438: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
441: *skip = vbinary->skipinfo;
442: return(0);
443: }
445: /*@
446: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
448: Not Collective
450: Input Parameter:
451: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
453: Output Parameter:
454: . skip - PETSC_TRUE implies the .info file was not generated
456: Level: advanced
458: Notes:
459: This must be called after PetscViewerSetType()
461: Concepts: PetscViewerBinary^accessing info file
463: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
464: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
465: @*/
466: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
467: {
471: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
472: return(0);
473: }
475: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
476: {
477: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
480: vbinary->skipoptions = skip;
481: return(0);
482: }
484: /*@
485: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
487: Not Collective
489: Input Parameters:
490: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
491: - skip - PETSC_TRUE means do not use
493: Options Database Key:
494: . -viewer_binary_skip_options
496: Level: advanced
498: Notes:
499: This must be called after PetscViewerSetType()
501: Concepts: PetscViewerBinary^accessing info file
503: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
504: PetscViewerBinaryGetSkipOptions()
505: @*/
506: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
507: {
511: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
512: return(0);
513: }
515: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
516: {
517: PetscViewer_Binary *vbinary;
521: vbinary = (PetscViewer_Binary*)viewer->data;
522: *skip = vbinary->skipoptions;
523: return(0);
524: }
526: /*@
527: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
529: Not Collective
531: Input Parameter:
532: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
534: Output Parameter:
535: . skip - PETSC_TRUE means do not use
537: Level: advanced
539: Notes:
540: This must be called after PetscViewerSetType()
542: Concepts: PetscViewerBinary^accessing info file
544: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
545: PetscViewerBinarySetSkipOptions()
546: @*/
547: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
548: {
552: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
553: return(0);
554: }
556: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
557: {
558: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
561: vbinary->skipheader = skip;
562: return(0);
563: }
565: /*@
566: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
568: Not Collective
570: Input Parameters:
571: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
572: - skip - PETSC_TRUE means do not write header
574: Options Database Key:
575: . -viewer_binary_skip_header
577: Level: advanced
579: Notes:
580: This must be called after PetscViewerSetType()
582: Can ONLY be called on a binary viewer
584: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
585: PetscViewerBinaryGetSkipHeader()
586: @*/
587: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
588: {
592: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
593: return(0);
594: }
596: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
597: {
598: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
601: *skip = vbinary->skipheader;
602: return(0);
603: }
605: /*@
606: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
608: Not Collective
610: Input Parameter:
611: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
613: Output Parameter:
614: . skip - PETSC_TRUE means do not write header
616: Level: advanced
618: Notes:
619: This must be called after PetscViewerSetType()
621: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
623: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
624: PetscViewerBinarySetSkipHeader()
625: @*/
626: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
627: {
631: *skip = PETSC_FALSE;
632: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
633: return(0);
634: }
636: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
637: {
638: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
639: PetscErrorCode ierr;
640: MPI_Comm comm;
643: PetscViewerSetUp(viewer);
644: *file = vbinary->fdes_info;
645: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
646: vbinary->matlabheaderwritten = PETSC_TRUE;
647: PetscObjectGetComm((PetscObject)viewer,&comm);
648: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
649: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
650: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
651: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
652: }
653: return(0);
654: }
656: /*@C
657: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
658: info file associated with a binary file.
660: Not Collective
662: Input Parameter:
663: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
665: Output Parameter:
666: . file - file pointer Always returns NULL if not a binary viewer
668: Level: advanced
670: Notes:
671: For writable binary PetscViewers, the descriptor will only be valid for the
672: first processor in the communicator that shares the PetscViewer.
674: Fortran Note:
675: This routine is not supported in Fortran.
677: Concepts: PetscViewerBinary^accessing info file
679: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
680: @*/
681: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
682: {
686: *file = NULL;
687: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
688: return(0);
689: }
691: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
692: {
693: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
694: PetscErrorCode ierr;
695: PetscMPIInt rank;
696: int err;
699: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
700: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
701: close(vbinary->fdes);
702: if (!rank && vbinary->storecompressed) {
703: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
704: FILE *fp;
705: /* compress the file */
706: PetscStrncpy(par,"gzip -f ",sizeof(par));
707: PetscStrlcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename,sizeof(par));
708: PetscFree(vbinary->ogzfilename);
709: #if defined(PETSC_HAVE_POPEN)
710: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
711: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
712: PetscPClose(PETSC_COMM_SELF,fp);
713: #else
714: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
715: #endif
716: }
717: }
718: if (vbinary->fdes_info) {
719: err = fclose(vbinary->fdes_info);
720: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
721: }
722: return(0);
723: }
725: #if defined(PETSC_HAVE_MPIIO)
726: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
727: {
728: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
729: int err;
730: PetscErrorCode ierr;
733: if (vbinary->mfdes != MPI_FILE_NULL) {
734: MPI_File_close(&vbinary->mfdes);
735: }
736: if (vbinary->mfsub != MPI_FILE_NULL) {
737: MPI_File_close(&vbinary->mfsub);
738: }
739: if (vbinary->fdes_info) {
740: err = fclose(vbinary->fdes_info);
741: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
742: }
743: return(0);
744: }
745: #endif
747: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
748: {
749: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
750: PetscErrorCode ierr;
753: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
754: MPI_Comm comm;
755: FILE *info;
757: PetscObjectGetComm((PetscObject)v,&comm);
758: PetscViewerBinaryGetInfoPointer(v,&info);
759: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
760: PetscFPrintf(comm,info,"#$$ close(fd);\n");
761: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
762: }
763: #if defined(PETSC_HAVE_MPIIO)
764: if (vbinary->usempiio) {
765: PetscViewerFileClose_BinaryMPIIO(v);
766: } else {
767: #endif
768: PetscViewerFileClose_Binary(v);
769: #if defined(PETSC_HAVE_MPIIO)
770: }
771: #endif
772: PetscFree(vbinary->filename);
773: PetscFree(vbinary->ogzfilename);
774: PetscFree(vbinary);
775: return(0);
776: }
778: /*@C
779: PetscViewerBinaryOpen - Opens a file for binary input/output.
781: Collective on MPI_Comm
783: Input Parameters:
784: + comm - MPI communicator
785: . name - name of file
786: - type - type of file
787: $ FILE_MODE_WRITE - create new file for binary output
788: $ FILE_MODE_READ - open existing file for binary input
789: $ FILE_MODE_APPEND - open existing file for binary output
791: Output Parameter:
792: . binv - PetscViewer for binary input/output to use with the specified file
794: Options Database Keys:
795: + -viewer_binary_filename <name>
796: . -viewer_binary_skip_info
797: . -viewer_binary_skip_options
798: . -viewer_binary_skip_header
799: - -viewer_binary_mpiio
801: Level: beginner
803: Note:
804: This PetscViewer should be destroyed with PetscViewerDestroy().
806: For reading files, the filename may begin with ftp:// or http:// and/or
807: end with .gz; in this case file is brought over and uncompressed.
809: For creating files, if the file name ends with .gz it is automatically
810: compressed when closed.
812: For writing files it only opens the file on processor 0 in the communicator.
813: For readable files it opens the file on all nodes that have the file. If
814: node 0 does not have the file it generates an error even if other nodes
815: do have the file.
817: Concepts: binary files
818: Concepts: PetscViewerBinary^creating
819: Concepts: gzip
820: Concepts: accessing remote file
821: Concepts: remote file
823: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
824: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
825: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
826: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
827: @*/
828: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
829: {
833: PetscViewerCreate(comm,binv);
834: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
835: PetscViewerFileSetMode(*binv,type);
836: PetscViewerFileSetName(*binv,name);
837: PetscViewerSetFromOptions(*binv);
838: return(0);
839: }
841: #if defined(PETSC_HAVE_MPIIO)
842: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
843: {
844: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
845: PetscErrorCode ierr;
846: MPI_File mfdes;
847: MPI_Datatype mdtype;
848: PetscMPIInt cnt;
849: MPI_Status status;
850: MPI_Aint ul,dsize;
853: mfdes = vbinary->mfdes;
854: PetscMPIIntCast(num,&cnt);
855: PetscDataTypeToMPIDataType(dtype,&mdtype);
856: MPI_File_set_view(mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
857: if (write) {
858: MPIU_File_write_all(mfdes,data,cnt,mdtype,&status);
859: } else {
860: MPIU_File_read_all(mfdes,data,cnt,mdtype,&status);
861: }
862: MPI_Type_get_extent(mdtype,&ul,&dsize);
864: vbinary->moff += dsize*cnt;
865: if (count) *count = num;
866: return(0);
867: }
868: #endif
870: /*@C
871: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
873: Collective on MPI_Comm
875: Input Parameters:
876: + viewer - the binary viewer
877: . data - location of the data to be written
878: . num - number of items of data to read
879: - dtype - type of data to read
881: Output Parameters:
882: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
884: Level: beginner
886: Concepts: binary files
888: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
890: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
891: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
892: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
893: @*/
894: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
895: {
896: PetscErrorCode ierr;
897: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
899: PetscViewerSetUp(viewer);
900: #if defined(PETSC_HAVE_MPIIO)
901: if (vbinary->usempiio) {
902: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
903: } else {
904: #endif
905: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
906: if (count) *count = num;
907: #if defined(PETSC_HAVE_MPIIO)
908: }
909: #endif
910: return(0);
911: }
913: /*@C
914: PetscViewerBinaryWrite - writes to a binary file, only from the first process
916: Collective on MPI_Comm
918: Input Parameters:
919: + viewer - the binary viewer
920: . data - location of data
921: . count - number of items of data to write
922: . dtype - type of data to write
923: - istemp - data may be overwritten
925: Level: beginner
927: Notes:
928: because byte-swapping may be done on the values in data it cannot be declared const
930: Concepts: binary files
932: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
933: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
934: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
935: @*/
936: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
937: {
938: PetscErrorCode ierr;
939: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
942: PetscViewerSetUp(viewer);
943: #if defined(PETSC_HAVE_MPIIO)
944: if (vbinary->usempiio) {
945: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
946: } else {
947: #endif
948: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
949: #if defined(PETSC_HAVE_MPIIO)
950: }
951: #endif
952: return(0);
953: }
955: /*@C
956: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
958: Collective on MPI_Comm
960: Input Parameters:
961: + viewer - the binary viewer
962: - data - location of the array of strings
965: Level: intermediate
967: Concepts: binary files
969: Notes:
970: array of strings is null terminated
972: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
973: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
974: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
975: @*/
976: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
977: {
979: PetscInt i,n = 0,*sizes;
981: PetscViewerSetUp(viewer);
982: /* count number of strings */
983: while (data[n++]) ;
984: n--;
985: PetscMalloc1(n+1,&sizes);
986: sizes[0] = n;
987: for (i=0; i<n; i++) {
988: size_t tmp;
989: PetscStrlen(data[i],&tmp);
990: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
991: }
992: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
993: for (i=0; i<n; i++) {
994: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
995: }
996: PetscFree(sizes);
997: return(0);
998: }
1000: /*@C
1001: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1003: Collective on MPI_Comm
1005: Input Parameter:
1006: . viewer - the binary viewer
1008: Output Parameter:
1009: . data - location of the array of strings
1011: Level: intermediate
1013: Concepts: binary files
1015: Notes:
1016: array of strings is null terminated
1018: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1019: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1020: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1021: @*/
1022: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1023: {
1025: PetscInt i,n,*sizes,N = 0;
1027: PetscViewerSetUp(viewer);
1028: /* count number of strings */
1029: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1030: PetscMalloc1(n,&sizes);
1031: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1032: for (i=0; i<n; i++) N += sizes[i];
1033: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1034: (*data)[0] = (char*)((*data) + n + 1);
1035: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1036: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1038: (*data)[n] = 0;
1040: PetscFree(sizes);
1041: return(0);
1042: }
1044: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1045: {
1046: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1049: *name = vbinary->filename;
1050: return(0);
1051: }
1053: /*@C
1054: PetscViewerFileGetMode - Gets the type of file to be open
1056: Not Collective
1058: Input Parameter:
1059: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1061: Output Parameter:
1062: . type - type of file
1063: $ FILE_MODE_WRITE - create new file for binary output
1064: $ FILE_MODE_READ - open existing file for binary input
1065: $ FILE_MODE_APPEND - open existing file for binary output
1067: Level: advanced
1069: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1071: @*/
1072: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1073: {
1079: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1080: return(0);
1081: }
1083: /*@
1084: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1085: before PetscViewerFileSetName()
1087: Logically Collective on PetscViewer
1089: Input Parameters:
1090: + viewer - the PetscViewer; must be a binary
1091: - flg - PETSC_TRUE means MPI-IO will be used
1093: Options Database:
1094: -viewer_binary_mpiio : Flag for using MPI-IO
1096: Level: advanced
1098: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1099: PetscViewerBinaryGetUseMPIIO()
1101: @*/
1102: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1103: {
1108: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1109: return(0);
1110: }
1112: /*@C
1113: PetscViewerFileSetMode - Sets the type of file to be open
1115: Logically Collective on PetscViewer
1117: Input Parameters:
1118: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1119: - type - type of file
1120: $ FILE_MODE_WRITE - create new file for output
1121: $ FILE_MODE_READ - open existing file for input
1122: $ FILE_MODE_APPEND - open existing file for output
1124: Level: advanced
1126: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1128: @*/
1129: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1130: {
1136: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1137: return(0);
1138: }
1140: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1141: {
1142: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1145: *type = vbinary->btype;
1146: return(0);
1147: }
1149: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1150: {
1151: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1154: vbinary->btype = type;
1155: return(0);
1156: }
1158: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1159: {
1160: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1161: PetscErrorCode ierr;
1164: if (vbinary->filename) {
1165: /* gzip can be run after the file with the previous filename has been closed */
1166: PetscFree(vbinary->ogzfilename);
1167: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1168: PetscFree(vbinary->filename);
1169: viewer->setupcalled = PETSC_FALSE;
1170: }
1171: PetscStrallocpy(name,&vbinary->filename);
1172: return(0);
1173: }
1174: /*
1175: Actually opens the file
1176: */
1177: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1178: {
1179: PetscMPIInt rank;
1180: PetscErrorCode ierr;
1181: size_t len;
1182: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1183: const char *fname;
1184: char bname[PETSC_MAX_PATH_LEN],*gz;
1185: PetscBool found;
1186: PetscFileMode type = vbinary->btype;
1189: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1190: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1191: PetscViewerFileClose_Binary(viewer);
1193: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1195: /* if ends in .gz strip that off and note user wants file compressed */
1196: vbinary->storecompressed = PETSC_FALSE;
1197: if (!rank && type == FILE_MODE_WRITE) {
1198: /* remove .gz if it ends library name */
1199: PetscStrstr(vbinary->filename,".gz",&gz);
1200: if (gz) {
1201: PetscStrlen(gz,&len);
1202: if (len == 3) {
1203: *gz = 0;
1204: vbinary->storecompressed = PETSC_TRUE;
1205: }
1206: }
1207: }
1209: /* only first processor opens file if writeable */
1210: if (!rank || type == FILE_MODE_READ) {
1212: if (type == FILE_MODE_READ) {
1213: /* possibly get the file from remote site or compressed file */
1214: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1215: fname = bname;
1216: /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */
1217: if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1218: } else fname = vbinary->filename;
1219: if (type == FILE_MODE_APPEND) { /* check if asked to append to a non-existing file */
1220: PetscTestFile(fname,'\0',&found);
1221: }
1223: #if defined(PETSC_HAVE_O_BINARY)
1224: if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) {
1225: if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1226: } else if (type == FILE_MODE_READ && fname) {
1227: if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1228: } else if (type == FILE_MODE_APPEND) {
1229: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1230: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1231: #else
1232: if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) {
1233: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1234: } else if (type == FILE_MODE_READ && fname) {
1235: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1236: } else if (type == FILE_MODE_APPEND) {
1237: if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname);
1238: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1239: #endif
1240: } else vbinary->fdes = -1;
1242: /*
1243: try to open info file: all processors open this file if read only
1244: */
1245: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1246: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1248: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1249: /* remove .gz if it ends library name */
1250: PetscStrstr(infoname,".gz",&gz);
1251: if (gz) {
1252: PetscStrlen(gz,&len);
1253: if (len == 3) *gz = 0;
1254: }
1256: PetscStrlcat(infoname,".info",sizeof(infoname));
1257: PetscFixFilename(infoname,iname);
1258: if (type == FILE_MODE_READ) {
1259: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1260: if (found) {
1261: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1262: }
1263: } else {
1264: vbinary->fdes_info = fopen(infoname,"w");
1265: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1266: }
1267: }
1268: #if defined(PETSC_USE_LOG)
1269: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1270: #endif
1271: return(0);
1272: }
1274: #if defined(PETSC_HAVE_MPIIO)
1275: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1276: {
1277: PetscMPIInt rank;
1278: PetscErrorCode ierr;
1279: size_t len;
1280: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1281: char *gz;
1282: PetscBool found;
1283: PetscFileMode type = vbinary->btype;
1284: int amode;
1287: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1288: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1289: PetscViewerFileClose_BinaryMPIIO(viewer);
1291: vbinary->storecompressed = PETSC_FALSE;
1293: switch (type) {
1294: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1295: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1296: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]);
1297: }
1298: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1300: /*
1301: try to open info file: all processors open this file if read only
1303: Below is identical code to the code for Binary above, should be put in separate routine
1304: */
1305: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1306: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1307: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1309: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1310: /* remove .gz if it ends library name */
1311: PetscStrstr(infoname,".gz",&gz);
1312: if (gz) {
1313: PetscStrlen(gz,&len);
1314: if (len == 3) *gz = 0;
1315: }
1317: PetscStrlcat(infoname,".info",sizeof(infoname));
1318: PetscFixFilename(infoname,iname);
1319: if (type == FILE_MODE_READ) {
1320: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1321: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1322: } else {
1323: vbinary->fdes_info = fopen(infoname,"w");
1324: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1325: }
1326: }
1327: #if defined(PETSC_USE_LOG)
1328: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1329: #endif
1330: return(0);
1331: }
1333: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1334: {
1335: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1337: vbinary->usempiio = flg;
1338: return(0);
1339: }
1340: #endif
1342: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1343: {
1344: PetscErrorCode ierr;
1345: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1348: if (binary->filename) {
1349: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1350: }
1351: return(0);
1352: }
1354: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1355: {
1356: PetscErrorCode ierr;
1357: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1360: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1361:
1362: #if defined(PETSC_HAVE_MPIIO)
1363: if (binary->usempiio) {
1364: PetscViewerFileSetUp_BinaryMPIIO(v);
1365: } else {
1366: #endif
1367: PetscViewerFileSetUp_Binary(v);
1368: #if defined(PETSC_HAVE_MPIIO)
1369: }
1370: #endif
1371: return(0);
1372: }
1374: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1375: {
1376: PetscErrorCode ierr;
1377: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1378: char defaultname[PETSC_MAX_PATH_LEN];
1379: PetscBool flg;
1382: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1383: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1384: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1385: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1386: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1387: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1388: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1389: #if defined(PETSC_HAVE_MPIIO)
1390: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1391: #elif defined(PETSC_HAVE_MPIUNI)
1392: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1393: #endif
1394: PetscOptionsTail();
1395: binary->setfromoptionscalled = PETSC_TRUE;
1396: return(0);
1397: }
1399: /*MC
1400: PETSCVIEWERBINARY - A viewer that saves to binary files
1403: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1404: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1405: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1406: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1408: Level: beginner
1410: M*/
1412: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1413: {
1414: PetscErrorCode ierr;
1415: PetscViewer_Binary *vbinary;
1418: PetscNewLog(v,&vbinary);
1419: v->data = (void*)vbinary;
1420: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1421: v->ops->destroy = PetscViewerDestroy_Binary;
1422: v->ops->view = PetscViewerView_Binary;
1423: v->ops->setup = PetscViewerSetUp_Binary;
1424: v->ops->flush = NULL;
1425: vbinary->fdes = 0;
1426: #if defined(PETSC_HAVE_MPIIO)
1427: vbinary->mfdes = MPI_FILE_NULL;
1428: vbinary->mfsub = MPI_FILE_NULL;
1429: #endif
1430: vbinary->fdes_info = 0;
1431: vbinary->skipinfo = PETSC_FALSE;
1432: vbinary->skipoptions = PETSC_TRUE;
1433: vbinary->skipheader = PETSC_FALSE;
1434: vbinary->setfromoptionscalled = PETSC_FALSE;
1435: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1436: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1437: v->ops->read = PetscViewerBinaryRead;
1438: vbinary->btype = (PetscFileMode) -1;
1439: vbinary->storecompressed = PETSC_FALSE;
1440: vbinary->filename = NULL;
1441: vbinary->ogzfilename = NULL;
1442: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1444: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1445: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1446: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1447: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1448: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1449: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1450: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1451: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1452: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1453: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1454: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1455: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1456: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1457: #if defined(PETSC_HAVE_MPIIO)
1458: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1459: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1460: #endif
1461: return(0);
1462: }
1464: /* ---------------------------------------------------------------------*/
1465: /*
1466: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1467: is attached to a communicator, in this case the attribute is a PetscViewer.
1468: */
1469: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1471: /*@C
1472: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1473: in a communicator.
1475: Collective on MPI_Comm
1477: Input Parameter:
1478: . comm - the MPI communicator to share the binary PetscViewer
1480: Level: intermediate
1482: Options Database Keys:
1483: + -viewer_binary_filename <name>
1484: . -viewer_binary_skip_info
1485: . -viewer_binary_skip_options
1486: . -viewer_binary_skip_header
1487: - -viewer_binary_mpiio
1489: Environmental variables:
1490: - PETSC_VIEWER_BINARY_FILENAME
1492: Notes:
1493: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1494: an error code. The binary PetscViewer is usually used in the form
1495: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1497: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1498: PetscViewerDestroy()
1499: @*/
1500: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1501: {
1503: PetscBool flg;
1504: PetscViewer viewer;
1505: char fname[PETSC_MAX_PATH_LEN];
1506: MPI_Comm ncomm;
1509: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1510: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1511: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1512: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1513: }
1514: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1515: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1516: if (!flg) { /* PetscViewer not yet created */
1517: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1518: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1519: if (!flg) {
1520: PetscStrcpy(fname,"binaryoutput");
1521: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1522: }
1523: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1524: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1525: PetscObjectRegisterDestroy((PetscObject)viewer);
1526: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1527: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1528: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1529: }
1530: PetscCommDestroy(&ncomm);
1531: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1532: PetscFunctionReturn(viewer);
1533: }