Actual source code: binv.c
petsc-3.9.4 2018-09-11
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: This must be called on all processes because Dave May changed
345: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
348: Concepts: file descriptor^getting
349: Concepts: PetscViewerBinary^accessing file descriptor
351: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
352: @*/
353: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
354: {
355: PetscErrorCode ierr;
356: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
359: PetscViewerSetUp(viewer);
360: *fdes = vbinary->fdes;
361: return(0);
362: }
364: /*@
365: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
367: Not Collective
369: Input Paramter:
370: . viewer - PetscViewer context, obtained from PetscViewerCreate()
372: Options Database Key:
373: . -viewer_binary_skip_info
375: Level: advanced
377: Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
378: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
379: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
381: The .info contains meta information about the data in the binary file, for example the block size if it was
382: set for a vector or matrix.
384: Concepts: PetscViewerBinary^accessing info file
386: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
387: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
388: @*/
389: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
390: {
391: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
394: vbinary->skipinfo = PETSC_TRUE;
395: return(0);
396: }
398: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
399: {
400: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
403: vbinary->skipinfo = skip;
404: return(0);
405: }
407: /*@
408: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
410: Not Collective
412: Input Paramter:
413: . viewer - PetscViewer context, obtained from PetscViewerCreate()
415: Options Database Key:
416: . -viewer_binary_skip_info
418: Level: advanced
420: Concepts: PetscViewerBinary^accessing info file
422: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
423: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
424: @*/
425: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
426: {
430: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
431: return(0);
432: }
434: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
435: {
436: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
439: *skip = vbinary->skipinfo;
440: return(0);
441: }
443: /*@
444: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
446: Not Collective
448: Input Parameter:
449: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
451: Output Parameter:
452: . skip - PETSC_TRUE implies the .info file was not generated
454: Level: advanced
456: Notes: This must be called after PetscViewerSetType()
458: Concepts: PetscViewerBinary^accessing info file
460: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
461: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
462: @*/
463: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
464: {
468: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
469: return(0);
470: }
472: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
473: {
474: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
477: vbinary->skipoptions = skip;
478: return(0);
479: }
481: /*@
482: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
484: Not Collective
486: Input Parameters:
487: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
488: - skip - PETSC_TRUE means do not use
490: Options Database Key:
491: . -viewer_binary_skip_options
493: Level: advanced
495: Notes: This must be called after PetscViewerSetType()
497: Concepts: PetscViewerBinary^accessing info file
499: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
500: PetscViewerBinaryGetSkipOptions()
501: @*/
502: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
503: {
507: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
508: return(0);
509: }
511: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
512: {
513: PetscViewer_Binary *vbinary;
517: vbinary = (PetscViewer_Binary*)viewer->data;
518: *skip = vbinary->skipoptions;
519: return(0);
520: }
522: /*@
523: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
525: Not Collective
527: Input Parameter:
528: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
530: Output Parameter:
531: . skip - PETSC_TRUE means do not use
533: Level: advanced
535: Notes: This must be called after PetscViewerSetType()
537: Concepts: PetscViewerBinary^accessing info file
539: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
540: PetscViewerBinarySetSkipOptions()
541: @*/
542: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
543: {
547: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
548: return(0);
549: }
551: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
552: {
553: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
556: vbinary->skipheader = skip;
557: return(0);
558: }
560: /*@
561: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
563: Not Collective
565: Input Parameters:
566: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
567: - skip - PETSC_TRUE means do not write header
569: Options Database Key:
570: . -viewer_binary_skip_header
572: Level: advanced
574: Notes: This must be called after PetscViewerSetType()
576: Can ONLY be called on a binary viewer
578: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
579: PetscViewerBinaryGetSkipHeader()
580: @*/
581: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
582: {
586: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
587: return(0);
588: }
590: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
591: {
592: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
595: *skip = vbinary->skipheader;
596: return(0);
597: }
599: /*@
600: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
602: Not Collective
604: Input Parameter:
605: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
607: Output Parameter:
608: . skip - PETSC_TRUE means do not write header
610: Level: advanced
612: Notes: This must be called after PetscViewerSetType()
614: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
616: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
617: PetscViewerBinarySetSkipHeader()
618: @*/
619: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
620: {
624: *skip = PETSC_FALSE;
625: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
626: return(0);
627: }
629: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
630: {
631: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
632: PetscErrorCode ierr;
633: MPI_Comm comm;
636: PetscViewerSetUp(viewer);
637: *file = vbinary->fdes_info;
638: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
639: vbinary->matlabheaderwritten = PETSC_TRUE;
640: PetscObjectGetComm((PetscObject)viewer,&comm);
641: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
642: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
643: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
644: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
645: }
646: return(0);
647: }
649: /*@C
650: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
651: info file associated with a binary file.
653: Not Collective
655: Input Parameter:
656: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
658: Output Parameter:
659: . file - file pointer Always returns NULL if not a binary viewer
661: Level: advanced
663: Notes:
664: For writable binary PetscViewers, the descriptor will only be valid for the
665: first processor in the communicator that shares the PetscViewer.
667: Fortran Note:
668: This routine is not supported in Fortran.
670: Concepts: PetscViewerBinary^accessing info file
672: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
673: @*/
674: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
675: {
679: *file = NULL;
680: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
681: return(0);
682: }
684: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
685: {
686: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
687: PetscErrorCode ierr;
688: PetscMPIInt rank;
689: int err;
692: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
693: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
694: close(vbinary->fdes);
695: if (!rank && vbinary->storecompressed) {
696: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
697: FILE *fp;
698: /* compress the file */
699: PetscStrncpy(par,"gzip -f ",sizeof(par));
700: PetscStrlcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename,sizeof(par));
701: PetscFree(vbinary->ogzfilename);
702: #if defined(PETSC_HAVE_POPEN)
703: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
704: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
705: PetscPClose(PETSC_COMM_SELF,fp);
706: #else
707: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
708: #endif
709: }
710: }
711: if (vbinary->fdes_info) {
712: err = fclose(vbinary->fdes_info);
713: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
714: }
715: return(0);
716: }
718: #if defined(PETSC_HAVE_MPIIO)
719: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
720: {
721: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
722: int err;
723: PetscErrorCode ierr;
726: if (vbinary->mfdes != MPI_FILE_NULL) {
727: MPI_File_close(&vbinary->mfdes);
728: }
729: if (vbinary->mfsub != MPI_FILE_NULL) {
730: MPI_File_close(&vbinary->mfsub);
731: }
732: if (vbinary->fdes_info) {
733: err = fclose(vbinary->fdes_info);
734: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
735: }
736: return(0);
737: }
738: #endif
740: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
741: {
742: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
743: PetscErrorCode ierr;
746: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
747: MPI_Comm comm;
748: FILE *info;
750: PetscObjectGetComm((PetscObject)v,&comm);
751: PetscViewerBinaryGetInfoPointer(v,&info);
752: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
753: PetscFPrintf(comm,info,"#$$ close(fd);\n");
754: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
755: }
756: #if defined(PETSC_HAVE_MPIIO)
757: if (vbinary->usempiio) {
758: PetscViewerFileClose_BinaryMPIIO(v);
759: } else {
760: #endif
761: PetscViewerFileClose_Binary(v);
762: #if defined(PETSC_HAVE_MPIIO)
763: }
764: #endif
765: PetscFree(vbinary->filename);
766: PetscFree(vbinary->ogzfilename);
767: PetscFree(vbinary);
768: return(0);
769: }
771: /*@C
772: PetscViewerBinaryOpen - Opens a file for binary input/output.
774: Collective on MPI_Comm
776: Input Parameters:
777: + comm - MPI communicator
778: . name - name of file
779: - type - type of file
780: $ FILE_MODE_WRITE - create new file for binary output
781: $ FILE_MODE_READ - open existing file for binary input
782: $ FILE_MODE_APPEND - open existing file for binary output
784: Output Parameter:
785: . binv - PetscViewer for binary input/output to use with the specified file
787: Options Database Keys:
788: + -viewer_binary_filename <name>
789: . -viewer_binary_skip_info
790: . -viewer_binary_skip_options
791: . -viewer_binary_skip_header
792: - -viewer_binary_mpiio
794: Level: beginner
796: Note:
797: This PetscViewer should be destroyed with PetscViewerDestroy().
799: For reading files, the filename may begin with ftp:// or http:// and/or
800: end with .gz; in this case file is brought over and uncompressed.
802: For creating files, if the file name ends with .gz it is automatically
803: compressed when closed.
805: For writing files it only opens the file on processor 0 in the communicator.
806: For readable files it opens the file on all nodes that have the file. If
807: node 0 does not have the file it generates an error even if other nodes
808: do have the file.
810: Concepts: binary files
811: Concepts: PetscViewerBinary^creating
812: Concepts: gzip
813: Concepts: accessing remote file
814: Concepts: remote file
816: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
817: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
818: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
819: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
820: @*/
821: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
822: {
826: PetscViewerCreate(comm,binv);
827: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
828: PetscViewerFileSetMode(*binv,type);
829: PetscViewerFileSetName(*binv,name);
830: PetscViewerSetFromOptions(*binv);
831: return(0);
832: }
834: #if defined(PETSC_HAVE_MPIIO)
835: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
836: {
837: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
838: PetscErrorCode ierr;
839: MPI_File mfdes;
840: MPI_Datatype mdtype;
841: PetscMPIInt cnt;
842: MPI_Status status;
843: MPI_Aint ul,dsize;
846: mfdes = vbinary->mfdes;
847: PetscMPIIntCast(num,&cnt);
848: PetscDataTypeToMPIDataType(dtype,&mdtype);
849: MPI_File_set_view(mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
850: if (write) {
851: MPIU_File_write_all(mfdes,data,cnt,mdtype,&status);
852: } else {
853: MPIU_File_read_all(mfdes,data,cnt,mdtype,&status);
854: }
855: MPI_Type_get_extent(mdtype,&ul,&dsize);
857: vbinary->moff += dsize*cnt;
858: if (count) *count = num;
859: return(0);
860: }
861: #endif
863: /*@C
864: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
866: Collective on MPI_Comm
868: Input Parameters:
869: + viewer - the binary viewer
870: . data - location of the data to be written
871: . num - number of items of data to read
872: - dtype - type of data to read
874: Output Parameters:
875: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
877: Level: beginner
879: Concepts: binary files
881: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
883: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
884: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
885: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
886: @*/
887: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
888: {
889: PetscErrorCode ierr;
890: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
892: PetscViewerSetUp(viewer);
893: #if defined(PETSC_HAVE_MPIIO)
894: if (vbinary->usempiio) {
895: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
896: } else {
897: #endif
898: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
899: if (count) *count = num;
900: #if defined(PETSC_HAVE_MPIIO)
901: }
902: #endif
903: return(0);
904: }
906: /*@C
907: PetscViewerBinaryWrite - writes to a binary file, only from the first process
909: Collective on MPI_Comm
911: Input Parameters:
912: + viewer - the binary viewer
913: . data - location of data
914: . count - number of items of data to write
915: . dtype - type of data to write
916: - istemp - data may be overwritten
918: Level: beginner
920: Notes: because byte-swapping may be done on the values in data it cannot be declared const
922: Concepts: binary files
924: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
925: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
926: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
927: @*/
928: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
929: {
930: PetscErrorCode ierr;
931: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
934: PetscViewerSetUp(viewer);
935: #if defined(PETSC_HAVE_MPIIO)
936: if (vbinary->usempiio) {
937: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
938: } else {
939: #endif
940: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
941: #if defined(PETSC_HAVE_MPIIO)
942: }
943: #endif
944: return(0);
945: }
947: /*@C
948: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
950: Collective on MPI_Comm
952: Input Parameters:
953: + viewer - the binary viewer
954: - data - location of the array of strings
957: Level: intermediate
959: Concepts: binary files
961: Notes: array of strings is null terminated
963: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
964: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
965: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
966: @*/
967: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
968: {
970: PetscInt i,n = 0,*sizes;
972: PetscViewerSetUp(viewer);
973: /* count number of strings */
974: while (data[n++]) ;
975: n--;
976: PetscMalloc1(n+1,&sizes);
977: sizes[0] = n;
978: for (i=0; i<n; i++) {
979: size_t tmp;
980: PetscStrlen(data[i],&tmp);
981: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
982: }
983: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
984: for (i=0; i<n; i++) {
985: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
986: }
987: PetscFree(sizes);
988: return(0);
989: }
991: /*@C
992: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
994: Collective on MPI_Comm
996: Input Parameter:
997: . viewer - the binary viewer
999: Output Parameter:
1000: . data - location of the array of strings
1002: Level: intermediate
1004: Concepts: binary files
1006: Notes: array of strings is null terminated
1008: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1009: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1010: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1011: @*/
1012: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1013: {
1015: PetscInt i,n,*sizes,N = 0;
1017: PetscViewerSetUp(viewer);
1018: /* count number of strings */
1019: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1020: PetscMalloc1(n,&sizes);
1021: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1022: for (i=0; i<n; i++) N += sizes[i];
1023: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1024: (*data)[0] = (char*)((*data) + n + 1);
1025: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1026: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1028: (*data)[n] = 0;
1030: PetscFree(sizes);
1031: return(0);
1032: }
1034: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1035: {
1036: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1039: *name = vbinary->filename;
1040: return(0);
1041: }
1043: /*@C
1044: PetscViewerFileGetMode - Gets the type of file to be open
1046: Not Collective
1048: Input Parameter:
1049: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1051: Output Parameter:
1052: . type - type of file
1053: $ FILE_MODE_WRITE - create new file for binary output
1054: $ FILE_MODE_READ - open existing file for binary input
1055: $ FILE_MODE_APPEND - open existing file for binary output
1057: Level: advanced
1059: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1061: @*/
1062: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1063: {
1069: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1070: return(0);
1071: }
1073: /*@
1074: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1075: before PetscViewerFileSetName()
1077: Logically Collective on PetscViewer
1079: Input Parameters:
1080: + viewer - the PetscViewer; must be a binary
1081: - flg - PETSC_TRUE means MPI-IO will be used
1083: Options Database:
1084: -viewer_binary_mpiio : Flag for using MPI-IO
1086: Level: advanced
1088: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1089: PetscViewerBinaryGetUseMPIIO()
1091: @*/
1092: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1093: {
1098: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1099: return(0);
1100: }
1102: /*@C
1103: PetscViewerFileSetMode - Sets the type of file to be open
1105: Logically Collective on PetscViewer
1107: Input Parameters:
1108: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1109: - type - type of file
1110: $ FILE_MODE_WRITE - create new file for binary output
1111: $ FILE_MODE_READ - open existing file for binary input
1112: $ FILE_MODE_APPEND - open existing file for binary output
1114: Level: advanced
1116: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1118: @*/
1119: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1120: {
1126: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1127: return(0);
1128: }
1130: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1131: {
1132: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1135: *type = vbinary->btype;
1136: return(0);
1137: }
1139: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1140: {
1141: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1144: vbinary->btype = type;
1145: return(0);
1146: }
1148: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1149: {
1150: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1151: PetscErrorCode ierr;
1154: if (vbinary->filename) {
1155: /* gzip can be run after the file with the previous filename has been closed */
1156: PetscFree(vbinary->ogzfilename);
1157: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1158: PetscFree(vbinary->filename);
1159: viewer->setupcalled = PETSC_FALSE;
1160: }
1161: PetscStrallocpy(name,&vbinary->filename);
1162: return(0);
1163: }
1164: /*
1165: Actually opens the file
1166: */
1167: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1168: {
1169: PetscMPIInt rank;
1170: PetscErrorCode ierr;
1171: size_t len;
1172: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1173: const char *fname;
1174: char bname[PETSC_MAX_PATH_LEN],*gz;
1175: PetscBool found;
1176: PetscFileMode type = vbinary->btype;
1179: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1180: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1181: PetscViewerFileClose_Binary(viewer);
1183: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1185: /* if ends in .gz strip that off and note user wants file compressed */
1186: vbinary->storecompressed = PETSC_FALSE;
1187: if (!rank && type == FILE_MODE_WRITE) {
1188: /* remove .gz if it ends library name */
1189: PetscStrstr(vbinary->filename,".gz",&gz);
1190: if (gz) {
1191: PetscStrlen(gz,&len);
1192: if (len == 3) {
1193: *gz = 0;
1194: vbinary->storecompressed = PETSC_TRUE;
1195: }
1196: }
1197: }
1199: /* only first processor opens file if writeable */
1200: if (!rank || type == FILE_MODE_READ) {
1202: if (type == FILE_MODE_READ) {
1203: /* possibly get the file from remote site or compressed file */
1204: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1205: fname = bname;
1206: /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */
1207: if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1208: } else fname = vbinary->filename;
1210: #if defined(PETSC_HAVE_O_BINARY)
1211: if (type == FILE_MODE_WRITE) {
1212: 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);
1213: } else if (type == FILE_MODE_READ && fname) {
1214: 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);
1215: } else if (type == FILE_MODE_APPEND) {
1216: 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);
1217: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1218: #else
1219: if (type == FILE_MODE_WRITE) {
1220: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1221: } else if (type == FILE_MODE_READ && fname) {
1222: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1223: } else if (type == FILE_MODE_APPEND) {
1224: 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);
1225: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1226: #endif
1227: } else vbinary->fdes = -1;
1229: /*
1230: try to open info file: all processors open this file if read only
1231: */
1232: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1233: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1235: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1236: /* remove .gz if it ends library name */
1237: PetscStrstr(infoname,".gz",&gz);
1238: if (gz) {
1239: PetscStrlen(gz,&len);
1240: if (len == 3) *gz = 0;
1241: }
1243: PetscStrlcat(infoname,".info",sizeof(infoname));
1244: PetscFixFilename(infoname,iname);
1245: if (type == FILE_MODE_READ) {
1246: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1247: if (found) {
1248: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1249: }
1250: } else {
1251: vbinary->fdes_info = fopen(infoname,"w");
1252: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1253: }
1254: }
1255: #if defined(PETSC_USE_LOG)
1256: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1257: #endif
1258: return(0);
1259: }
1261: #if defined(PETSC_HAVE_MPIIO)
1262: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1263: {
1264: PetscMPIInt rank;
1265: PetscErrorCode ierr;
1266: size_t len;
1267: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1268: char *gz;
1269: PetscBool found;
1270: PetscFileMode type = vbinary->btype;
1271: int amode;
1274: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1275: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1276: PetscViewerFileClose_BinaryMPIIO(viewer);
1278: vbinary->storecompressed = PETSC_FALSE;
1280: switch (type) {
1281: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1282: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1283: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]);
1284: }
1285: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1287: /*
1288: try to open info file: all processors open this file if read only
1290: Below is identical code to the code for Binary above, should be put in separate routine
1291: */
1292: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1293: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1294: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1296: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1297: /* remove .gz if it ends library name */
1298: PetscStrstr(infoname,".gz",&gz);
1299: if (gz) {
1300: PetscStrlen(gz,&len);
1301: if (len == 3) *gz = 0;
1302: }
1304: PetscStrlcat(infoname,".info",sizeof(infoname));
1305: PetscFixFilename(infoname,iname);
1306: if (type == FILE_MODE_READ) {
1307: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1308: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1309: } else {
1310: vbinary->fdes_info = fopen(infoname,"w");
1311: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1312: }
1313: }
1314: #if defined(PETSC_USE_LOG)
1315: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1316: #endif
1317: return(0);
1318: }
1320: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1321: {
1322: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1324: vbinary->usempiio = flg;
1325: return(0);
1326: }
1327: #endif
1329: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1330: {
1331: PetscErrorCode ierr;
1332: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1335: if (binary->filename) {
1336: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1337: }
1338: return(0);
1339: }
1341: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1342: {
1343: PetscErrorCode ierr;
1344: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1347: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1348:
1349: #if defined(PETSC_HAVE_MPIIO)
1350: if (binary->usempiio) {
1351: PetscViewerFileSetUp_BinaryMPIIO(v);
1352: } else {
1353: #endif
1354: PetscViewerFileSetUp_Binary(v);
1355: #if defined(PETSC_HAVE_MPIIO)
1356: }
1357: #endif
1358: return(0);
1359: }
1361: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1362: {
1363: PetscErrorCode ierr;
1364: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1365: char defaultname[PETSC_MAX_PATH_LEN];
1366: PetscBool flg;
1369: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1370: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1371: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1372: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1373: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1374: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1375: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1376: #if defined(PETSC_HAVE_MPIIO)
1377: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1378: #elif defined(PETSC_HAVE_MPIUNI)
1379: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1380: #endif
1381: PetscOptionsTail();
1382: binary->setfromoptionscalled = PETSC_TRUE;
1383: return(0);
1384: }
1386: /*MC
1387: PETSCVIEWERBINARY - A viewer that saves to binary files
1390: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1391: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1392: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1393: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1395: Level: beginner
1397: M*/
1399: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1400: {
1401: PetscErrorCode ierr;
1402: PetscViewer_Binary *vbinary;
1405: PetscNewLog(v,&vbinary);
1406: v->data = (void*)vbinary;
1407: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1408: v->ops->destroy = PetscViewerDestroy_Binary;
1409: v->ops->view = PetscViewerView_Binary;
1410: v->ops->setup = PetscViewerSetUp_Binary;
1411: v->ops->flush = NULL;
1412: vbinary->fdes = 0;
1413: #if defined(PETSC_HAVE_MPIIO)
1414: vbinary->mfdes = MPI_FILE_NULL;
1415: vbinary->mfsub = MPI_FILE_NULL;
1416: #endif
1417: vbinary->fdes_info = 0;
1418: vbinary->skipinfo = PETSC_FALSE;
1419: vbinary->skipoptions = PETSC_TRUE;
1420: vbinary->skipheader = PETSC_FALSE;
1421: vbinary->setfromoptionscalled = PETSC_FALSE;
1422: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1423: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1424: v->ops->read = PetscViewerBinaryRead;
1425: vbinary->btype = (PetscFileMode) -1;
1426: vbinary->storecompressed = PETSC_FALSE;
1427: vbinary->filename = NULL;
1428: vbinary->ogzfilename = NULL;
1429: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1431: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1432: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1433: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1434: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1435: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1436: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1437: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1438: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1439: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1440: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1441: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1442: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1443: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1444: #if defined(PETSC_HAVE_MPIIO)
1445: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1446: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1447: #endif
1448: return(0);
1449: }
1451: /* ---------------------------------------------------------------------*/
1452: /*
1453: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1454: is attached to a communicator, in this case the attribute is a PetscViewer.
1455: */
1456: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1458: /*@C
1459: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1460: in a communicator.
1462: Collective on MPI_Comm
1464: Input Parameter:
1465: . comm - the MPI communicator to share the binary PetscViewer
1467: Level: intermediate
1469: Options Database Keys:
1470: + -viewer_binary_filename <name>
1471: . -viewer_binary_skip_info
1472: . -viewer_binary_skip_options
1473: . -viewer_binary_skip_header
1474: - -viewer_binary_mpiio
1476: Environmental variables:
1477: - PETSC_VIEWER_BINARY_FILENAME
1479: Notes:
1480: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1481: an error code. The binary PetscViewer is usually used in the form
1482: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1484: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1485: PetscViewerDestroy()
1486: @*/
1487: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1488: {
1490: PetscBool flg;
1491: PetscViewer viewer;
1492: char fname[PETSC_MAX_PATH_LEN];
1493: MPI_Comm ncomm;
1496: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1497: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1498: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1499: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1500: }
1501: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1502: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1503: if (!flg) { /* PetscViewer not yet created */
1504: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1505: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1506: if (!flg) {
1507: PetscStrcpy(fname,"binaryoutput");
1508: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1509: }
1510: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1511: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1512: PetscObjectRegisterDestroy((PetscObject)viewer);
1513: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1514: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1515: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1516: }
1517: PetscCommDestroy(&ncomm);
1518: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1519: PetscFunctionReturn(viewer);
1520: }