Actual source code: binv.c
petsc-3.12.5 2020-03-29
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: PetscMPIInt flg;
46: MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);
47: if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERBINARY requires a singleton MPI_Comm");
48: PetscViewerCreate(comm,outviewer);
49: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
50: PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));
51: (*outviewer)->setupcalled = PETSC_TRUE;
52: } else {
53: *outviewer = NULL;
54: }
56: #if defined(PETSC_HAVE_MPIIO)
57: if (vbinary->usempiio && *outviewer) {
58: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
59: /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */
60: if (vbinary->mfsub == MPI_FILE_NULL) {
61: int amode;
62: switch (vbinary->btype) {
63: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
64: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY; break;
65: default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->btype]);
66: }
67: MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);
68: }
69: /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */
70: obinary->mfdes = vbinary->mfsub;
71: obinary->mfsub = MPI_FILE_NULL;
72: obinary->moff = vbinary->moff;
73: }
74: #endif
75: return(0);
76: }
78: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
79: {
80: PetscMPIInt rank;
81: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
82: PetscErrorCode ierr;
83: #if defined(PETSC_HAVE_MPIIO)
84: MPI_Offset moff = 0;
85: #endif
88: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
89: if (rank && *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
91: #if defined(PETSC_HAVE_MPIIO)
92: if (vbinary->usempiio && *outviewer) {
93: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
94: if (obinary->mfdes != vbinary->mfsub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
95: moff = obinary->moff;
96: }
97: #endif
99: if (*outviewer) {
100: PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
101: if (obinary->fdes != vbinary->fdes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
102: PetscFree((*outviewer)->data);
103: PetscHeaderDestroy(outviewer);
104: }
106: #if defined(PETSC_HAVE_MPIIO)
107: if (vbinary->usempiio) {
108: PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */
109: MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));
110: vbinary->moff = (MPI_Offset)ioff;
111: }
112: #endif
113: return(0);
114: }
116: #if defined(PETSC_HAVE_MPIIO)
117: /*@C
118: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
120: Not Collective
122: Input Parameter:
123: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
125: Output Parameter:
126: . off - the current offset
128: Level: advanced
130: Fortran Note:
131: This routine is not supported in Fortran.
133: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
136: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
137: @*/
138: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
139: {
140: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
143: *off = vbinary->moff;
144: return(0);
145: }
147: /*@C
148: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
150: Not Collective
152: Input Parameters:
153: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
154: - off - the addition to the offset
156: Level: advanced
158: Fortran Note:
159: This routine is not supported in Fortran.
161: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
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.
192: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
193: @*/
194: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
195: {
196: PetscErrorCode ierr;
197: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
200: PetscViewerSetUp(viewer);
201: *fdes = vbinary->mfdes;
202: return(0);
203: }
205: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg)
206: {
207: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
210: *flg = vbinary->usempiio;
211: return(0);
212: }
213: #endif
216: /*@C
217: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
219: Not Collective
221: Input Parameter:
222: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
224: Output Parameter:
225: - flg - PETSC_TRUE if MPI-IO is being used
227: Options Database:
228: -viewer_binary_mpiio : Flag for using MPI-IO
230: Level: advanced
232: Note:
233: If MPI-IO is not available, this function will always return PETSC_FALSE
235: Fortran Note:
236: This routine is not supported in Fortran.
239: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
240: @*/
241: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
242: {
246: *flg = PETSC_FALSE;
247: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
248: return(0);
249: }
251: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
252: {
253: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
256: *fc = vbinary->flowcontrol;
257: return(0);
258: }
260: /*@C
261: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
263: Not Collective
265: Input Parameter:
266: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
268: Output Parameter:
269: . fc - the number of messages
271: Level: advanced
273: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
275: @*/
276: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
277: {
281: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
282: return(0);
283: }
285: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
286: {
287: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
290: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
291: vbinary->flowcontrol = fc;
292: return(0);
293: }
295: /*@C
296: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
298: Not Collective
300: Input Parameter:
301: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
302: - fc - the number of messages, defaults to 256 if this function was not called
304: Level: advanced
306: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
308: @*/
309: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
310: {
314: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
315: return(0);
316: }
318: /*@C
319: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
321: Collective On PetscViewer
323: Input Parameter:
324: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
326: Output Parameter:
327: . fdes - file descriptor
329: Level: advanced
331: Notes:
332: For writable binary PetscViewers, the descriptor will only be valid for the
333: first processor in the communicator that shares the PetscViewer. For readable
334: files it will only be valid on nodes that have the file. If node 0 does not
335: have the file it generates an error even if another node does have the file.
337: Fortran Note:
338: This routine is not supported in Fortran.
340: Developer Notes:
341: This must be called on all processes because Dave May changed
342: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
346: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
347: @*/
348: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
349: {
350: PetscErrorCode ierr;
351: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
354: PetscViewerSetUp(viewer);
355: *fdes = vbinary->fdes;
356: return(0);
357: }
359: /*@
360: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
362: Not Collective
364: Input Paramter:
365: . viewer - PetscViewer context, obtained from PetscViewerCreate()
367: Options Database Key:
368: . -viewer_binary_skip_info
370: Level: advanced
372: Notes:
373: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
374: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
375: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
377: The .info contains meta information about the data in the binary file, for example the block size if it was
378: set for a vector or matrix.
380: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
381: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
382: @*/
383: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
384: {
385: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
388: vbinary->skipinfo = PETSC_TRUE;
389: return(0);
390: }
392: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
393: {
394: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
397: vbinary->skipinfo = skip;
398: return(0);
399: }
401: /*@
402: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
404: Not Collective
406: Input Paramter:
407: . viewer - PetscViewer context, obtained from PetscViewerCreate()
409: Options Database Key:
410: . -viewer_binary_skip_info
412: Level: advanced
414: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
415: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
416: @*/
417: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
418: {
422: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
423: return(0);
424: }
426: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
427: {
428: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
431: *skip = vbinary->skipinfo;
432: return(0);
433: }
435: /*@
436: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
438: Not Collective
440: Input Parameter:
441: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
443: Output Parameter:
444: . skip - PETSC_TRUE implies the .info file was not generated
446: Level: advanced
448: Notes:
449: This must be called after PetscViewerSetType()
451: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
452: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
453: @*/
454: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
455: {
459: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
460: return(0);
461: }
463: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
464: {
465: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
468: vbinary->skipoptions = skip;
469: return(0);
470: }
472: /*@
473: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
475: Not Collective
477: Input Parameters:
478: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
479: - skip - PETSC_TRUE means do not use
481: Options Database Key:
482: . -viewer_binary_skip_options
484: Level: advanced
486: Notes:
487: This must be called after PetscViewerSetType()
489: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
490: PetscViewerBinaryGetSkipOptions()
491: @*/
492: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
493: {
497: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
498: return(0);
499: }
501: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
502: {
503: PetscViewer_Binary *vbinary;
507: vbinary = (PetscViewer_Binary*)viewer->data;
508: *skip = vbinary->skipoptions;
509: return(0);
510: }
512: /*@
513: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
515: Not Collective
517: Input Parameter:
518: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
520: Output Parameter:
521: . skip - PETSC_TRUE means do not use
523: Level: advanced
525: Notes:
526: This must be called after PetscViewerSetType()
528: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
529: PetscViewerBinarySetSkipOptions()
530: @*/
531: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
532: {
536: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
537: return(0);
538: }
540: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
541: {
542: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
545: vbinary->skipheader = skip;
546: return(0);
547: }
549: /*@
550: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
552: Not Collective
554: Input Parameters:
555: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
556: - skip - PETSC_TRUE means do not write header
558: Options Database Key:
559: . -viewer_binary_skip_header
561: Level: advanced
563: Notes:
564: This must be called after PetscViewerSetType()
566: Can ONLY be called on a binary viewer
568: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
569: PetscViewerBinaryGetSkipHeader()
570: @*/
571: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
572: {
576: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
577: return(0);
578: }
580: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
581: {
582: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
585: *skip = vbinary->skipheader;
586: return(0);
587: }
589: /*@
590: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
592: Not Collective
594: Input Parameter:
595: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
597: Output Parameter:
598: . skip - PETSC_TRUE means do not write header
600: Level: advanced
602: Notes:
603: This must be called after PetscViewerSetType()
605: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
607: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
608: PetscViewerBinarySetSkipHeader()
609: @*/
610: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
611: {
615: *skip = PETSC_FALSE;
616: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
617: return(0);
618: }
620: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
621: {
622: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
623: PetscErrorCode ierr;
624: MPI_Comm comm;
627: PetscViewerSetUp(viewer);
628: *file = vbinary->fdes_info;
629: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
630: vbinary->matlabheaderwritten = PETSC_TRUE;
631: PetscObjectGetComm((PetscObject)viewer,&comm);
632: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
633: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
634: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
635: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
636: }
637: return(0);
638: }
640: /*@C
641: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
642: info file associated with a binary file.
644: Not Collective
646: Input Parameter:
647: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
649: Output Parameter:
650: . file - file pointer Always returns NULL if not a binary viewer
652: Level: advanced
654: Notes:
655: For writable binary PetscViewers, the descriptor will only be valid for the
656: first processor in the communicator that shares the PetscViewer.
658: Fortran Note:
659: This routine is not supported in Fortran.
661: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
662: @*/
663: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
664: {
668: *file = NULL;
669: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
670: return(0);
671: }
673: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
674: {
675: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
676: PetscErrorCode ierr;
677: PetscMPIInt rank;
678: int err;
681: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
682: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
683: close(vbinary->fdes);
684: if (!rank && vbinary->storecompressed) {
685: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
686: FILE *fp;
687: /* compress the file */
688: PetscStrncpy(par,"gzip -f ",sizeof(par));
689: PetscStrlcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename,sizeof(par));
690: PetscFree(vbinary->ogzfilename);
691: #if defined(PETSC_HAVE_POPEN)
692: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
693: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
694: PetscPClose(PETSC_COMM_SELF,fp);
695: #else
696: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
697: #endif
698: }
699: }
700: if (vbinary->fdes_info) {
701: err = fclose(vbinary->fdes_info);
702: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
703: }
704: return(0);
705: }
707: #if defined(PETSC_HAVE_MPIIO)
708: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
709: {
710: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
711: int err;
712: PetscErrorCode ierr;
715: if (vbinary->mfdes != MPI_FILE_NULL) {
716: MPI_File_close(&vbinary->mfdes);
717: }
718: if (vbinary->mfsub != MPI_FILE_NULL) {
719: MPI_File_close(&vbinary->mfsub);
720: }
721: if (vbinary->fdes_info) {
722: err = fclose(vbinary->fdes_info);
723: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
724: }
725: return(0);
726: }
727: #endif
729: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
730: {
731: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
732: PetscErrorCode ierr;
735: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
736: MPI_Comm comm;
737: FILE *info;
739: PetscObjectGetComm((PetscObject)v,&comm);
740: PetscViewerBinaryGetInfoPointer(v,&info);
741: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
742: PetscFPrintf(comm,info,"#$$ close(fd);\n");
743: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
744: }
745: #if defined(PETSC_HAVE_MPIIO)
746: if (vbinary->usempiio) {
747: PetscViewerFileClose_BinaryMPIIO(v);
748: } else {
749: #endif
750: PetscViewerFileClose_Binary(v);
751: #if defined(PETSC_HAVE_MPIIO)
752: }
753: #endif
754: PetscFree(vbinary->filename);
755: PetscFree(vbinary->ogzfilename);
756: PetscFree(vbinary);
757: return(0);
758: }
760: /*@C
761: PetscViewerBinaryOpen - Opens a file for binary input/output.
763: Collective
765: Input Parameters:
766: + comm - MPI communicator
767: . name - name of file
768: - type - type of file
769: $ FILE_MODE_WRITE - create new file for binary output
770: $ FILE_MODE_READ - open existing file for binary input
771: $ FILE_MODE_APPEND - open existing file for binary output
773: Output Parameter:
774: . binv - PetscViewer for binary input/output to use with the specified file
776: Options Database Keys:
777: + -viewer_binary_filename <name> -
778: . -viewer_binary_skip_info -
779: . -viewer_binary_skip_options -
780: . -viewer_binary_skip_header -
781: - -viewer_binary_mpiio -
783: Level: beginner
785: Note:
786: This PetscViewer should be destroyed with PetscViewerDestroy().
788: For reading files, the filename may begin with ftp:// or http:// and/or
789: end with .gz; in this case file is brought over and uncompressed.
791: For creating files, if the file name ends with .gz it is automatically
792: compressed when closed.
794: For writing files it only opens the file on processor 0 in the communicator.
795: For readable files it opens the file on all nodes that have the file. If
796: node 0 does not have the file it generates an error even if other nodes
797: do have the file.
799: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
800: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
801: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
802: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
803: @*/
804: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
805: {
809: PetscViewerCreate(comm,binv);
810: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
811: PetscViewerFileSetMode(*binv,type);
812: PetscViewerFileSetName(*binv,name);
813: PetscViewerSetFromOptions(*binv);
814: return(0);
815: }
817: #if defined(PETSC_HAVE_MPIIO)
818: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
819: {
820: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
821: PetscErrorCode ierr;
822: MPI_File mfdes;
823: MPI_Datatype mdtype;
824: PetscMPIInt cnt;
825: MPI_Status status;
826: MPI_Aint ul,dsize;
829: mfdes = vbinary->mfdes;
830: PetscMPIIntCast(num,&cnt);
831: PetscDataTypeToMPIDataType(dtype,&mdtype);
832: MPI_File_set_view(mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
833: if (write) {
834: MPIU_File_write_all(mfdes,data,cnt,mdtype,&status);
835: } else {
836: MPIU_File_read_all(mfdes,data,cnt,mdtype,&status);
837: if (cnt > 0) {MPI_Get_count(&status,mdtype,&cnt);}
838: }
839: MPI_Type_get_extent(mdtype,&ul,&dsize);
841: vbinary->moff += dsize*cnt;
842: if (count) *count = cnt;
843: return(0);
844: }
845: #endif
847: /*@C
848: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
850: Collective
852: Input Parameters:
853: + viewer - the binary viewer
854: . data - location of the data to be written
855: . num - number of items of data to read
856: - dtype - type of data to read
858: Output Parameters:
859: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
861: Level: beginner
863: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
865: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
866: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
867: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
868: @*/
869: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
870: {
871: PetscErrorCode ierr;
872: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
874: PetscViewerSetUp(viewer);
875: #if defined(PETSC_HAVE_MPIIO)
876: if (vbinary->usempiio) {
877: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
878: } else {
879: #endif
880: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);
881: #if defined(PETSC_HAVE_MPIIO)
882: }
883: #endif
884: return(0);
885: }
887: /*@C
888: PetscViewerBinaryWrite - writes to a binary file, only from the first process
890: Collective
892: Input Parameters:
893: + viewer - the binary viewer
894: . data - location of data
895: . count - number of items of data to write
896: . dtype - type of data to write
897: - istemp - data may be overwritten
899: Level: beginner
901: Notes:
902: because byte-swapping may be done on the values in data it cannot be declared const
904: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
905: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
906: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
907: @*/
908: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
909: {
910: PetscErrorCode ierr;
911: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
914: PetscViewerSetUp(viewer);
915: #if defined(PETSC_HAVE_MPIIO)
916: if (vbinary->usempiio) {
917: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
918: } else {
919: #endif
920: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
921: #if defined(PETSC_HAVE_MPIIO)
922: }
923: #endif
924: return(0);
925: }
927: /*@C
928: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
930: Collective
932: Input Parameters:
933: + viewer - the binary viewer
934: - data - location of the array of strings
937: Level: intermediate
939: Notes:
940: array of strings is null terminated
942: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
943: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
944: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
945: @*/
946: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
947: {
949: PetscInt i,n = 0,*sizes;
951: PetscViewerSetUp(viewer);
952: /* count number of strings */
953: while (data[n++]) ;
954: n--;
955: PetscMalloc1(n+1,&sizes);
956: sizes[0] = n;
957: for (i=0; i<n; i++) {
958: size_t tmp;
959: PetscStrlen(data[i],&tmp);
960: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
961: }
962: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
963: for (i=0; i<n; i++) {
964: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
965: }
966: PetscFree(sizes);
967: return(0);
968: }
970: /*@C
971: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
973: Collective
975: Input Parameter:
976: . viewer - the binary viewer
978: Output Parameter:
979: . data - location of the array of strings
981: Level: intermediate
983: Notes:
984: array of strings is null terminated
986: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
987: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
988: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
989: @*/
990: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
991: {
993: PetscInt i,n,*sizes,N = 0;
995: PetscViewerSetUp(viewer);
996: /* count number of strings */
997: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
998: PetscMalloc1(n,&sizes);
999: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1000: for (i=0; i<n; i++) N += sizes[i];
1001: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1002: (*data)[0] = (char*)((*data) + n + 1);
1003: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1004: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1006: (*data)[n] = 0;
1008: PetscFree(sizes);
1009: return(0);
1010: }
1012: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1013: {
1014: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1017: *name = vbinary->filename;
1018: return(0);
1019: }
1021: /*@C
1022: PetscViewerFileGetMode - Gets the type of file to be open
1024: Not Collective
1026: Input Parameter:
1027: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1029: Output Parameter:
1030: . type - type of file
1031: $ FILE_MODE_WRITE - create new file for binary output
1032: $ FILE_MODE_READ - open existing file for binary input
1033: $ FILE_MODE_APPEND - open existing file for binary output
1035: Level: advanced
1037: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1039: @*/
1040: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1041: {
1047: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1048: return(0);
1049: }
1051: /*@
1052: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1053: before PetscViewerFileSetName()
1055: Logically Collective on PetscViewer
1057: Input Parameters:
1058: + viewer - the PetscViewer; must be a binary
1059: - flg - PETSC_TRUE means MPI-IO will be used
1061: Options Database:
1062: -viewer_binary_mpiio : Flag for using MPI-IO
1064: Level: advanced
1066: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1067: PetscViewerBinaryGetUseMPIIO()
1069: @*/
1070: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1071: {
1076: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1077: return(0);
1078: }
1080: /*@C
1081: PetscViewerFileSetMode - Sets the type of file to be open
1083: Logically Collective on PetscViewer
1085: Input Parameters:
1086: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1087: - type - type of file
1088: $ FILE_MODE_WRITE - create new file for output
1089: $ FILE_MODE_READ - open existing file for input
1090: $ FILE_MODE_APPEND - open existing file for output
1092: Level: advanced
1094: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1096: @*/
1097: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1098: {
1104: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1105: return(0);
1106: }
1108: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1109: {
1110: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1113: *type = vbinary->btype;
1114: return(0);
1115: }
1117: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1118: {
1119: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1122: vbinary->btype = type;
1123: return(0);
1124: }
1126: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1127: {
1128: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1129: PetscErrorCode ierr;
1132: if (vbinary->filename) {
1133: /* gzip can be run after the file with the previous filename has been closed */
1134: PetscFree(vbinary->ogzfilename);
1135: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1136: PetscFree(vbinary->filename);
1137: viewer->setupcalled = PETSC_FALSE;
1138: }
1139: PetscStrallocpy(name,&vbinary->filename);
1140: return(0);
1141: }
1142: /*
1143: Actually opens the file
1144: */
1145: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1146: {
1147: PetscMPIInt rank;
1148: PetscErrorCode ierr;
1149: size_t len;
1150: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1151: const char *fname;
1152: char bname[PETSC_MAX_PATH_LEN],*gz;
1153: PetscBool found;
1154: PetscFileMode type = vbinary->btype;
1157: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1158: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1159: PetscViewerFileClose_Binary(viewer);
1161: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1163: /* if ends in .gz strip that off and note user wants file compressed */
1164: vbinary->storecompressed = PETSC_FALSE;
1165: if (!rank && type == FILE_MODE_WRITE) {
1166: /* remove .gz if it ends library name */
1167: PetscStrstr(vbinary->filename,".gz",&gz);
1168: if (gz) {
1169: PetscStrlen(gz,&len);
1170: if (len == 3) {
1171: *gz = 0;
1172: vbinary->storecompressed = PETSC_TRUE;
1173: }
1174: }
1175: }
1177: /* only first processor opens file if writeable */
1178: if (!rank || type == FILE_MODE_READ) {
1180: if (type == FILE_MODE_READ) {
1181: /* possibly get the file from remote site or compressed file */
1182: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1183: fname = bname;
1184: /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */
1185: if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1186: } else fname = vbinary->filename;
1187: if (type == FILE_MODE_APPEND) { /* check if asked to append to a non-existing file */
1188: PetscTestFile(fname,'\0',&found);
1189: }
1191: #if defined(PETSC_HAVE_O_BINARY)
1192: if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) {
1193: 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);
1194: } else if (type == FILE_MODE_READ && fname) {
1195: 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);
1196: } else if (type == FILE_MODE_APPEND) {
1197: 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);
1198: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1199: #else
1200: if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) {
1201: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1202: } else if (type == FILE_MODE_READ && fname) {
1203: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1204: } else if (type == FILE_MODE_APPEND) {
1205: 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);
1206: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1207: #endif
1208: } else vbinary->fdes = -1;
1210: /*
1211: try to open info file: all processors open this file if read only
1212: */
1213: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1214: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1216: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1217: /* remove .gz if it ends library name */
1218: PetscStrstr(infoname,".gz",&gz);
1219: if (gz) {
1220: PetscStrlen(gz,&len);
1221: if (len == 3) *gz = 0;
1222: }
1224: PetscStrlcat(infoname,".info",sizeof(infoname));
1225: PetscFixFilename(infoname,iname);
1226: if (type == FILE_MODE_READ) {
1227: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1228: if (found) {
1229: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1230: }
1231: } else {
1232: vbinary->fdes_info = fopen(infoname,"w");
1233: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1234: }
1235: }
1236: #if defined(PETSC_USE_LOG)
1237: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1238: #endif
1239: return(0);
1240: }
1242: #if defined(PETSC_HAVE_MPIIO)
1243: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1244: {
1245: PetscMPIInt rank;
1246: PetscErrorCode ierr;
1247: size_t len;
1248: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1249: char *gz;
1250: PetscBool found;
1251: PetscFileMode type = vbinary->btype;
1252: int amode;
1255: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1256: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1257: PetscViewerFileClose_BinaryMPIIO(viewer);
1259: vbinary->storecompressed = PETSC_FALSE;
1261: switch (type) {
1262: case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1263: case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1264: default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]);
1265: }
1266: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);
1268: /*
1269: try to open info file: all processors open this file if read only
1271: Below is identical code to the code for Binary above, should be put in separate routine
1272: */
1273: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1274: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1275: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1277: PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));
1278: /* remove .gz if it ends library name */
1279: PetscStrstr(infoname,".gz",&gz);
1280: if (gz) {
1281: PetscStrlen(gz,&len);
1282: if (len == 3) *gz = 0;
1283: }
1285: PetscStrlcat(infoname,".info",sizeof(infoname));
1286: PetscFixFilename(infoname,iname);
1287: if (type == FILE_MODE_READ) {
1288: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1289: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1290: } else {
1291: vbinary->fdes_info = fopen(infoname,"w");
1292: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1293: }
1294: }
1295: #if defined(PETSC_USE_LOG)
1296: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1297: #endif
1298: return(0);
1299: }
1301: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1302: {
1303: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1305: vbinary->usempiio = flg;
1306: return(0);
1307: }
1308: #endif
1310: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1311: {
1312: PetscErrorCode ierr;
1313: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1316: if (binary->filename) {
1317: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1318: }
1319: return(0);
1320: }
1322: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1323: {
1324: PetscErrorCode ierr;
1325: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1328: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1329:
1330: #if defined(PETSC_HAVE_MPIIO)
1331: if (binary->usempiio) {
1332: PetscViewerFileSetUp_BinaryMPIIO(v);
1333: } else {
1334: #endif
1335: PetscViewerFileSetUp_Binary(v);
1336: #if defined(PETSC_HAVE_MPIIO)
1337: }
1338: #endif
1339: return(0);
1340: }
1342: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1343: {
1344: PetscErrorCode ierr;
1345: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1346: char defaultname[PETSC_MAX_PATH_LEN];
1347: PetscBool flg;
1350: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1351: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1352: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1353: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1354: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1355: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1356: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1357: #if defined(PETSC_HAVE_MPIIO)
1358: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1359: #elif defined(PETSC_HAVE_MPIUNI)
1360: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1361: #endif
1362: PetscOptionsTail();
1363: binary->setfromoptionscalled = PETSC_TRUE;
1364: return(0);
1365: }
1367: /*MC
1368: PETSCVIEWERBINARY - A viewer that saves to binary files
1371: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1372: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1373: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1374: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1376: Level: beginner
1378: M*/
1380: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1381: {
1382: PetscErrorCode ierr;
1383: PetscViewer_Binary *vbinary;
1386: PetscNewLog(v,&vbinary);
1387: v->data = (void*)vbinary;
1388: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1389: v->ops->destroy = PetscViewerDestroy_Binary;
1390: v->ops->view = PetscViewerView_Binary;
1391: v->ops->setup = PetscViewerSetUp_Binary;
1392: v->ops->flush = NULL;
1393: vbinary->fdes = 0;
1394: #if defined(PETSC_HAVE_MPIIO)
1395: vbinary->mfdes = MPI_FILE_NULL;
1396: vbinary->mfsub = MPI_FILE_NULL;
1397: #endif
1398: vbinary->fdes_info = 0;
1399: vbinary->skipinfo = PETSC_FALSE;
1400: vbinary->skipoptions = PETSC_TRUE;
1401: vbinary->skipheader = PETSC_FALSE;
1402: vbinary->setfromoptionscalled = PETSC_FALSE;
1403: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1404: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1405: v->ops->read = PetscViewerBinaryRead;
1406: vbinary->btype = (PetscFileMode) -1;
1407: vbinary->storecompressed = PETSC_FALSE;
1408: vbinary->filename = NULL;
1409: vbinary->ogzfilename = NULL;
1410: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1412: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1413: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1414: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1415: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1416: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1417: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1418: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1419: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1420: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1421: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1422: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1423: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1424: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1425: #if defined(PETSC_HAVE_MPIIO)
1426: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1427: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1428: #endif
1429: return(0);
1430: }
1432: /* ---------------------------------------------------------------------*/
1433: /*
1434: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1435: is attached to a communicator, in this case the attribute is a PetscViewer.
1436: */
1437: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1439: /*@C
1440: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1441: in a communicator.
1443: Collective
1445: Input Parameter:
1446: . comm - the MPI communicator to share the binary PetscViewer
1448: Level: intermediate
1450: Options Database Keys:
1451: + -viewer_binary_filename <name>
1452: . -viewer_binary_skip_info
1453: . -viewer_binary_skip_options
1454: . -viewer_binary_skip_header
1455: - -viewer_binary_mpiio
1457: Environmental variables:
1458: - PETSC_VIEWER_BINARY_FILENAME
1460: Notes:
1461: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1462: an error code. The binary PetscViewer is usually used in the form
1463: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1465: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1466: PetscViewerDestroy()
1467: @*/
1468: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1469: {
1471: PetscBool flg;
1472: PetscViewer viewer;
1473: char fname[PETSC_MAX_PATH_LEN];
1474: MPI_Comm ncomm;
1477: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1478: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1479: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1480: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1481: }
1482: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1483: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1484: if (!flg) { /* PetscViewer not yet created */
1485: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1486: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1487: if (!flg) {
1488: PetscStrcpy(fname,"binaryoutput");
1489: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1490: }
1491: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1492: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1493: PetscObjectRegisterDestroy((PetscObject)viewer);
1494: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1495: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1496: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1497: }
1498: PetscCommDestroy(&ncomm);
1499: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1500: PetscFunctionReturn(viewer);
1501: }