Actual source code: binv.c
petsc-3.8.4 2018-03-24
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_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: char *ogzfilename; /* gzip can be run after the filename has been updated */
23: PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */
24: PetscBool skipoptions; /* don't use PETSc options database when loading */
25: PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
26: PetscBool skipheader; /* don't write header, only raw data */
27: PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
28: PetscBool setfromoptionscalled;
29: } PetscViewer_Binary;
31: static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
32: {
33: int rank;
34: PetscErrorCode ierr;
35: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data,*obinary;
38: PetscViewerSetUp(viewer);
39: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
40: if (!rank) {
41: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
42: PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);
43: obinary = (PetscViewer_Binary*)(*outviewer)->data;
44: PetscMemcpy(obinary,vbinary,sizeof(PetscViewer_Binary));
45: } SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot get subcomm viewer for binary files or sockets unless SubViewer contains the rank 0 process");
46: return(0);
47: }
49: static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
50: {
52: PetscErrorCode rank;
55: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
56: if (!rank) {
57: PetscFree((*outviewer)->data);
58: PetscHeaderDestroy(outviewer);
59: }
60: return(0);
61: }
63: #if defined(PETSC_HAVE_MPIIO)
64: /*@C
65: PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view()
67: Not Collective
69: Input Parameter:
70: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
72: Output Parameter:
73: . off - the current offset
75: Level: advanced
77: Fortran Note:
78: This routine is not supported in Fortran.
80: Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
82: Concepts: file descriptor^getting
83: Concepts: PetscViewerBinary^accessing file descriptor
85: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
86: @*/
87: PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
88: {
89: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
92: *off = vbinary->moff;
93: return(0);
94: }
96: /*@C
97: PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view()
99: Not Collective
101: Input Parameters:
102: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
103: - off - the addition to the offset
105: Level: advanced
107: Fortran Note:
108: This routine is not supported in Fortran.
110: Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view()
112: Concepts: file descriptor^getting
113: Concepts: PetscViewerBinary^accessing file descriptor
115: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
116: @*/
117: PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
118: {
119: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
122: vbinary->moff += off;
123: return(0);
124: }
126: /*@C
127: PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
129: Not Collective
131: Input Parameter:
132: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
134: Output Parameter:
135: . fdes - file descriptor
137: Level: advanced
139: Fortran Note:
140: This routine is not supported in Fortran.
142: Concepts: file descriptor^getting
143: Concepts: PetscViewerBinary^accessing file descriptor
145: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
146: @*/
147: PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
148: {
149: PetscErrorCode ierr;
150: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
153: PetscViewerSetUp(viewer);
154: *fdes = vbinary->mfdes;
155: return(0);
156: }
158: static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg)
159: {
160: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
161:
163: *flg = vbinary->usempiio;
164: return(0);
165: }
166: #endif
169: /*@C
170: PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
172: Not Collective
174: Input Parameter:
175: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
177: Output Parameter:
178: - flg - PETSC_TRUE if MPI-IO is being used
180: Options Database:
181: -viewer_binary_mpiio : Flag for using MPI-IO
183: Level: advanced
185: Note:
186: If MPI-IO is not available, this function will always return PETSC_FALSE
188: Fortran Note:
189: This routine is not supported in Fortran.
191: Concepts: file descriptor^getting
192: Concepts: PetscViewerBinary^accessing file descriptor
194: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
195: @*/
196: PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg)
197: {
201: *flg = PETSC_FALSE;
202: PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));
203: return(0);
204: }
206: static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
207: {
208: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
211: *fc = vbinary->flowcontrol;
212: return(0);
213: }
215: /*@C
216: PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
218: Not Collective
220: Input Parameter:
221: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
223: Output Parameter:
224: . fc - the number of messages
226: Level: advanced
228: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
230: @*/
231: PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
232: {
236: PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));
237: return(0);
238: }
240: static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
241: {
242: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
245: if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
246: vbinary->flowcontrol = fc;
247: return(0);
248: }
250: /*@C
251: PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
253: Not Collective
255: Input Parameter:
256: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
257: - fc - the number of messages, defaults to 256 if this function was not called
259: Level: advanced
261: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
263: @*/
264: PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
265: {
269: PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));
270: return(0);
271: }
273: /*@C
274: PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
276: Collective On PetscViewer
278: Input Parameter:
279: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
281: Output Parameter:
282: . fdes - file descriptor
284: Level: advanced
286: Notes:
287: For writable binary PetscViewers, the descriptor will only be valid for the
288: first processor in the communicator that shares the PetscViewer. For readable
289: files it will only be valid on nodes that have the file. If node 0 does not
290: have the file it generates an error even if another node does have the file.
292: Fortran Note:
293: This routine is not supported in Fortran.
295: Developer Notes: This must be called on all processes because Dave May changed
296: the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
299: Concepts: file descriptor^getting
300: Concepts: PetscViewerBinary^accessing file descriptor
302: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
303: @*/
304: PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
305: {
306: PetscErrorCode ierr;
307: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
310: PetscViewerSetUp(viewer);
311: *fdes = vbinary->fdes;
312: return(0);
313: }
315: /*@
316: PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
318: Not Collective
320: Input Paramter:
321: . viewer - PetscViewer context, obtained from PetscViewerCreate()
323: Options Database Key:
324: . -viewer_binary_skip_info
326: Level: advanced
328: Notes: This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
329: you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
330: viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
332: The .info contains meta information about the data in the binary file, for example the block size if it was
333: set for a vector or matrix.
335: Concepts: PetscViewerBinary^accessing info file
337: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
338: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
339: @*/
340: PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
341: {
342: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
345: vbinary->skipinfo = PETSC_TRUE;
346: return(0);
347: }
349: static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
350: {
351: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
354: vbinary->skipinfo = skip;
355: return(0);
356: }
358: /*@
359: PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
361: Not Collective
363: Input Paramter:
364: . viewer - PetscViewer context, obtained from PetscViewerCreate()
366: Options Database Key:
367: . -viewer_binary_skip_info
369: Level: advanced
371: Concepts: PetscViewerBinary^accessing info file
373: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
374: PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
375: @*/
376: PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
377: {
381: PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));
382: return(0);
383: }
385: static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
386: {
387: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
390: *skip = vbinary->skipinfo;
391: return(0);
392: }
394: /*@
395: PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
397: Not Collective
399: Input Parameter:
400: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
402: Output Parameter:
403: . skip - PETSC_TRUE implies the .info file was not generated
405: Level: advanced
407: Notes: This must be called after PetscViewerSetType()
409: Concepts: PetscViewerBinary^accessing info file
411: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
412: PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
413: @*/
414: PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
415: {
419: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));
420: return(0);
421: }
423: static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
424: {
425: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
428: vbinary->skipoptions = skip;
429: return(0);
430: }
432: /*@
433: PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
435: Not Collective
437: Input Parameters:
438: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
439: - skip - PETSC_TRUE means do not use
441: Options Database Key:
442: . -viewer_binary_skip_options
444: Level: advanced
446: Notes: This must be called after PetscViewerSetType()
448: Concepts: PetscViewerBinary^accessing info file
450: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
451: PetscViewerBinaryGetSkipOptions()
452: @*/
453: PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
454: {
458: PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));
459: return(0);
460: }
462: static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
463: {
464: PetscViewer_Binary *vbinary;
468: vbinary = (PetscViewer_Binary*)viewer->data;
469: *skip = vbinary->skipoptions;
470: return(0);
471: }
473: /*@
474: PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
476: Not Collective
478: Input Parameter:
479: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
481: Output Parameter:
482: . skip - PETSC_TRUE means do not use
484: Level: advanced
486: Notes: This must be called after PetscViewerSetType()
488: Concepts: PetscViewerBinary^accessing info file
490: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
491: PetscViewerBinarySetSkipOptions()
492: @*/
493: PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
494: {
498: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));
499: return(0);
500: }
502: static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
503: {
504: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
507: vbinary->skipheader = skip;
508: return(0);
509: }
511: /*@
512: PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
514: Not Collective
516: Input Parameters:
517: + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
518: - skip - PETSC_TRUE means do not write header
520: Options Database Key:
521: . -viewer_binary_skip_header
523: Level: advanced
525: Notes: This must be called after PetscViewerSetType()
527: Can ONLY be called on a binary viewer
529: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
530: PetscViewerBinaryGetSkipHeader()
531: @*/
532: PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
533: {
537: PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));
538: return(0);
539: }
541: static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
542: {
543: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
546: *skip = vbinary->skipheader;
547: return(0);
548: }
550: /*@
551: PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
553: Not Collective
555: Input Parameter:
556: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
558: Output Parameter:
559: . skip - PETSC_TRUE means do not write header
561: Level: advanced
563: Notes: This must be called after PetscViewerSetType()
565: Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
567: .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
568: PetscViewerBinarySetSkipHeader()
569: @*/
570: PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
571: {
575: *skip = PETSC_FALSE;
576: PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));
577: return(0);
578: }
580: static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
581: {
582: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
583: PetscErrorCode ierr;
584: MPI_Comm comm;
587: PetscViewerSetUp(viewer);
588: *file = vbinary->fdes_info;
589: if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
590: vbinary->matlabheaderwritten = PETSC_TRUE;
591: PetscObjectGetComm((PetscObject)viewer,&comm);
592: PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
593: PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);
594: PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");
595: PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
596: }
597: return(0);
598: }
600: /*@C
601: PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
602: info file associated with a binary file.
604: Not Collective
606: Input Parameter:
607: . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
609: Output Parameter:
610: . file - file pointer Always returns NULL if not a binary viewer
612: Level: advanced
614: Notes:
615: For writable binary PetscViewers, the descriptor will only be valid for the
616: first processor in the communicator that shares the PetscViewer.
618: Fortran Note:
619: This routine is not supported in Fortran.
621: Concepts: PetscViewerBinary^accessing info file
623: .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
624: @*/
625: PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
626: {
630: *file = NULL;
631: PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));
632: return(0);
633: }
635: static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
636: {
637: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
638: PetscErrorCode ierr;
639: PetscMPIInt rank;
640: int err;
643: MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
644: if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) {
645: close(vbinary->fdes);
646: if (!rank && vbinary->storecompressed) {
647: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
648: FILE *fp;
649: /* compress the file */
650: PetscStrcpy(par,"gzip -f ");
651: PetscStrcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename);
652: PetscFree(vbinary->ogzfilename);
653: #if defined(PETSC_HAVE_POPEN)
654: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
655: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf);
656: PetscPClose(PETSC_COMM_SELF,fp,NULL);
657: #else
658: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
659: #endif
660: }
661: }
662: if (vbinary->fdes_info) {
663: err = fclose(vbinary->fdes_info);
664: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
665: }
666: return(0);
667: }
669: #if defined(PETSC_HAVE_MPIIO)
670: static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
671: {
672: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
673: int err;
674: PetscErrorCode ierr;
677: if (vbinary->mfdes) {
678: MPI_File_close(&vbinary->mfdes);
679: }
680: if (vbinary->fdes_info) {
681: err = fclose(vbinary->fdes_info);
682: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
683: }
684: return(0);
685: }
686: #endif
688: static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
689: {
690: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
691: PetscErrorCode ierr;
694: if (v->format == PETSC_VIEWER_BINARY_MATLAB) {
695: MPI_Comm comm;
696: FILE *info;
698: PetscObjectGetComm((PetscObject)v,&comm);
699: PetscViewerBinaryGetInfoPointer(v,&info);
700: PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
701: PetscFPrintf(comm,info,"#$$ close(fd);\n");
702: PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
703: }
704: #if defined(PETSC_HAVE_MPIIO)
705: if (vbinary->usempiio) {
706: PetscViewerFileClose_BinaryMPIIO(v);
707: } else {
708: #endif
709: PetscViewerFileClose_Binary(v);
710: #if defined(PETSC_HAVE_MPIIO)
711: }
712: #endif
713: PetscFree(vbinary->filename);
714: PetscFree(vbinary->ogzfilename);
715: PetscFree(vbinary);
716: return(0);
717: }
719: /*@C
720: PetscViewerBinaryOpen - Opens a file for binary input/output.
722: Collective on MPI_Comm
724: Input Parameters:
725: + comm - MPI communicator
726: . name - name of file
727: - type - type of file
728: $ FILE_MODE_WRITE - create new file for binary output
729: $ FILE_MODE_READ - open existing file for binary input
730: $ FILE_MODE_APPEND - open existing file for binary output
732: Output Parameter:
733: . binv - PetscViewer for binary input/output to use with the specified file
735: Options Database Keys:
736: + -viewer_binary_filename <name>
737: . -viewer_binary_skip_info
738: . -viewer_binary_skip_options
739: . -viewer_binary_skip_header
740: - -viewer_binary_mpiio
742: Level: beginner
744: Note:
745: This PetscViewer should be destroyed with PetscViewerDestroy().
747: For reading files, the filename may begin with ftp:// or http:// and/or
748: end with .gz; in this case file is brought over and uncompressed.
750: For creating files, if the file name ends with .gz it is automatically
751: compressed when closed.
753: For writing files it only opens the file on processor 0 in the communicator.
754: For readable files it opens the file on all nodes that have the file. If
755: node 0 does not have the file it generates an error even if other nodes
756: do have the file.
758: Concepts: binary files
759: Concepts: PetscViewerBinary^creating
760: Concepts: gzip
761: Concepts: accessing remote file
762: Concepts: remote file
764: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
765: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
766: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
767: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
768: @*/
769: PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv)
770: {
774: PetscViewerCreate(comm,binv);
775: PetscViewerSetType(*binv,PETSCVIEWERBINARY);
776: PetscViewerFileSetMode(*binv,type);
777: PetscViewerFileSetName(*binv,name);
778: PetscViewerSetFromOptions(*binv);
779: return(0);
780: }
782: #if defined(PETSC_HAVE_MPIIO)
783: static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
784: {
785: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
786: PetscErrorCode ierr;
787: MPI_Datatype mdtype;
788: PetscMPIInt cnt;
789: MPI_Status status;
790: MPI_Aint ul,dsize;
793: PetscMPIIntCast(num,&cnt);
794: PetscDataTypeToMPIDataType(dtype,&mdtype);
795: MPI_File_set_view(vbinary->mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);
796: if (write) {
797: MPIU_File_write_all(vbinary->mfdes,data,cnt,mdtype,&status);
798: } else {
799: MPIU_File_read_all(vbinary->mfdes,data,cnt,mdtype,&status);
800: }
801: MPI_Type_get_extent(mdtype,&ul,&dsize);
803: vbinary->moff += dsize*cnt;
804: if (count) *count = num;
805: return(0);
806: }
807: #endif
809: /*@C
810: PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
812: Collective on MPI_Comm
814: Input Parameters:
815: + viewer - the binary viewer
816: . data - location of the data to be written
817: . num - number of items of data to read
818: - dtype - type of data to read
820: Output Parameters:
821: . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num.
823: Level: beginner
825: Concepts: binary files
827: Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves.
829: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
830: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
831: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
832: @*/
833: PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
834: {
835: PetscErrorCode ierr;
836: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
838: PetscViewerSetUp(viewer);
839: #if defined(PETSC_HAVE_MPIIO)
840: if (vbinary->usempiio) {
841: PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);
842: } else {
843: #endif
844: PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,dtype);
845: if (count) *count = num;
846: #if defined(PETSC_HAVE_MPIIO)
847: }
848: #endif
849: return(0);
850: }
852: /*@C
853: PetscViewerBinaryWrite - writes to a binary file, only from the first process
855: Collective on MPI_Comm
857: Input Parameters:
858: + viewer - the binary viewer
859: . data - location of data
860: . count - number of items of data to write
861: . dtype - type of data to write
862: - istemp - data may be overwritten
864: Level: beginner
866: Notes: because byte-swapping may be done on the values in data it cannot be declared const
868: Concepts: binary files
870: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
871: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
872: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
873: @*/
874: PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp)
875: {
876: PetscErrorCode ierr;
877: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
880: PetscViewerSetUp(viewer);
881: #if defined(PETSC_HAVE_MPIIO)
882: if (vbinary->usempiio) {
883: PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);
884: } else {
885: #endif
886: PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);
887: #if defined(PETSC_HAVE_MPIIO)
888: }
889: #endif
890: return(0);
891: }
893: /*@C
894: PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
896: Collective on MPI_Comm
898: Input Parameters:
899: + viewer - the binary viewer
900: - data - location of the array of strings
903: Level: intermediate
905: Concepts: binary files
907: Notes: array of strings is null terminated
909: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
910: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
911: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
912: @*/
913: PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
914: {
916: PetscInt i,n = 0,*sizes;
918: PetscViewerSetUp(viewer);
919: /* count number of strings */
920: while (data[n++]) ;
921: n--;
922: PetscMalloc1(n+1,&sizes);
923: sizes[0] = n;
924: for (i=0; i<n; i++) {
925: size_t tmp;
926: PetscStrlen(data[i],&tmp);
927: sizes[i+1] = tmp + 1; /* size includes space for the null terminator */
928: }
929: PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);
930: for (i=0; i<n; i++) {
931: PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);
932: }
933: PetscFree(sizes);
934: return(0);
935: }
937: /*@C
938: PetscViewerBinaryReadStringArray - reads a binary file an array of strings
940: Collective on MPI_Comm
942: Input Parameter:
943: . viewer - the binary viewer
945: Output Parameter:
946: . data - location of the array of strings
948: Level: intermediate
950: Concepts: binary files
952: Notes: array of strings is null terminated
954: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
955: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
956: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
957: @*/
958: PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
959: {
961: PetscInt i,n,*sizes,N = 0;
963: PetscViewerSetUp(viewer);
964: /* count number of strings */
965: PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);
966: PetscMalloc1(n,&sizes);
967: PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);
968: for (i=0; i<n; i++) N += sizes[i];
969: PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);
970: (*data)[0] = (char*)((*data) + n + 1);
971: for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
972: PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);
974: (*data)[n] = 0;
976: PetscFree(sizes);
977: return(0);
978: }
980: static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
981: {
982: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
985: *name = vbinary->filename;
986: return(0);
987: }
989: /*@C
990: PetscViewerFileGetMode - Gets the type of file to be open
992: Not Collective
994: Input Parameter:
995: . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
997: Output Parameter:
998: . type - type of file
999: $ FILE_MODE_WRITE - create new file for binary output
1000: $ FILE_MODE_READ - open existing file for binary input
1001: $ FILE_MODE_APPEND - open existing file for binary output
1003: Level: advanced
1005: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1007: @*/
1008: PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type)
1009: {
1015: PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));
1016: return(0);
1017: }
1019: /*@
1020: PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
1021: before PetscViewerFileSetName()
1023: Logically Collective on PetscViewer
1025: Input Parameters:
1026: + viewer - the PetscViewer; must be a binary
1027: - flg - PETSC_TRUE means MPI-IO will be used
1029: Options Database:
1030: -viewer_binary_mpiio : Flag for using MPI-IO
1032: Level: advanced
1034: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
1035: PetscViewerBinaryGetUseMPIIO()
1037: @*/
1038: PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg)
1039: {
1044: PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));
1045: return(0);
1046: }
1048: /*@C
1049: PetscViewerFileSetMode - Sets the type of file to be open
1051: Logically Collective on PetscViewer
1053: Input Parameters:
1054: + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1055: - type - type of file
1056: $ FILE_MODE_WRITE - create new file for binary output
1057: $ FILE_MODE_READ - open existing file for binary input
1058: $ FILE_MODE_APPEND - open existing file for binary output
1060: Level: advanced
1062: .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1064: @*/
1065: PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type)
1066: {
1072: PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));
1073: return(0);
1074: }
1076: static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type)
1077: {
1078: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1081: *type = vbinary->btype;
1082: return(0);
1083: }
1085: static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type)
1086: {
1087: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1090: vbinary->btype = type;
1091: return(0);
1092: }
1094: static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1095: {
1096: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1097: PetscErrorCode ierr;
1100: if (vbinary->filename) {
1101: /* gzip can be run after the file with the previous filename has been closed */
1102: PetscFree(vbinary->ogzfilename);
1103: PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);
1104: PetscFree(vbinary->filename);
1105: viewer->setupcalled = PETSC_FALSE;
1106: }
1107: PetscStrallocpy(name,&vbinary->filename);
1108: return(0);
1109: }
1110: /*
1111: Actually opens the file
1112: */
1113: static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer)
1114: {
1115: PetscMPIInt rank;
1116: PetscErrorCode ierr;
1117: size_t len;
1118: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1119: const char *fname;
1120: char bname[PETSC_MAX_PATH_LEN],*gz;
1121: PetscBool found;
1122: PetscFileMode type = vbinary->btype;
1125: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1126: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1127: PetscViewerFileClose_Binary(viewer);
1129: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1131: /* if ends in .gz strip that off and note user wants file compressed */
1132: vbinary->storecompressed = PETSC_FALSE;
1133: if (!rank && type == FILE_MODE_WRITE) {
1134: /* remove .gz if it ends library name */
1135: PetscStrstr(vbinary->filename,".gz",&gz);
1136: if (gz) {
1137: PetscStrlen(gz,&len);
1138: if (len == 3) {
1139: *gz = 0;
1140: vbinary->storecompressed = PETSC_TRUE;
1141: }
1142: }
1143: }
1145: /* only first processor opens file if writeable */
1146: if (!rank || type == FILE_MODE_READ) {
1148: if (type == FILE_MODE_READ) {
1149: /* possibly get the file from remote site or compressed file */
1150: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);
1151: fname = bname;
1152: if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename);
1153: else if (!found) {
1154: PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");
1155: fname = 0;
1156: }
1157: } else fname = vbinary->filename;
1159: #if defined(PETSC_HAVE_O_BINARY)
1160: if (type == FILE_MODE_WRITE) {
1161: 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);
1162: } else if (type == FILE_MODE_READ && fname) {
1163: 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);
1164: } else if (type == FILE_MODE_APPEND) {
1165: 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);
1166: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1167: #else
1168: if (type == FILE_MODE_WRITE) {
1169: if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname);
1170: } else if (type == FILE_MODE_READ && fname) {
1171: if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname);
1172: } else if (type == FILE_MODE_APPEND) {
1173: 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);
1174: } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type");
1175: #endif
1176: } else vbinary->fdes = -1;
1178: /*
1179: try to open info file: all processors open this file if read only
1180: */
1181: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1182: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1184: PetscStrcpy(infoname,vbinary->filename);
1185: /* remove .gz if it ends library name */
1186: PetscStrstr(infoname,".gz",&gz);
1187: if (gz) {
1188: PetscStrlen(gz,&len);
1189: if (len == 3) *gz = 0;
1190: }
1192: PetscStrcat(infoname,".info");
1193: PetscFixFilename(infoname,iname);
1194: if (type == FILE_MODE_READ) {
1195: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1196: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1197: } else {
1198: vbinary->fdes_info = fopen(infoname,"w");
1199: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1200: }
1201: }
1202: #if defined(PETSC_USE_LOG)
1203: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1204: #endif
1205: return(0);
1206: }
1208: #if defined(PETSC_HAVE_MPIIO)
1209: static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1210: {
1211: PetscMPIInt rank;
1212: PetscErrorCode ierr;
1213: size_t len;
1214: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1215: char *gz;
1216: PetscBool found;
1217: PetscFileMode type = vbinary->btype;
1220: if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1221: if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1222: PetscViewerFileClose_BinaryMPIIO(viewer);
1224: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1226: vbinary->storecompressed = PETSC_FALSE;
1228: /* only first processor opens file if writeable */
1229: if (type == FILE_MODE_READ) {
1230: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);
1231: } else if (type == FILE_MODE_WRITE) {
1232: MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);
1233: }
1235: /*
1236: try to open info file: all processors open this file if read only
1238: Below is identical code to the code for Binary above, should be put in separate routine
1239: */
1240: if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) {
1241: char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN];
1243: PetscStrcpy(infoname,vbinary->filename);
1244: /* remove .gz if it ends library name */
1245: PetscStrstr(infoname,".gz",&gz);
1246: if (gz) {
1247: PetscStrlen(gz,&len);
1248: if (len == 3) *gz = 0;
1249: }
1251: PetscStrcat(infoname,".info");
1252: PetscFixFilename(infoname,iname);
1253: if (type == FILE_MODE_READ) {
1254: PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);
1255: PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);
1256: } else {
1257: vbinary->fdes_info = fopen(infoname,"w");
1258: if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1259: }
1260: }
1261: #if defined(PETSC_USE_LOG)
1262: PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);
1263: #endif
1264: return(0);
1265: }
1267: static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg)
1268: {
1269: PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1271: vbinary->usempiio = flg;
1272: return(0);
1273: }
1274: #endif
1276: static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1277: {
1278: PetscErrorCode ierr;
1279: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1282: if (binary->filename) {
1283: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);
1284: }
1285: return(0);
1286: }
1288: static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v)
1289: {
1290: PetscErrorCode ierr;
1291: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1294: if (!binary->setfromoptionscalled) { PetscViewerSetFromOptions(v); }
1295:
1296: #if defined(PETSC_HAVE_MPIIO)
1297: if (binary->usempiio) {
1298: PetscViewerFileSetUp_BinaryMPIIO(v);
1299: } else {
1300: #endif
1301: PetscViewerFileSetUp_Binary(v);
1302: #if defined(PETSC_HAVE_MPIIO)
1303: }
1304: #endif
1305: return(0);
1306: }
1308: static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v)
1309: {
1310: PetscErrorCode ierr;
1311: PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data;
1312: char defaultname[PETSC_MAX_PATH_LEN];
1313: PetscBool flg;
1316: PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");
1317: PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");
1318: PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);
1319: if (flg) { PetscViewerFileSetName_Binary(v,defaultname); }
1320: PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);
1321: PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);
1322: PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);
1323: #if defined(PETSC_HAVE_MPIIO)
1324: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);
1325: #elif defined(PETSC_HAVE_MPIUNI)
1326: PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);
1327: #endif
1328: PetscOptionsTail();
1329: binary->setfromoptionscalled = PETSC_TRUE;
1330: return(0);
1331: }
1333: /*MC
1334: PETSCVIEWERBINARY - A viewer that saves to binary files
1337: .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1338: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1339: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1340: PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1342: Level: beginner
1344: M*/
1346: PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1347: {
1348: PetscErrorCode ierr;
1349: PetscViewer_Binary *vbinary;
1352: PetscNewLog(v,&vbinary);
1353: v->data = (void*)vbinary;
1354: v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1355: v->ops->destroy = PetscViewerDestroy_Binary;
1356: v->ops->view = PetscViewerView_Binary;
1357: v->ops->setup = PetscViewerSetUp_Binary;
1358: v->ops->flush = NULL;
1359: vbinary->fdes_info = 0;
1360: vbinary->fdes = 0;
1361: vbinary->skipinfo = PETSC_FALSE;
1362: vbinary->skipoptions = PETSC_TRUE;
1363: vbinary->skipheader = PETSC_FALSE;
1364: vbinary->setfromoptionscalled = PETSC_FALSE;
1365: v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1366: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1367: v->ops->read = PetscViewerBinaryRead;
1368: vbinary->btype = (PetscFileMode) -1;
1369: vbinary->storecompressed = PETSC_FALSE;
1370: vbinary->filename = NULL;
1371: vbinary->ogzfilename = NULL;
1372: vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1374: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);
1375: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);
1376: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);
1377: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);
1378: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);
1379: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);
1380: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);
1381: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);
1382: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);
1383: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);
1384: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);
1385: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);
1386: PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);
1387: #if defined(PETSC_HAVE_MPIIO)
1388: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);
1389: PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);
1390: #endif
1391: return(0);
1392: }
1394: /* ---------------------------------------------------------------------*/
1395: /*
1396: The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1397: is attached to a communicator, in this case the attribute is a PetscViewer.
1398: */
1399: PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1401: /*@C
1402: PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1403: in a communicator.
1405: Collective on MPI_Comm
1407: Input Parameter:
1408: . comm - the MPI communicator to share the binary PetscViewer
1410: Level: intermediate
1412: Options Database Keys:
1413: + -viewer_binary_filename <name>
1414: . -viewer_binary_skip_info
1415: . -viewer_binary_skip_options
1416: . -viewer_binary_skip_header
1417: - -viewer_binary_mpiio
1419: Environmental variables:
1420: - PETSC_VIEWER_BINARY_FILENAME
1422: Notes:
1423: Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1424: an error code. The binary PetscViewer is usually used in the form
1425: $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1427: .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1428: PetscViewerDestroy()
1429: @*/
1430: PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1431: {
1433: PetscBool flg;
1434: PetscViewer viewer;
1435: char fname[PETSC_MAX_PATH_LEN];
1436: MPI_Comm ncomm;
1439: PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1440: if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1441: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0);
1442: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1443: }
1444: MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1445: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1446: if (!flg) { /* PetscViewer not yet created */
1447: PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1448: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1449: if (!flg) {
1450: PetscStrcpy(fname,"binaryoutput");
1451: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1452: }
1453: PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1454: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1455: PetscObjectRegisterDestroy((PetscObject)viewer);
1456: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1457: MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1458: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1459: }
1460: PetscCommDestroy(&ncomm);
1461: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
1462: PetscFunctionReturn(viewer);
1463: }