Actual source code: binv.c
petsc-3.7.7 2017-09-25
2: #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
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_Offset moff;
17: #endif
18: PetscFileMode btype; /* read or write? */
19: FILE *fdes_info; /* optional file containing info on binary file*/
20: PetscBool storecompressed; /* gzip the write binary file when closing it*/
21: char *filename;
22: PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */
23: PetscBool skipoptions; /* don't use PETSc options database when loading */
24: PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
25: PetscBool skipheader; /* don't write header, only raw data */
26: PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
27: PetscBool setfromoptionscalled;
28: } 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,*obinary;
39: PetscViewerSetUp(viewer);
40: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
41: if (!rank) {
42: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
43: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
44: obinary = (PetscViewer_Binary*)(*outviewer)->data;
45: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
46: } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get subcomm viewer for binary files or sockets unless SubViewer contains the rank 0 process");
47: return(0);
48: }
52: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
53: {
55: PetscErrorCode rank;
58: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
59: if (!rank) {
60: PetscFree((*outviewer)->data);
61: PetscHeaderDestroy(outviewer);
62: }
63: return(0);
64: }
66: #if defined(PETSC_HAVE_MPIIO)
69: /*@C
70: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
72: Not Collective
74: Input Parameter:
75: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
77: Output Parameter:
78: . off - the current offset
80: Level: advanced
82: Fortran Note:
83: This routine is not supported in Fortran.
85: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
87: Concepts: file descriptor^getting
88: Concepts: PetscViewerBinary^accessing file descriptor
90: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
91: @*/
92: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
93: {
94: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
97: *off = vbinary->moff;
98: return(0);
99: }
103: /*@C
104: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
106: Not Collective
108: Input Parameters:
109: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
110: - off - the addition to the offset
112: Level: advanced
114: Fortran Note:
115: This routine is not supported in Fortran.
117: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
119: Concepts: file descriptor^getting
120: Concepts: PetscViewerBinary^accessing file descriptor
122: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
123: @*/
124: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
125: {
126: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
129: vbinary->moff += off;
130: return(0);
131: }
135: /*@C
136: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
138: Not Collective
140: Input Parameter:
141: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
143: Output Parameter:
144: . fdes - file descriptor
146: Level: advanced
148: Fortran Note:
149: This routine is not supported in Fortran.
151: Concepts: file descriptor^getting
152: Concepts: PetscViewerBinary^accessing file descriptor
154: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
155: @*/
156: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
157: {
158: PetscErrorCode ierr;
159: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
162: PetscViewerSetUp(viewer);
163: *fdes = vbinary->mfdes;
164: return(0);
165: }
169: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg)
170: {
171: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
172:
174: *flg = vbinary->usempiio;
175: return(0);
176: }
177: #endif
182: /*@C
183: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
185: Not Collective
187: Input Parameter:
188: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
190: Output Parameter:
191: - flg - PETSC_TRUE if MPI-IO is being used
193: Options Database:
194: -viewer_binary_mpiio : Flag for using MPI-IO
196: Level: advanced
198: Note:
199: If MPI-IO is not available, this function will always return PETSC_FALSE
201: Fortran Note:
202: This routine is not supported in Fortran.
204: Concepts: file descriptor^getting
205: Concepts: PetscViewerBinary^accessing file descriptor
207: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer()
208: @*/
209: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
210: {
214: *flg = PETSC_FALSE;
215: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
216: return(0);
217: }
221: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
222: {
223: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
226: *fc = vbinary->flowcontrol;
227: return(0);
228: }
232: /*@C
233: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
235: Not Collective
237: Input Parameter:
238: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
240: Output Parameter:
241: . fc - the number of messages
243: Level: advanced
245: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
247: @*/
248: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
249: {
253: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
254: return(0);
255: }
259: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
260: {
261: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
264: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
265: vbinary->flowcontrol = fc;
266: return(0);
267: }
271: /*@C
272: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
274: Not Collective
276: Input Parameter:
277: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
278: - fc - the number of messages, defaults to 256 if this function was not called
280: Level: advanced
282: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
284: @*/
285: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
286: {
290: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
291: return(0);
292: }
296: /*@C
297: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
299: Collective On PetscViewer
301: Input Parameter:
302: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
304: Output Parameter:
305: . fdes - file descriptor
307: Level: advanced
309: Notes:
310: For writable binary PetscViewers, the descriptor will only be valid for the
311: first processor in the communicator that shares the PetscViewer. For readable
312: files it will only be valid on nodes that have the file. If node 0 does not
313: have the file it generates an error even if another node does have the file.
315: Fortran Note:
316: This routine is not supported in Fortran.
318: Developer Notes: This must be called on all processes because Dave May changed
319: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
322: Concepts: file descriptor^getting
323: Concepts: PetscViewerBinary^accessing file descriptor
325: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
326: @*/
327: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
328: {
329: PetscErrorCode ierr;
330: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
333: PetscViewerSetUp(viewer);
334: *fdes = vbinary->fdes;
335: return(0);
336: }
340: /*@
341: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
343: Not Collective
345: Input Paramter:
346: . viewer - PetscViewer context, obtained from PetscViewerCreate()
348: Options Database Key:
349: . -viewer_binary_skip_info
351: Level: advanced
353: Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
354: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
355: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
357: The .info contains meta information about the data in the binary file, for example the block size if it was
358: set for a vector or matrix.
360: Concepts: PetscViewerBinary^accessing info file
362: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
363: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
364: @*/
365: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
366: {
367: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
370: vbinary->skipinfo = PETSC_TRUE;
371: return(0);
372: }
376: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
377: {
378: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
381: vbinary->skipinfo = skip;
382: return(0);
383: }
387: /*@
388: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
390: Not Collective
392: Input Paramter:
393: . viewer - PetscViewer context, obtained from PetscViewerCreate()
395: Options Database Key:
396: . -viewer_binary_skip_info
398: Level: advanced
400: Concepts: PetscViewerBinary^accessing info file
402: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
403: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
404: @*/
405: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
406: {
410: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
411: return(0);
412: }
416: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
417: {
418: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
421: *skip = vbinary->skipinfo;
422: return(0);
423: }
427: /*@
428: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
430: Not Collective
432: Input Parameter:
433: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
435: Output Parameter:
436: . skip - PETSC_TRUE implies the .info file was not generated
438: Level: advanced
440: Notes: This must be called after PetscViewerSetType()
442: Concepts: PetscViewerBinary^accessing info file
444: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
445: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
446: @*/
447: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
448: {
452: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
453: return(0);
454: }
458: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
459: {
460: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
463: vbinary->skipoptions = skip;
464: return(0);
465: }
469: /*@
470: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
472: Not Collective
474: Input Parameters:
475: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
476: - skip - PETSC_TRUE means do not use
478: Options Database Key:
479: . -viewer_binary_skip_options
481: Level: advanced
483: Notes: This must be called after PetscViewerSetType()
485: Concepts: PetscViewerBinary^accessing info file
487: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
488: PetscViewerBinaryGetSkipOptions()
489: @*/
490: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
491: {
495: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
496: return(0);
497: }
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: }
514: /*@
515: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
517: Not Collective
519: Input Parameter:
520: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
522: Output Parameter:
523: . skip - PETSC_TRUE means do not use
525: Level: advanced
527: Notes: This must be called after PetscViewerSetType()
529: Concepts: PetscViewerBinary^accessing info file
531: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
532: PetscViewerBinarySetSkipOptions()
533: @*/
534: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
535: {
539: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
540: return(0);
541: }
545: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
546: {
547: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
550: vbinary->skipheader = skip;
551: return(0);
552: }
556: /*@
557: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
559: Not Collective
561: Input Parameters:
562: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
563: - skip - PETSC_TRUE means do not write header
565: Options Database Key:
566: . -viewer_binary_skip_header
568: Level: advanced
570: Notes: This must be called after PetscViewerSetType()
572: Can ONLY be called on a binary viewer
574: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
575: PetscViewerBinaryGetSkipHeader()
576: @*/
577: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
578: {
582: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
583: return(0);
584: }
588: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
589: {
590: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
593: *skip = vbinary->skipheader;
594: return(0);
595: }
599: /*@
600: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
602: Not Collective
604: Input Parameter:
605: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
607: Output Parameter:
608: . skip - PETSC_TRUE means do not write header
610: Level: advanced
612: Notes: This must be called after PetscViewerSetType()
614: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
616: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
617: PetscViewerBinarySetSkipHeader()
618: @*/
619: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
620: {
624: *skip = PETSC_FALSE;
625: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
626: return(0);
627: }
631: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
632: {
633: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
634: PetscErrorCode ierr;
635: MPI_Comm comm;
638: PetscViewerSetUp(viewer);
639: *file = vbinary->fdes_info;
640: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
641: vbinary->matlabheaderwritten = PETSC_TRUE;
642: PetscObjectGetComm((PetscObject)viewer,&comm);
643: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
644: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
645: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
646: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
647: }
648: return(0);
649: }
653: /*@C
654: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
655: info file associated with a binary file.
657: Not Collective
659: Input Parameter:
660: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
662: Output Parameter:
663: . file - file pointer Always returns NULL if not a binary viewer
665: Level: advanced
667: Notes:
668: For writable binary PetscViewers, the descriptor will only be valid for the
669: first processor in the communicator that shares the PetscViewer.
671: Fortran Note:
672: This routine is not supported in Fortran.
674: Concepts: PetscViewerBinary^accessing info file
676: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
677: @*/
678: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
679: {
683: *file = NULL;
684: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
685: return(0);
686: }
690: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
691: {
692: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
693: PetscErrorCode ierr;
694: PetscMPIInt rank;
695: int err;
698: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
699: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
700: close(vbinary->fdes);
701: if (!rank && vbinary->storecompressed) {
702: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
703: FILE *fp;
704: /* compress the file */
705: PetscStrcpy(par,"gzip -f ");
706: PetscStrcat(par,vbinary->filename);
707: #if defined(PETSC_HAVE_POPEN)
708: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
709: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
710: PetscPClose(PETSC_COMM_SELF,fp,NULL);
711: #else
712: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
713: #endif
714: }
715: }
716: if (vbinary->fdes_info) {
717: err = fclose(vbinary->fdes_info);
718: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
719: }
720: return(0);
721: }
723: #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) {
734: MPI_File_close(&vbinary->mfdes);
735: }
736: if (vbinary->fdes_info) {
737: err = fclose(vbinary->fdes_info);
738: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
739: }
740: return(0);
741: }
742: #endif
746: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
747: {
748: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
749: PetscErrorCode ierr;
752: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
753: MPI_Comm comm;
754: FILE *info;
756: PetscObjectGetComm((PetscObject)v,&comm);
757: PetscViewerBinaryGetInfoPointer(v,&info);
758: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
759: PetscFPrintf(comm,info,"#$$ close(fd);\n");
760: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
761: }
762: #if defined(PETSC_HAVE_MPIIO)
763: if (vbinary->usempiio) {
764: PetscViewerFileClose_BinaryMPIIO(v);
765: } else {
766: #endif
767: PetscViewerFileClose_Binary(v);
768: #if defined(PETSC_HAVE_MPIIO)
769: }
770: #endif
771: if (vbinary->filename) { PetscFree(vbinary->filename); }
772: PetscFree(vbinary);
773: return(0);
774: }
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()
826: @*/
827: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
828: {
832: PetscViewerCreate(comm,binv);
833: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
834: PetscViewerFileSetMode(*binv,type);
835: PetscViewerFileSetName(*binv,name);
836: PetscViewerSetFromOptions(*binv);
837: return(0);
838: }
840: #if defined(PETSC_HAVE_MPIIO)
843: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
844: {
845: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
846: PetscErrorCode ierr;
847: MPI_Datatype mdtype;
848: PetscMPIInt cnt;
849: MPI_Status status;
850: MPI_Aint ul,dsize;
853: PetscMPIIntCast(num,&cnt);
854: PetscDataTypeToMPIDataType(dtype,&mdtype);
855: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
856: if (write) {
857: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
858: } else {
859: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
860: }
861: MPI_Type_get_extent(mdtype,&ul,&dsize);
863: vbinary->moff += dsize*cnt;
864: if (count) *count = num;
865: return(0);
866: }
867: #endif
871: /*@C
872: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
874: Collective on MPI_Comm
876: Input Parameters:
877: + viewer - the binary viewer
878: . data - location of the data to be written
879: . num - number of items of data to read
880: - dtype - type of data to read
882: Output Parameters:
883: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
885: Level: beginner
887: Concepts: binary files
889: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
891: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
892: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
893: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
894: @*/
895: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
896: {
897: PetscErrorCode ierr;
898: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
900: PetscViewerSetUp(viewer);
901: #if defined(PETSC_HAVE_MPIIO)
902: if (vbinary->usempiio) {
903: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
904: } else {
905: #endif
906: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
907: if (count) *count = num;
908: #if defined(PETSC_HAVE_MPIIO)
909: }
910: #endif
911: return(0);
912: }
916: /*@C
917: PetscViewerBinaryWrite - writes to a binary file, only from the first process
919: Collective on MPI_Comm
921: Input Parameters:
922: + viewer - the binary viewer
923: . data - location of data
924: . count - number of items of data to write
925: . dtype - type of data to write
926: - istemp - data may be overwritten
928: Level: beginner
930: Notes: because byte-swapping may be done on the values in data it cannot be declared const
932: Concepts: binary files
934: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
935: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
936: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
937: @*/
938: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
939: {
940: PetscErrorCode ierr;
941: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
944: PetscViewerSetUp(viewer);
945: #if defined(PETSC_HAVE_MPIIO)
946: if (vbinary->usempiio) {
947: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
948: } else {
949: #endif
950: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
951: #if defined(PETSC_HAVE_MPIIO)
952: }
953: #endif
954: return(0);
955: }
959: /*@C
960: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
962: Collective on MPI_Comm
964: Input Parameters:
965: + viewer - the binary viewer
966: - data - location of the array of strings
969: Level: intermediate
971: Concepts: binary files
973: Notes: array of strings is null terminated
975: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
976: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
977: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
978: @*/
979: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data)
980: {
982: PetscInt i,n = 0,*sizes;
984: PetscViewerSetUp(viewer);
985: /* count number of strings */
986: while (data[n++]) ;
987: n--;
988: PetscMalloc1(n+1,&sizes);
989: sizes[0] = n;
990: for (i=0; i<n; i++) {
991: size_t tmp;
992: PetscStrlen(data[i],&tmp);
993: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
994: }
995: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
996: for (i=0; i<n; i++) {
997: PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
998: }
999: PetscFree(sizes);
1000: return(0);
1001: }
1005: /*@C
1006: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1008: Collective on MPI_Comm
1010: Input Parameter:
1011: . viewer - the binary viewer
1013: Output Parameter:
1014: . data - location of the array of strings
1016: Level: intermediate
1018: Concepts: binary files
1020: Notes: array of strings is null terminated
1022: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1023: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1024: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1025: @*/
1026: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1027: {
1029: PetscInt i,n,*sizes,N = 0;
1031: PetscViewerSetUp(viewer);
1032: /* count number of strings */
1033: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
1034: PetscMalloc1(n,&sizes);
1035: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
1036: for (i=0; i<n; i++) N += sizes[i];
1037: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
1038: (*data)[0] = (char*)((*data) + n + 1);
1039: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1040: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
1042: (*data)[n] = 0;
1044: PetscFree(sizes);
1045: return(0);
1046: }
1050: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1051: {
1052: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1055: *name = vbinary->filename;
1056: return(0);
1057: }
1061: /*@C
1062: PetscViewerFileGetMode - Gets the type of file to be open
1064: Not Collective
1066: Input Parameter:
1067: . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer
1069: Output Parameter:
1070: . type - type of file
1071: $ FILE_MODE_WRITE - create new file for binary output
1072: $ FILE_MODE_READ - open existing file for binary input
1073: $ FILE_MODE_APPEND - open existing file for binary output
1075: Level: advanced
1077: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1079: @*/
1080: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1081: {
1087: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1088: return(0);
1089: }
1093: /*@
1094: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1095: before PetscViewerFileSetName()
1097: Logically Collective on PetscViewer
1099: Input Parameters:
1100: + viewer - the PetscViewer; must be a binary
1101: - flg - PETSC_TRUE means MPI-IO will be used
1103: Options Database:
1104: -viewer_binary_mpiio : Flag for using MPI-IO
1106: Level: advanced
1108: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1109: PetscViewerBinaryGetUseMPIIO()
1111: @*/
1112: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1113: {
1118: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1119: return(0);
1120: }
1124: /*@C
1125: PetscViewerFileSetMode - Sets the type of file to be open
1127: Logically Collective on PetscViewer
1129: Input Parameters:
1130: + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer
1131: - type - type of file
1132: $ FILE_MODE_WRITE - create new file for binary output
1133: $ FILE_MODE_READ - open existing file for binary input
1134: $ FILE_MODE_APPEND - open existing file for binary output
1136: Level: advanced
1138: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1140: @*/
1141: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1142: {
1148: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1149: return(0);
1150: }
1154: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1155: {
1156: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1159: *type = vbinary->btype;
1160: return(0);
1161: }
1165: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1166: {
1167: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1170: vbinary->btype = type;
1171: return(0);
1172: }
1176: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1177: {
1178: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1179: PetscErrorCode ierr;
1180:
1182: if (vbinary->filename) { PetscFree(vbinary->filename); }
1183: PetscStrallocpy(name,&vbinary->filename);
1184: return(0);
1185: }
1186: /*
1187: Actually opens the file
1188: */
1191: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1192: {
1193: PetscMPIInt rank;
1194: PetscErrorCode ierr;
1195: size_t len;
1196: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1197: const char *fname;
1198: char bname[PETSC_MAX_PATH_LEN],*gz;
1199: PetscBool found;
1200: PetscFileMode type = vbinary->btype;
1203: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1204: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1205: PetscViewerFileClose_Binary(viewer);
1207: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1209: /* if ends in .gz strip that off and note user wants file compressed */
1210: vbinary->storecompressed = PETSC_FALSE;
1211: if (!rank && type == FILE_MODE_WRITE) {
1212: /* remove .gz if it ends library name */
1213: PetscStrstr(vbinary->filename,".gz",&gz);
1214: if (gz) {
1215: PetscStrlen(gz,&len);
1216: if (len == 3) {
1217: *gz = 0;
1218: vbinary->storecompressed = PETSC_TRUE;
1219: }
1220: }
1221: }
1223: /* only first processor opens file if writeable */
1224: if (!rank || type == FILE_MODE_READ) {
1226: if (type == FILE_MODE_READ) {
1227: /* possibly get the file from remote site or compressed file */
1228: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1229: fname = bname;
1230: if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1231: else if (!found) {
1232: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
1233: fname = 0;
1234: }
1235: } else fname = vbinary->filename;
1237: #if defined(PETSC_HAVE_O_BINARY)
1238: if (type == FILE_MODE_WRITE) {
1239: 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);
1240: } else if (type == FILE_MODE_READ && fname) {
1241: 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);
1242: } else if (type == FILE_MODE_APPEND) {
1243: 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);
1244: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1245: #else
1246: if (type == FILE_MODE_WRITE) {
1247: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1248: } else if (type == FILE_MODE_READ && fname) {
1249: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1250: } else if (type == FILE_MODE_APPEND) {
1251: 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);
1252: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1253: #endif
1254: } else vbinary->fdes = -1;
1256: /*
1257: try to open info file: all processors open this file if read only
1258: */
1259: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1260: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1262: PetscStrcpy(infoname,vbinary->filename);
1263: /* remove .gz if it ends library name */
1264: PetscStrstr(infoname,".gz",&gz);
1265: if (gz) {
1266: PetscStrlen(gz,&len);
1267: if (len == 3) *gz = 0;
1268: }
1270: PetscStrcat(infoname,".info");
1271: PetscFixFilename(infoname,iname);
1272: if (type == FILE_MODE_READ) {
1273: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1274: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1275: } else {
1276: vbinary->fdes_info = fopen(infoname,"w");
1277: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1278: }
1279: }
1280: #if defined(PETSC_USE_LOG)
1281: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1282: #endif
1283: return(0);
1284: }
1286: #if defined(PETSC_HAVE_MPIIO)
1289: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1290: {
1291: PetscMPIInt rank;
1292: PetscErrorCode ierr;
1293: size_t len;
1294: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1295: char *gz;
1296: PetscBool found;
1297: PetscFileMode type = vbinary->btype;
1300: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1301: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1302: PetscViewerFileClose_BinaryMPIIO(viewer);
1304: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1306: vbinary->storecompressed = PETSC_FALSE;
1308: /* only first processor opens file if writeable */
1309: if (type == FILE_MODE_READ) {
1310: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1311: } else if (type == FILE_MODE_WRITE) {
1312: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1313: }
1315: /*
1316: try to open info file: all processors open this file if read only
1318: Below is identical code to the code for Binary above, should be put in separate routine
1319: */
1320: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1321: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1323: PetscStrcpy(infoname,vbinary->filename);
1324: /* remove .gz if it ends library name */
1325: PetscStrstr(infoname,".gz",&gz);
1326: if (gz) {
1327: PetscStrlen(gz,&len);
1328: if (len == 3) *gz = 0;
1329: }
1331: PetscStrcat(infoname,".info");
1332: PetscFixFilename(infoname,iname);
1333: if (type == FILE_MODE_READ) {
1334: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1335: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1336: } else {
1337: vbinary->fdes_info = fopen(infoname,"w");
1338: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1339: }
1340: }
1341: #if defined(PETSC_USE_LOG)
1342: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1343: #endif
1344: return(0);
1345: }
1349: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1350: {
1351: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1353: vbinary->usempiio = flg;
1354: return(0);
1355: }
1356: #endif
1360: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1361: {
1362: PetscErrorCode ierr;
1363: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1366: if (binary->filename) {
1367: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1368: }
1369: return(0);
1370: }
1374: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1375: {
1376: PetscErrorCode ierr;
1377: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1380: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1381:
1382: #if defined(PETSC_HAVE_MPIIO)
1383: if (binary->usempiio) {
1384: PetscViewerFileSetUp_BinaryMPIIO(v);
1385: } else {
1386: #endif
1387: PetscViewerFileSetUp_Binary(v);
1388: #if defined(PETSC_HAVE_MPIIO)
1389: }
1390: #endif
1391: return(0);
1392: }
1396: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1397: {
1398: PetscErrorCode ierr;
1399: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1400: char defaultname[PETSC_MAX_PATH_LEN];
1401: PetscBool flg;
1404: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1405: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1406: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1407: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1408: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1409: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1410: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1411: #if defined(PETSC_HAVE_MPIIO)
1412: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1413: #elif defined(PETSC_HAVE_MPIUNI)
1414: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1415: #endif
1416: PetscOptionsTail();
1417: binary->setfromoptionscalled = PETSC_TRUE;
1418: return(0);
1419: }
1423: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1424: {
1425: PetscErrorCode ierr;
1426: PetscViewer_Binary *vbinary;
1429: PetscNewLog(v,&vbinary);
1430: v->data = (void*)vbinary;
1431: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1432: v->ops->destroy = PetscViewerDestroy_Binary;
1433: v->ops->view = PetscViewerView_Binary;
1434: v->ops->setup = PetscViewerSetUp_Binary;
1435: v->ops->flush = NULL;
1436: vbinary->fdes_info = 0;
1437: vbinary->fdes = 0;
1438: vbinary->skipinfo = PETSC_FALSE;
1439: vbinary->skipoptions = PETSC_TRUE;
1440: vbinary->skipheader = PETSC_FALSE;
1441: vbinary->setfromoptionscalled = PETSC_FALSE;
1442: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1443: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1444: v->ops->read = PetscViewerBinaryRead;
1445: vbinary->btype = (PetscFileMode) -1;
1446: vbinary->storecompressed = PETSC_FALSE;
1447: vbinary->filename = 0;
1448: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1450: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1451: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1452: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1453: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1454: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1455: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1456: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1457: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1458: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1459: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1460: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1461: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1462: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1463: #if defined(PETSC_HAVE_MPIIO)
1464: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1465: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1466: #endif
1467: return(0);
1468: }
1470: /* ---------------------------------------------------------------------*/
1471: /*
1472: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1473: is attached to a communicator, in this case the attribute is a PetscViewer.
1474: */
1475: static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1479: /*@C
1480: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1481: in a communicator.
1483: Collective on MPI_Comm
1485: Input Parameter:
1486: . comm - the MPI communicator to share the binary PetscViewer
1488: Level: intermediate
1490: Options Database Keys:
1491: + -viewer_binary_filename <name>
1492: . -viewer_binary_skip_info
1493: . -viewer_binary_skip_options
1494: . -viewer_binary_skip_header
1495: - -viewer_binary_mpiio
1497: Environmental variables:
1498: - PETSC_VIEWER_BINARY_FILENAME
1500: Notes:
1501: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1502: an error code. The binary PetscViewer is usually used in the form
1503: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1505: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1506: PetscViewerDestroy()
1507: @*/
1508: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1509: {
1511: PetscBool flg;
1512: PetscViewer viewer;
1513: char fname[PETSC_MAX_PATH_LEN];
1514: MPI_Comm ncomm;
1517: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1518: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1519: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1520: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1521: }
1522: MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1523: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1524: if (!flg) { /* PetscViewer not yet created */
1525: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1526: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1527: if (!flg) {
1528: PetscStrcpy(fname,"binaryoutput");
1529: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1530: }
1531: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1532: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1533: PetscObjectRegisterDestroy((PetscObject)viewer);
1534: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1535: MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1536: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1537: }
1538: PetscCommDestroy(&ncomm);
1539: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1540: PetscFunctionReturn(viewer);
1541: }