Actual source code: binv.c
petsc-3.10.5 2019-03-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 binary output
1121: $ FILE_MODE_READ - open existing file for binary input
1122: $ FILE_MODE_APPEND - open existing file for binary 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;
1220: #if defined(PETSC_HAVE_O_BINARY)
1221: if (type == FILE_MODE_WRITE) {
1222: 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);
1223: } else if (type == FILE_MODE_READ && fname) {
1224: 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);
1225: } else if (type == FILE_MODE_APPEND) {
1226: 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);
1227: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1228: #else
1229: if (type == FILE_MODE_WRITE) {
1230: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1231: } else if (type == FILE_MODE_READ && fname) {
1232: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1233: } else if (type == FILE_MODE_APPEND) {
1234: 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);
1235: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1236: #endif
1237: } else vbinary->fdes = -1;
1239: /*
1240: try to open info file: all processors open this file if read only
1241: */
1242: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1243: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1245: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1246: /* remove .gz if it ends library name */
1247: PetscStrstr(infoname,".gz",&gz);
1248: if (gz) {
1249: PetscStrlen(gz,&len);
1250: if (len == 3) *gz = 0;
1251: }
1253: PetscStrlcat(infoname,".info",sizeof(infoname));
1254: PetscFixFilename(infoname,iname);
1255: if (type == FILE_MODE_READ) {
1256: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1257: if (found) {
1258: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1259: }
1260: } else {
1261: vbinary->fdes_info = fopen(infoname,"w");
1262: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1263: }
1264: }
1265: #if defined(PETSC_USE_LOG)
1266: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1267: #endif
1268: return(0);
1269: }
1271: #if defined(PETSC_HAVE_MPIIO)
1272: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1273: {
1274: PetscMPIInt rank;
1275: PetscErrorCode ierr;
1276: size_t len;
1277: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1278: char *gz;
1279: PetscBool found;
1280: PetscFileMode type = vbinary->btype;
1281: int amode;
1284: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1285: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1286: PetscViewerFileClose_BinaryMPIIO(viewer);
1288: vbinary->storecompressed = PETSC_FALSE;
1290: switch (type) {
1291: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1292: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1293: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]);
1294: }
1295: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1297: /*
1298: try to open info file: all processors open this file if read only
1300: Below is identical code to the code for Binary above, should be put in separate routine
1301: */
1302: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1303: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1304: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1306: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1307: /* remove .gz if it ends library name */
1308: PetscStrstr(infoname,".gz",&gz);
1309: if (gz) {
1310: PetscStrlen(gz,&len);
1311: if (len == 3) *gz = 0;
1312: }
1314: PetscStrlcat(infoname,".info",sizeof(infoname));
1315: PetscFixFilename(infoname,iname);
1316: if (type == FILE_MODE_READ) {
1317: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1318: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1319: } else {
1320: vbinary->fdes_info = fopen(infoname,"w");
1321: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1322: }
1323: }
1324: #if defined(PETSC_USE_LOG)
1325: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1326: #endif
1327: return(0);
1328: }
1330: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1331: {
1332: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1334: vbinary->usempiio = flg;
1335: return(0);
1336: }
1337: #endif
1339: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1340: {
1341: PetscErrorCode ierr;
1342: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1345: if (binary->filename) {
1346: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1347: }
1348: return(0);
1349: }
1351: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1352: {
1353: PetscErrorCode ierr;
1354: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1357: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1358:
1359: #if defined(PETSC_HAVE_MPIIO)
1360: if (binary->usempiio) {
1361: PetscViewerFileSetUp_BinaryMPIIO(v);
1362: } else {
1363: #endif
1364: PetscViewerFileSetUp_Binary(v);
1365: #if defined(PETSC_HAVE_MPIIO)
1366: }
1367: #endif
1368: return(0);
1369: }
1371: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1372: {
1373: PetscErrorCode ierr;
1374: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1375: char defaultname[PETSC_MAX_PATH_LEN];
1376: PetscBool flg;
1379: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1380: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1381: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1382: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1383: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1384: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1385: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1386: #if defined(PETSC_HAVE_MPIIO)
1387: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1388: #elif defined(PETSC_HAVE_MPIUNI)
1389: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1390: #endif
1391: PetscOptionsTail();
1392: binary->setfromoptionscalled = PETSC_TRUE;
1393: return(0);
1394: }
1396: /*MC
1397: PETSCVIEWERBINARY - A viewer that saves to binary files
1400: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1401: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1402: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1403: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1405: Level: beginner
1407: M*/
1409: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1410: {
1411: PetscErrorCode ierr;
1412: PetscViewer_Binary *vbinary;
1415: PetscNewLog(v,&vbinary);
1416: v->data = (void*)vbinary;
1417: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1418: v->ops->destroy = PetscViewerDestroy_Binary;
1419: v->ops->view = PetscViewerView_Binary;
1420: v->ops->setup = PetscViewerSetUp_Binary;
1421: v->ops->flush = NULL;
1422: vbinary->fdes = 0;
1423: #if defined(PETSC_HAVE_MPIIO)
1424: vbinary->mfdes = MPI_FILE_NULL;
1425: vbinary->mfsub = MPI_FILE_NULL;
1426: #endif
1427: vbinary->fdes_info = 0;
1428: vbinary->skipinfo = PETSC_FALSE;
1429: vbinary->skipoptions = PETSC_TRUE;
1430: vbinary->skipheader = PETSC_FALSE;
1431: vbinary->setfromoptionscalled = PETSC_FALSE;
1432: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1433: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1434: v->ops->read = PetscViewerBinaryRead;
1435: vbinary->btype = (PetscFileMode) -1;
1436: vbinary->storecompressed = PETSC_FALSE;
1437: vbinary->filename = NULL;
1438: vbinary->ogzfilename = NULL;
1439: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1441: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1442: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1443: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1444: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1445: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1446: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1447: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1448: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1449: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1450: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1451: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1452: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1453: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1454: #if defined(PETSC_HAVE_MPIIO)
1455: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1456: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1457: #endif
1458: return(0);
1459: }
1461: /* ---------------------------------------------------------------------*/
1462: /*
1463: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1464: is attached to a communicator, in this case the attribute is a PetscViewer.
1465: */
1466: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1468: /*@C
1469: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1470: in a communicator.
1472: Collective on MPI_Comm
1474: Input Parameter:
1475: . comm - the MPI communicator to share the binary PetscViewer
1477: Level: intermediate
1479: Options Database Keys:
1480: + -viewer_binary_filename <name>
1481: . -viewer_binary_skip_info
1482: . -viewer_binary_skip_options
1483: . -viewer_binary_skip_header
1484: - -viewer_binary_mpiio
1486: Environmental variables:
1487: - PETSC_VIEWER_BINARY_FILENAME
1489: Notes:
1490: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1491: an error code. The binary PetscViewer is usually used in the form
1492: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1494: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1495: PetscViewerDestroy()
1496: @*/
1497: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1498: {
1500: PetscBool flg;
1501: PetscViewer viewer;
1502: char fname[PETSC_MAX_PATH_LEN];
1503: MPI_Comm ncomm;
1506: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1507: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1508: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1509: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1510: }
1511: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1512: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1513: if (!flg) { /* PetscViewer not yet created */
1514: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1515: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1516: if (!flg) {
1517: PetscStrcpy(fname,"binaryoutput");
1518: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1519: }
1520: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1521: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1522: PetscObjectRegisterDestroy((PetscObject)viewer);
1523: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1524: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1525: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1526: }
1527: PetscCommDestroy(&ncomm);
1528: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1529: PetscFunctionReturn(viewer);
1530: }